Skip to content

Commit

Permalink
Merge pull request #21 from UofA-Blueprint/ASC-84
Browse files Browse the repository at this point in the history
ASC-84: Member Table
  • Loading branch information
PaulHo0501 authored May 21, 2024
2 parents e7d4641 + 89e768e commit 5d06fe0
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 159 deletions.
190 changes: 98 additions & 92 deletions src/App.tsx
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;
133 changes: 133 additions & 0 deletions src/components/MemberTable.tsx
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>
);
}
Loading

0 comments on commit 5d06fe0

Please sign in to comment.