Skip to content

Commit

Permalink
Added Jordan's requested changes to AdminTable branch.
Browse files Browse the repository at this point in the history
  • Loading branch information
FeimeiChen authored and Prayag-Das committed Nov 9, 2024
1 parent 0dde260 commit 5022f13
Show file tree
Hide file tree
Showing 28 changed files with 683 additions and 54 deletions.
3 changes: 1 addition & 2 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@fortawesome/free-regular-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"@hookform/resolvers": "^3.3.4",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
Expand Down
94 changes: 64 additions & 30 deletions ui/src/app/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,71 @@
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { getAllGroupings } from '@/lib/fetchers';
import { groupingAdmins } from '@/lib/fetchers';
import GroupingsTableSkeleton from '@/components/table/groupings-table/groupings-table-skeleton';
import AdminTableSkeleton from '@/components/table/admin-table/admin-table-skeleton';
import dynamic from 'next/dynamic';

// Require dynamic import for localStorage
const GroupingsTable = dynamic(() => import('@/components/table/groupings-table/groupings-table'), {
ssr: false,
loading: () => <GroupingsTableSkeleton />
});

const AdminTable = dynamic(() => import('@/components/table/admin-table/admin-table'), {
ssr: true,
loading: () => <AdminTableSkeleton />
});

const Admin = async () => {

const { groupingPaths } = await getAllGroupings();
const { members } = await groupingAdmins();

const Admin = () => {
return (
<Tabs className="bg-seafoam" defaultValue="manage-groupings">
<div className="container">
<TabsList variant="outline">
<TabsTrigger value="manage-groupings" variant="outline">
Manage Groupings
</TabsTrigger>
<TabsTrigger value="manage-admins" variant="outline">
Manage Admins
</TabsTrigger>
<TabsTrigger value="manage-person" variant="outline">
Manage Person
</TabsTrigger>
</TabsList>
<main>
<div className="bg-seafoam pt-3">
<Tabs defaultValue="manage-groupings">
<div className="container">
<TabsList variant="outline">
<TabsTrigger
value="manage-groupings" variant="outline" >
Manage Groupings
</TabsTrigger>
<TabsTrigger
value="manage-admins" variant="outline" >
Manage Admins
</TabsTrigger>
<TabsTrigger
value="manage-person" variant="outline" >
Manage Person
</TabsTrigger>
</TabsList>
</div>
<TabsContent value="manage-groupings">
<div className="bg-white">
<div className="container">
<GroupingsTable groupingPaths = {groupingPaths}/>
</div>
</div>
</TabsContent>
<TabsContent value="manage-admins">
<div className="bg-white">
<div className="container">
<AdminTable members ={members}/>
{/*<AddAdmin/>*/}
</div>
</div>
</TabsContent>
<TabsContent value="manage-person">
<div className="bg-white">
<div className="container">
{/* PersonTable goes here */}
</div>
</div>
</TabsContent>
</Tabs>
</div>
<TabsContent value="manage-groupings">
<div className="bg-white">
<div className="container">{/* GroupingsTable goes here */}</div>
</div>
</TabsContent>
<TabsContent value="manage-admins">
<div className="bg-white">
<div className="container">{/* AdminTable goes here */}</div>
</div>
</TabsContent>
<TabsContent value="manage-person">
<div className="bg-white">
<div className="container">{/* PersonTable goes here */}</div>
</div>
</TabsContent>
</Tabs>
</main>
);
};

Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/groupings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ownerGroupings } from '@/lib/fetchers';
import dynamic from 'next/dynamic';
import GroupingsTableSkeleton from '@/components/table/groupings-table-skeleton';
import GroupingsTableSkeleton from '@/components/table/groupings-table/groupings-table-skeleton';

