Added drawer

This commit is contained in:
Meliora Ho 2024-03-27 15:47:44 +00:00
parent 80760c1f14
commit 6f18419a74
10 changed files with 172 additions and 192 deletions

View File

@ -0,0 +1,37 @@
"use client"
import Sidebar from '@/components/resource/Sidebar';
import React, { useState } from 'react';
import { ChevronDoubleRightIcon } from '@heroicons/react/24/outline';
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
return (
<div className="flex-row">
{/* button to open sidebar */}
<button
onClick={() => setIsSidebarOpen(!isSidebarOpen)}
className={`fixed z-20 p-2 text-gray-500 hover:text-gray-800 left-0`}
aria-label={'Open sidebar'}
>
{!isSidebarOpen &&
<ChevronDoubleRightIcon className="h-5 w-5" /> // Icon for closing the sidebar
}
</button>
{/* sidebar */}
<div className={`absolute inset-y-0 left-0 transform ${isSidebarOpen ? 'translate-x-0' : '-translate-x-full'} w-64 transition duration-300 ease-in-out`}>
<Sidebar setIsSidebarOpen={setIsSidebarOpen} />
</div>
{/* page ui */}
<div className={`flex-1 transition duration-300 ease-in-out ${isSidebarOpen ? 'ml-64' : 'ml-0'}`}>
{children}
</div>
</div>
)
}

View File

@ -1,90 +1,21 @@
"use client";
// import Table from "@/components/Table";
import {
ColumnDef,
createColumnHelper,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import { useState } from "react";
import usersImport from "./users.json";
const usersExample = usersImport as unknown as User[];
type User = {
id: number;
created_at: any;
username: string;
role: "ADMIN" | "EMPLOYEE" | "VOLUNTEER";
email: string;
program: "DOMESTIC" | "ECONOMIC" | "COMMUNITY";
experience: number;
group?: string;
};
import { PageLayout } from "@/components/admin/PageLayout";
import { Table } from "@/components/admin/Table/Index";
import { UsersIcon } from "@heroicons/react/24/solid";
import { BookmarkIcon } from "@heroicons/react/24/solid";
export default function Page() {
const columnHelper = createColumnHelper<User>();
const columns = [
columnHelper.accessor("username", {
cell: (info) => info.getValue(),
}),
columnHelper.accessor("role", {
cell: (info) => info.renderValue(),
}),
columnHelper.accessor("email", {
cell: (info) => info.renderValue(),
}),
columnHelper.accessor("program", {
cell: (info) => info.renderValue(),
}),
];
const [data, setData] = useState<User[]>([...usersExample]);
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
});
return (
<div className="min-h-screen flex flex-col">
{/* icon + title */}
<PageLayout title="Resources" icon={<BookmarkIcon />}>
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
<PageLayout title="Users" icon={<UsersIcon />}>
<Table />
</PageLayout>
</div>
);

View File

@ -1,86 +0,0 @@
// pages/index.tsx
"use client";
import Button from '@/components/Button';
import Input from '@/components/Input'
import InlineLink from '@/components/InlineLink';
import Paper from '@/components/auth/Paper';
// import { Metadata } from 'next'
import Image from 'next/image';
import {ChangeEvent, useState} from "react";
// export const metadata: Metadata = {
// title: 'Login',
// }
export default function Page() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setEmail(event.currentTarget.value);
console.log("email " + email);
}
const handlePasswordChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(event.currentTarget.value);
console.log("password " + password)
}
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
// Priority: Incorrect combo > Missing email > Missing password
if (password.trim().length === 0) {
setError("Please enter your password.")
}
// This shouldn't happen, <input type="email"> already provides validation, but just in case.
if (email.trim().length === 0) {
setError("Please enter your email.")
}
// Placeholder for incorrect email + password combo.
if (email === "incorrect@gmail.com" && password) {
setError("Incorrect password.")
}
}
return (
<>
<Paper>
<form className="mb-0 m-auto mt-6 space-y-4 rounded-lg p-4 shadow-lg sm:p-6 lg:p-8 bg-white max-w-xl">
<Image
src="/logo.png"
alt='Compass Center logo.'
width={100}
height={91}
/>
<h1 className='font-bold text-xl text-purple-800'>Login</h1>
<div className="mb-4">
<Input type='email' title="Email" placeholder="janedoe@gmail.com" onChange={handleEmailChange} />
</div>
<div className="mb-6">
<Input type='password' title="Password" onChange={handlePasswordChange} />
</div>
<div className="flex flex-col items-left space-y-4">
<InlineLink href="/forgot_password">
Forgot password?
</InlineLink>
<Button onClick={handleClick}>
Login
</Button>
<div className="text-center text-red-600" hidden={!error}>
<p>{error}</p>
</div>
</div>
</form>
<p className="text-center mt-6 text-gray-500 text-xs">
&copy; 2024 Compass Center
</p>
</Paper>
</>
);
};

