generated from UofA-Blueprint/ScaffoldTool
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from UofA-Blueprint/ASC-84
ASC-84: Member Table
- Loading branch information
Showing
5 changed files
with
321 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,120 +1,126 @@ | ||
import { createBrowserRouter, RouterProvider } from "react-router-dom"; | ||
|
||
//#region imports | ||
// routes | ||
|
||
import ModalTestRoute from "@/routes/ModalTestRoute"; | ||
import ButtonTestRoute from "@/routes/ButtonTestRoute"; | ||
import ProfilePictureTest from "./routes/ProfilePictureTestRoute"; | ||
import Test from "./routes/Test"; | ||
import SearchBarTest from "./routes/SearchBarTestRoute"; | ||
import DropdownItem from "@/components/DropdownItem"; | ||
import SortDropdownListTestRoute from "@/routes/SortDropdownListTestRoute"; | ||
import NavigationTest from "@/routes/NavigationTest"; | ||
import TooltipTestRoute from "./routes/TooltipTestRoute"; | ||
import InputCodeTest from "@/routes/InputCodeTest"; | ||
import ToastTestRoute from "@/routes/ToastTestRoute"; | ||
import MediaUploadZoneTestRoute from "@/routes/MediaUploadZoneTestRoute"; | ||
|
||
import IconOptionTest from "./routes/IconOptionTest"; | ||
import { MemberTableTestRoute } from "./routes/MemberTableTestRoute"; | ||
|
||
// components | ||
import ColorPickerTestRoute from "@/routes/ColorPickerTestRoute"; | ||
import InputFieldTestRoute from "./routes/InputFieldTestRoute"; | ||
import MemberHeaderTestRoute from "@/routes/MemberHeaderTestRoute"; | ||
import { MemberInformation } from "./components/MemberInformation"; | ||
import ModalTestRoute from "@/routes/ModalTestRoute"; | ||
import { LoginModal } from "./components/LoginModal"; | ||
import { MemberTable } from "./components/MemberTable"; | ||
//#endregion | ||
|
||
const router = createBrowserRouter([ | ||
{ | ||
path: "/test", | ||
element: <Test />, | ||
}, | ||
{ | ||
path: "/SearchBarTestRoute", | ||
element: <SearchBarTest />, | ||
}, | ||
{ | ||
path: "/testButton", | ||
element: <ButtonTestRoute />, | ||
}, | ||
{ | ||
path: "/SortDropdownListTestRoute", | ||
element: <SortDropdownListTestRoute />, | ||
}, | ||
{ | ||
path: "/nav-test", | ||
element: <NavigationTest />, | ||
}, | ||
{ | ||
path: "/tooltip", | ||
element: <TooltipTestRoute />, | ||
}, | ||
{ | ||
path: "/input-code-test", | ||
element: <InputCodeTest />, | ||
}, | ||
{ | ||
path: "/upload-file-test", | ||
element: <MediaUploadZoneTestRoute />, | ||
}, | ||
{ | ||
path: "/toast-test", | ||
element: <ToastTestRoute />, | ||
}, | ||
{ | ||
path: "/icon-select", | ||
element: <IconOptionTest />, | ||
}, | ||
{ | ||
path: "/ProfilePic", | ||
element: <ProfilePictureTest />, | ||
}, | ||
{ | ||
path: "/color-picker-test", | ||
element: <ColorPickerTestRoute />, | ||
}, | ||
{ | ||
path: "/member-header-test", | ||
element: <MemberHeaderTestRoute />, | ||
}, | ||
{ | ||
path: "/profile-test", | ||
element: <ProfilePictureTest />, | ||
}, | ||
{ | ||
path: "/member-information-test", | ||
element: ( | ||
<div className="flex flex-col gap-y-20 items-center justify-center w-full h-[100vh] bg-slate-400"> | ||
<MemberInformation /> | ||
</div> | ||
), | ||
}, | ||
{ | ||
path: "/input-field-test", | ||
element: <InputFieldTestRoute />, | ||
}, | ||
{ | ||
path: "/modal-test", | ||
element: <ModalTestRoute />, | ||
}, | ||
{ | ||
path: "/login-modal-test", | ||
element: ( | ||
<div className="flex flex-col gap-y-8 justify-center items-center py-20 bg-slate-100"> | ||
<LoginModal | ||
title="Admin Panel" | ||
type="admin" | ||
/> | ||
<LoginModal | ||
title="Caregiver Panel" | ||
type="member" | ||
/> | ||
</div> | ||
), | ||
}, | ||
{ | ||
path: "/test", | ||
element: <Test />, | ||
}, | ||
{ | ||
path: "/SearchBarTestRoute", | ||
element: <SearchBarTest />, | ||
}, | ||
{ | ||
path: "/testButton", | ||
element: <ButtonTestRoute />, | ||
}, | ||
{ | ||
path: "/SortDropdownListTestRoute", | ||
element: <SortDropdownListTestRoute />, | ||
}, | ||
{ | ||
path: "/nav-test", | ||
element: <NavigationTest />, | ||
}, | ||
{ | ||
path: "/tooltip", | ||
element: <TooltipTestRoute />, | ||
}, | ||
{ | ||
path: "/input-code-test", | ||
element: <InputCodeTest />, | ||
}, | ||
{ | ||
path: "/upload-file-test", | ||
element: <MediaUploadZoneTestRoute />, | ||
}, | ||
{ | ||
path: "/toast-test", | ||
element: <ToastTestRoute />, | ||
}, | ||
{ | ||
path: "/icon-select", | ||
element: <IconOptionTest />, | ||
}, | ||
{ | ||
path: "/ProfilePic", | ||
element: <ProfilePictureTest />, | ||
}, | ||
{ | ||
path: "/color-picker-test", | ||
element: <ColorPickerTestRoute />, | ||
}, | ||
{ | ||
path: "/member-header-test", | ||
element: <MemberHeaderTestRoute />, | ||
}, | ||
{ | ||
path: "/profile-test", | ||
element: <ProfilePictureTest />, | ||
}, | ||
{ | ||
path: "/member-information-test", | ||
element: ( | ||
<div className="flex flex-col gap-y-20 items-center justify-center w-full h-[100vh] bg-slate-400"> | ||
<MemberInformation /> | ||
</div> | ||
), | ||
}, | ||
{ | ||
path: "/input-field-test", | ||
element: <InputFieldTestRoute />, | ||
}, | ||
{ | ||
path: "/modal-test", | ||
element: <ModalTestRoute />, | ||
}, | ||
{ | ||
path: "/login-modal-test", | ||
element: ( | ||
<div className="flex flex-col gap-y-8 justify-center items-center py-20 bg-slate-100"> | ||
<LoginModal | ||
title="Admin Panel" | ||
type="admin" | ||
/> | ||
<LoginModal | ||
title="Caregiver Panel" | ||
type="member" | ||
/> | ||
</div> | ||
), | ||
}, | ||
{ | ||
path: "/member-table", | ||
element: <MemberTableTestRoute />, | ||
}, | ||
]); | ||
|
||
function App() { | ||
return <RouterProvider router={router}></RouterProvider>; | ||
return <RouterProvider router={router}></RouterProvider>; | ||
} | ||
|
||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
//#region imports | ||
import { UserCircle, Folder, ArrowsClockwise } from "@phosphor-icons/react"; | ||
import ProfilePictures from "./ProfilePictures"; | ||
import * as Icon from "@phosphor-icons/react"; | ||
//#endregion | ||
|
||
//#region interfaces | ||
interface MemberTableProps { | ||
data: { | ||
profilePicture: { | ||
type: "img" | "icon" | string; | ||
src: string; | ||
backgroundColor?: string; | ||
}; | ||
name: string; | ||
storageUsed: string; | ||
lastUpdated: string; | ||
}[]; | ||
} | ||
//#endregion | ||
|
||
//#region helpers | ||
function selectIcon(type: string) { | ||
const iconStyling = | ||
"w-full h-full rounded-full p-2 object-cover text-white"; | ||
switch (type) { | ||
case "PawPrint": | ||
return <Icon.PawPrint className={iconStyling} />; | ||
case "Tree": | ||
return <Icon.Tree className={iconStyling} />; | ||
case "Pizza": | ||
return <Icon.Pizza className={iconStyling} />; | ||
case "Camera": | ||
return <Icon.Camera className={iconStyling} />; | ||
case "Atom": | ||
return <Icon.Atom className={iconStyling} />; | ||
case "Binoculars": | ||
return <Icon.Binoculars className={iconStyling} />; | ||
case "SoccerBall": | ||
return <Icon.SoccerBall className={iconStyling} />; | ||
case "Coffee": | ||
return <Icon.Coffee className={iconStyling} />; | ||
} | ||
} | ||
//#endregion | ||
|
||
/** | ||
* Represents a table component that displays member data. | ||
* @param data - An array of objects representing each member's data. | ||
*/ | ||
export function MemberTable({ data }: MemberTableProps) { | ||
const headers = [ | ||
{ icon: <UserCircle />, label: "Name" }, | ||
{ icon: <Folder />, label: "Storage Used" }, | ||
{ icon: <ArrowsClockwise />, label: "Last Updated" }, | ||
]; | ||
|
||
function handleClick(row: any) { | ||
alert(`Clicked ${row.name}`); | ||
} | ||
|
||
return ( | ||
<div className="rounded-lg w-full overflow-hidden"> | ||
<table className="w-full"> | ||
{/* Headers */} | ||
<thead className="bg-primary-light text-white"> | ||
<tr> | ||
{headers.map((header, index) => ( | ||
<th | ||
scope="col" | ||
key={index} | ||
className="px-4 py-4 md:py-7" | ||
> | ||
<div className="flex items-center font-normal gap-x-2"> | ||
<span className=" text-xl"> | ||
{header.icon} | ||
</span> | ||
<span className="font-display text-sm md:text-base"> | ||
{header.label} | ||
</span> | ||
</div> | ||
</th> | ||
))} | ||
</tr> | ||
</thead> | ||
|
||
{/* Data */} | ||
<tbody> | ||
{data.map((row, index) => ( | ||
<tr | ||
key={index} | ||
className="cursor-pointer hover:bg-status-blue-light" | ||
onClick={() => handleClick(row)} | ||
> | ||
<td className="px-4 py-6"> | ||
<div className="flex items-center gap-x-6"> | ||
<ProfilePictures | ||
className="w-12 md:w-16 aspect-square" | ||
backgroundColor={ | ||
row.profilePicture.backgroundColor | ||
} | ||
> | ||
{row.profilePicture.type === "img" ? ( | ||
<img | ||
src={row.profilePicture.src} | ||
alt="profile" | ||
className="w-full h-full rounded-full object-cover" | ||
/> | ||
) : ( | ||
selectIcon( | ||
row.profilePicture | ||
.src as string, | ||
) | ||
)} | ||
</ProfilePictures> | ||
<span className="font-display text-sm md:text-base"> | ||
{row.name} | ||
</span> | ||
</div> | ||
</td> | ||
<td className="px-4 py-6 font-display text-sm md:text-base"> | ||
{row.storageUsed} | ||
</td> | ||
<td className="px-4 py-6 font-display text-sm md:text-base"> | ||
{row.lastUpdated} | ||
</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.