// Require dynamic import for localStorage
const GroupingsTable = dynamic(() => import('@/components/table/groupings-table'), {
const GroupingsTable = dynamic(() => import('@/components/table/groupings-table/groupings-table'), {
ssr: false,
loading: () => <GroupingsTableSkeleton />
});
Expand Down
55 changes: 55 additions & 0 deletions ui/src/components/table/admin-table/admin-table-skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Skeleton } from '@/components/ui/skeleton';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import AdminTableColumns from '@/components/table/admin-table/table-element/admin-table-columns';

const AdminTableSkeleton = () => {
const pageSize = 7; // Average number of rows

return (
<div className="mb-12">
<div className="h-full flex flex-col md:flex-row md:justify-between pt-5 mb-4">
<h1 className="text-[2rem] font-medium text-text-color text-center pt-3">Manage Admins</h1>
<div className="flex items-center space-x-2 md:w-60 lg:w-72">
<Skeleton className="h-10 w-96 rounded-[0.25rem]" />
<div className="hidden sm:block">
<Skeleton className="h-10 w-10 rounded-[0.25rem]" />
</div>
</div>
</div>
<Table className="mb-4">
<TableHeader>
<TableRow>
{AdminTableColumns.map((column) => (
<TableHead
key={column.accessorKey}
className={`pl-[0.5rem]`}
>
<Skeleton className="h-5 w-36 rounded-[0.25rem]" />
</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{Array.from(Array(pageSize), (_, index) => (
<TableRow key={index}>
{AdminTableColumns.map((column) => (
<TableCell
key={column.accessorKey}
className={/*`p-[0.5rem]
${column.accessorKey !== 'name' ? 'hidden sm:table-cell' : ''}`*/ `p-[0.5rem]`}
>
<Skeleton className="h-5 w-72 rounded-[0.25rem]" />
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
<div className="float-end">
<Skeleton className="h-10 w-80 rounded-[0.25rem]" />
</div>
</div>
);
};

export default AdminTableSkeleton;
107 changes: 107 additions & 0 deletions ui/src/components/table/admin-table/admin-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
'use client';

import {
useReactTable,
flexRender,
getCoreRowModel,
getPaginationRowModel,
getFilteredRowModel,
getSortedRowModel
} from '@tanstack/react-table';
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from '@/components/ui/table';
import AdminTableColumns from '@/components/table/admin-table/table-element/admin-table-columns';
import PaginationBar from '@/components/table/table-element/pagination-bar';
import GlobalFilter from '@/components/table/table-element/global-filter';
import SortArrow from '@/components/table/table-element/sort-arrow';
import RemoveAdminsDialog from '@/components/table/admin-table/table-element/remove-admins-dialog';
import {useState} from 'react';
//import AddAdminsDialog from '@/components/table/adminTable/table-element/add-admins-dialog';
import {MemberResult} from '@/lib/types';
const pageSize = parseInt(process.env.NEXT_PUBLIC_PAGE_SIZE as string);

const AdminTable = ({ members } : { members: MemberResult[] }) => {
const [globalFilter, setGlobalFilter] = useState('');
//const [adminInput, setAdminInput] = useState('');
const [sorting, setSorting] = useState([]);

const table = useReactTable({
columns: AdminTableColumns,
data: members,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
state: { globalFilter, sorting },
initialState: { pagination: { pageSize } },
onGlobalFilterChange: setGlobalFilter,
onSortingChange: setSorting,
enableMultiSort: true
});

return (
<>
<div className="flex flex-col md:flex-row md:justify-between pt-5 mb-4">
<h1 className="text-[2rem] font-medium text-text-color pt-3">Manage Admins</h1>
<div className="flex items-center space-x-2 md:w-60 lg:w-72">
<GlobalFilter placeholder={'Filter Admins...'} filter={globalFilter} setFilter={setGlobalFilter}/>
</div>
</div>
<Table className = "relative overflow-x-auto">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead
key={header.id}
onClick={header.column.getToggleSortingHandler()}
className={`w-1/3`}
>
<div className="flex items-center">
{flexRender(header.column.columnDef.header, header.getContext())}
<SortArrow direction={header.column.getIsSorted()} />
</div>
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows.map((row) => (
<TableRow key={row.id}>
{row.getVisibleCells().map(cell => (
<TableCell
key={cell.id}
width={cell.column.columnDef.size}
>
<div className="flex items-center px-2 overflow-hidden whitespace-nowrap">
<div className="m-2">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</div>
{cell.column.id === 'REMOVE' && (
<RemoveAdminsDialog
uid={row.getValue('uid')}
name={row.getValue('name')}
uhUuid={row.getValue('uhUuid')}
/>
)}
</div>
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
<div className="grid grid-cols-2 items-center">
<div>
{/*TODO: <AddAdmin input={adminInput} setInput={setAdminInput}/>
TODO: <AddAdminsDialog input={adminInput} setInput={setAdminInput}/>*/}
</div>
<div className="flex justify-end">
<PaginationBar table={table}/>
</div>
</div>
</>
);
};

export default AdminTable;
50 changes: 50 additions & 0 deletions ui/src/components/table/admin-table/table-element/add-admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {Input} from '@/components/ui/input'
import {Dispatch, SetStateAction} from 'react';
import {Button} from '@/components/ui/button';
import {addAdmin} from '@/actions/groupings-api';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '@/components/ui/tooltip';

interface InputProps {
input: string;
setInput: Dispatch<SetStateAction<string>>;
}

const handleClick = (input: string) => {
//TODO: create a condition where the admin list is checked for the uhid/uhUuid the user entered in.
//TODO: if it does not exist in the admin list, add the new admin to the UH Groupings admin list.
addAdmin(input);
};
const AddAdmin = ({input, setInput}: InputProps) => (
//Add tooltip
<div className="inline-flex" role="group">
<Input
className="rounded-r-none"
placeholder={'UH Username or UH #'}
value={input || ''}

onChange={e => setInput(e.target.value)}
/>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
className="rounded-l-none"
onClick={() => handleClick(input)}
>
Add
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Add to admins</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
);

export default AddAdmin;
Loading

0 comments on commit 5022f13

Please sign in to comment.