Skip to content

Commit

Permalink
Create Admin Table component (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
Prayag-Das authored Dec 14, 2024
1 parent ac14178 commit 20cc9f6
Show file tree
Hide file tree
Showing 29 changed files with 734 additions and 76 deletions.
2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@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
77 changes: 47 additions & 30 deletions ui/src/app/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,54 @@
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
//TODO: import { getAllGroupings, groupingAdmins } from '@/lib/fetchers';
import { groupingAdmins, ownerGroupings } from '@/lib/fetchers';
import GroupingsTable from '@/components/table/groupings-table/groupings-table';
import AdminTable from '@/components/table/admin-table/admin-table';

const Admin = async () => {
//TODO: const { groupingPaths } = await getAllGroupings();
const { groupingPaths } = await ownerGroupings();
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
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ const DescriptionForm = ({ groupDescription, groupPath }: { groupDescription: st
<div className="relative">
<form className="max-w-full flex rounded bg-white" onSubmit={handleSubmit(onSubmit)}>
<input
className="rounded-r-none float-left border-0 block w-full h-[calc(1.5em+0.75rem+2px)] p-[0.375rem_0.75rem] text-base font-normal leading-6 text-gray-700 bg-white border border-gray-300 rounded transition duration-150 ease-in-out focus:border-blue-500 focus:outline-none"
className="rounded-r-none float-left border-0 block w-full
h-[calc(1.5em+0.75rem+2px)] p-[0.375rem_0.75rem] text-base font-normal
leading-6 text-gray-700 bg-white border-gray-300 rounded transition duration-150
ease-in-out focus:border-blue-500 focus:outline-none"
{...register('description')}
placeholder="Brief description for this grouping..."
maxLength={98}
Expand All @@ -97,7 +100,8 @@ const DescriptionForm = ({ groupDescription, groupPath }: { groupDescription: st
<Tooltip>
<TooltipTrigger asChild>
<button
className="text-primary border-none bg-white text-text-color px-1 py-0.5 my-0 mx-0.5 h-9"
className="text-primary border-none bg-white
text-text-color px-1 py-0.5 my-0 mx-0.5 h-9"
disabled={isSubmitting}
type="submit"
aria-label="circle-check"
Expand All @@ -121,7 +125,8 @@ const DescriptionForm = ({ groupDescription, groupPath }: { groupDescription: st
<button
type="button"
onClick={closeForm}
className="text-primary border-none bg-white text-text-color px-1 py-0.5 my-0 mx-0.5 h-9"
className="text-primary border-none bg-white
text-text-color px-1 py-0.5 my-0 mx-0.5 h-9"
aria-label="times-circle"
>
<FontAwesomeIcon
Expand All @@ -141,7 +146,8 @@ const DescriptionForm = ({ groupDescription, groupPath }: { groupDescription: st
{currentDescription.length >= 98 && (
<Alert
data-testid="description-alert"
className="bg-rose-100 text-rose-900 lg:w-max lg:h-[50px] md:w-max md:h-[50px] sm:h-1/2 pt-2.5 pl-2 pr-2 mb-1 mt-1 border"
className="bg-rose-100 text-rose-900 lg:w-max lg:h-[50px]
md:w-max md:h-[50px] sm:h-1/2 pt-2.5 pl-2 pr-2 mb-1 mt-1 border"
>
<strong>Maximum length reached. </strong>A grouping&apos;s description cannot exceed 98
characters.
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/groupings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ownerGroupings } from '@/lib/fetchers';
import GroupingsTable from '@/components/table/groupings-table';
import GroupingsTable from '@/components/table/groupings-table/groupings-table';

const Groupings = async () => {
const { groupingPaths } = await ownerGroupings();
Expand Down
109 changes: 109 additions & 0 deletions ui/src/components/modal/remove-member-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Label } from '@/components/ui/label';
import { Trash2Icon } from 'lucide-react';
import { MemberResult } from '@/lib/types';

const RemoveMemberModal = ({
uid,
name,
uhUuid,
list,
action
}: {
uid;
name;
uhUuid: MemberResult;
list: string;
action: () => void;
}) => {
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Trash2Icon className="h-4 w-4 text-red-600" />
</AlertDialogTrigger>
<AlertDialogContent className="sm:max-w-[500px]">
<AlertDialogHeader>
<AlertDialogTitle className="text-[1.4rem] text-text-color">Remove Member</AlertDialogTitle>
<AlertDialogDescription>
You are about to remove the following member from the <span>{list}</span> list.
</AlertDialogDescription>
</AlertDialogHeader>
<div className="grid grid-cols-2">
<div className="grid">
<div className="grid grid-cols-3 items-center py-1 px-4">
<Label htmlFor="name" className="font-bold text-s text-left whitespace-nowrap">
NAME:
</Label>
</div>
<div className="grid grid-cols-3 items-center py-1 px-4">
<Label htmlFor="name" className="font-bold text-s text-left whitespace-nowrap">
UH USERNAME:
</Label>
</div>
<div className="grid grid-cols-3 items-center py-1 px-4">
<Label htmlFor="name" className="font-bold text-s text-left whitespace-nowrap">
UH USER ID:
</Label>
</div>
</div>

{/*second column*/}

<div className="grid">
<div className="grid grid-cols-3 items-center">
<Label htmlFor="name" className="text-s text-left whitespace-nowrap">
{name}
</Label>
</div>
<div className="grid grid-cols-4 items-center">
<Label htmlFor="name" className="text-s text-left whitespace-nowrap">
{uid}
</Label>
</div>
<div className="grid grid-cols-4 items-center">
<Label htmlFor="name" className="text-s text-left whitespace-nowrap">
{uhUuid}
</Label>
</div>
</div>
</div>
<AlertDialogDescription>
Are you sure you want to remove{' '}
<span
className="font-bold
text-text-color"
>
{name}
</span>{' '}
from the <span>{list}</span> list?
</AlertDialogDescription>
<div className="px-3">
<Alert className="bg-yellow-100 border border-yellow-200 mb-2">
<AlertDescription>
Membership changes made may not take effect immediately. Usually, 3-5 minutes should be
anticipated. In extreme cases changes may take several hours to be fully processed,
depending on the number of members and the synchronization destination.
</AlertDescription>
</Alert>
</div>
<AlertDialogFooter>
<Button onClick={() => action(uid)}>Yes</Button>
<AlertDialogCancel onClick={() => close()}>Cancel</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};

export default RemoveMemberModal;
48 changes: 48 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,48 @@
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={`header-${column}`} 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={`header-${column}`} className={`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;
Loading

0 comments on commit 20cc9f6

Please sign in to comment.