View File

@ -1,26 +0,0 @@
// pages/index.tsx
"use client";
import Drawer from '@/components/page/Drawer';
// import { Metadata } from 'next'
import {ChangeEvent, useState} from "react";
// export const metadata: Metadata = {
// title: 'Login',
// }
export default function Page() {
const [pageContent, setPageContent] = useState("")
const handleDrawerContentChange = (newContent) => {
setPageContent(newContent);
};
return (
<>
<h1 className="text-2xl font-bold text-gray-700 sm:text-3xl">Resources</h1>
<Drawer title="My Drawer Title" editableContent={pageContent} onSave={handleDrawerContentChange}>{pageContent}</Drawer>
</>
);
};

View File

@ -15,7 +15,7 @@ export const PageLayout: React.FC<PageLayoutProps> = ({ icon, title, children })
</div>
</div>
{/* data */}
<div>
<div className="px-8 py-8">
{children}
</div>
</div>

View File

@ -0,0 +1,91 @@
// for showcasing to compass
import usersImport from "./users.json";
import {
ColumnDef,
createColumnHelper,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import { useState } from "react";
import { RowAction } from "./RowAction";
import { TableAction } from "./TableAction";
const usersExample = usersImport as unknown as User[];
type User = {
id: number;
created_at: any;
username: string;
role: "ADMIN" | "EMPLOYEE" | "VOLUNTEER";
email: string;
program: "DOMESTIC" | "ECONOMIC" | "COMMUNITY";
experience: number;
group?: string;
};
export const Table = () => {
const columnHelper = createColumnHelper<User>();
const columns = [
columnHelper.accessor("username", {
cell: (info) => <RowAction title={info.getValue()} />,
}),
columnHelper.accessor("role", {
cell: (info) => info.renderValue(),
}),
columnHelper.accessor("email", {
cell: (info) => info.renderValue(),
}),
columnHelper.accessor("program", {
cell: (info) => info.renderValue(),
}),
];
const [data, setData] = useState<User[]>([...usersExample]);
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
});
return(
<div className="flex flex-col">
<div className="flex flex-row justify-end">
<TableAction />
</div>
<table className="w-full text-xs text-left rtl:text-right">
<thead className="text-xs text-gray-500 capitalize">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th scope="col" className="p-3 border-gray-200 border-y font-medium" key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody className="">
{table.getRowModel().rows.map((row) => (
<tr className="text-gray-800 border-y lowercase hover:bg-gray-50" key={row.id}>
{row.getVisibleCells().map((cell) => (
<td className="py-2 px-2" key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}

View File

@ -0,0 +1,21 @@
import Drawer from "@/components/page/Drawer";
import {ChangeEvent, useState} from "react";
export const RowAction = ({ title }) => {
const [pageContent, setPageContent] = useState("")
const handleDrawerContentChange = (newContent) => {
setPageContent(newContent);
};
return (
<div className="font-semibold group flex flex-row items-center justify-between pr-2">
{title}
<span >
<Drawer title="My Drawer Title" editableContent={pageContent} onSave={handleDrawerContentChange}>{pageContent}</Drawer>
</span>
</div>
);
};

View File

@ -0,0 +1,12 @@
import { MagnifyingGlassIcon } from "@heroicons/react/24/solid";
export const TableAction = () => {
return (
<div className="w-40 flex flex-row items-center justify-between text-xs font-medium text-gray-500 p-2">
<span>Filter</span>
<span>Sort</span>
<span className="w-4 h-4"><MagnifyingGlassIcon /></span>
</div>
);
};

View File

@ -44,7 +44,7 @@ const Drawer: FunctionComponent<DrawerProps> = ({ title, children, onSave, edita
return (
<div>
<Button onClick={toggleDrawer}>{isOpen ? "Close" : "Open"} Drawer</Button>
<button className="ml-2 uppercase opacity-0 group-hover:opacity-100 text-gray-500 font-medium border border-gray-200 bg-white shadow hover:bg-gray-50 p-2 rounded-md" onClick={toggleDrawer}>Open</button>
<div className={drawerClassName}>
<div className="flex items-center justify-between p-4 border-b">
<h2>{title}</h2>