mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-03 19:40:16 -04:00
Completely forgot what I did
This commit is contained in:
parent
f9a6e71484
commit
ea547026cf
|
@ -1,37 +1,44 @@
|
|||
"use client"
|
||||
"use client";
|
||||
|
||||
import Sidebar from '@/components/resource/Sidebar';
|
||||
import React, { useState } from 'react';
|
||||
import { ChevronDoubleRightIcon } from '@heroicons/react/24/outline';
|
||||
import Sidebar from "@/components/Sidebar/Sidebar";
|
||||
import React, { useState } from "react";
|
||||
import { ChevronDoubleRightIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
children,
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
||||
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>
|
||||
)
|
||||
}
|
||||
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 isAdmin={true} setIsSidebarOpen={setIsSidebarOpen} />
|
||||
</div>
|
||||
{/* page ui */}
|
||||
<div
|
||||
className={`flex-1 transition duration-300 ease-in-out ${
|
||||
isSidebarOpen ? "ml-64" : "ml-0"
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,37 +1,44 @@
|
|||
"use client"
|
||||
"use client";
|
||||
|
||||
import Sidebar from '@/components/resource/Sidebar';
|
||||
import React, { useState } from 'react';
|
||||
import { ChevronDoubleRightIcon } from '@heroicons/react/24/outline';
|
||||
import Sidebar from "@/components/Sidebar/Sidebar";
|
||||
import React, { useState } from "react";
|
||||
import { ChevronDoubleRightIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
children,
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
||||
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>
|
||||
)
|
||||
}
|
||||
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 isAdmin={false} setIsSidebarOpen={setIsSidebarOpen} />
|
||||
</div>
|
||||
{/* page ui */}
|
||||
<div
|
||||
className={`flex-1 transition duration-300 ease-in-out ${
|
||||
isSidebarOpen ? "ml-64" : "ml-0"
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
246
compass/components/Drawer/Drawer.tsx
Normal file
246
compass/components/Drawer/Drawer.tsx
Normal file
|
@ -0,0 +1,246 @@
|
|||
import { FunctionComponent, ReactNode } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { ChevronDoubleLeftIcon } from "@heroicons/react/24/solid";
|
||||
import {
|
||||
StarIcon as SolidStarIcon,
|
||||
EnvelopeIcon,
|
||||
UserIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import {
|
||||
ArrowsPointingOutIcon,
|
||||
ArrowsPointingInIcon,
|
||||
StarIcon as OutlineStarIcon,
|
||||
ListBulletIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import TagsInput from "../TagsInput/Index";
|
||||
|
||||
type DrawerProps = {
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
type?: "button" | "submit" | "reset"; // specify possible values for type
|
||||
disabled?: boolean;
|
||||
editableContent?: any;
|
||||
onSave?: (content: any) => void;
|
||||
rowContent?: any;
|
||||
onRowUpdate?: (content: any) => void;
|
||||
};
|
||||
|
||||
interface EditContent {
|
||||
content: string;
|
||||
isEditing: boolean;
|
||||
}
|
||||
|
||||
const Drawer: FunctionComponent<DrawerProps> = ({
|
||||
title,
|
||||
children,
|
||||
onSave,
|
||||
editableContent,
|
||||
rowContent,
|
||||
onRowUpdate,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isFull, setIsFull] = useState(false);
|
||||
const [isFavorite, setIsFavorite] = useState(false);
|
||||
const [tempRowContent, setTempRowContent] = useState(rowContent);
|
||||
|
||||
const handleTempRowContentChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
console.log(name);
|
||||
console.log(value);
|
||||
setTempRowContent((prevContent) => ({
|
||||
...prevContent,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleEnterPress = (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
// Update the rowContent with the temporaryRowContent
|
||||
if (onRowUpdate) {
|
||||
onRowUpdate(tempRowContent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const toggleDrawer = () => {
|
||||
setIsOpen(!isOpen);
|
||||
if (isFull) {
|
||||
setIsFull(!isFull);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleDrawerFullScreen = () => setIsFull(!isFull);
|
||||
|
||||
const toggleFavorite = () => setIsFavorite(!isFavorite);
|
||||
|
||||
const drawerClassName = `fixed top-0 right-0 w-1/2 h-full bg-white transform ease-in-out duration-300 z-20 ${
|
||||
isOpen ? "translate-x-0 shadow-xl" : "translate-x-full"
|
||||
} ${isFull ? "w-full" : "w-1/2"}`;
|
||||
|
||||
const iconComponent = isFull ? (
|
||||
<ArrowsPointingInIcon className="h-5 w-5" />
|
||||
) : (
|
||||
<ArrowsPointingOutIcon className="h-5 w-5" />
|
||||
);
|
||||
|
||||
const favoriteIcon = isFavorite ? (
|
||||
<SolidStarIcon className="h-5 w-5" />
|
||||
) : (
|
||||
<OutlineStarIcon className="h-5 w-5" />
|
||||
);
|
||||
|
||||
const [presetOptions, setPresetOptions] = useState([
|
||||
"administrator",
|
||||
"volunteer",
|
||||
"employee",
|
||||
]);
|
||||
const [rolePresetOptions, setRolePresetOptions] = useState([
|
||||
"domestic",
|
||||
"community",
|
||||
"economic",
|
||||
]);
|
||||
const [tagColors, setTagColors] = useState(new Map());
|
||||
|
||||
const getTagColor = (tag: string) => {
|
||||
if (!tagColors.has(tag)) {
|
||||
const colors = [
|
||||
"bg-cyan-100",
|
||||
"bg-blue-100",
|
||||
"bg-green-100",
|
||||
"bg-yellow-100",
|
||||
"bg-purple-100",
|
||||
];
|
||||
const randomColor = colors[Math.floor(Math.random() * colors.length)];
|
||||
setTagColors(new Map(tagColors).set(tag, randomColor));
|
||||
}
|
||||
return tagColors.get(tag);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
className={
|
||||
"ml-2 text-xs 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>
|
||||
<div className={drawerClassName}>
|
||||
<div className="flex items-center justify-between p-4">
|
||||
<div className="flex flex-row items-center justify-between space-x-2">
|
||||
<span className="h-5 text-purple-200 w-5">
|
||||
<UserIcon />
|
||||
</span>
|
||||
<h2 className="text-lg text-gray-800 font-semibold">
|
||||
{rowContent.username}
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
onClick={toggleFavorite}
|
||||
className="py-2 text-gray-500 hover:text-gray-800 mr-2"
|
||||
>
|
||||
{favoriteIcon}
|
||||
</button>
|
||||
<button
|
||||
onClick={toggleDrawerFullScreen}
|
||||
className="py-2 text-gray-500 hover:text-gray-800 mr-2"
|
||||
>
|
||||
{iconComponent}
|
||||
</button>
|
||||
<button
|
||||
onClick={toggleDrawer}
|
||||
className="py-2 text-gray-500 hover:text-gray-800"
|
||||
>
|
||||
<ChevronDoubleLeftIcon className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<table className="p-4">
|
||||
<tbody className="items-center">
|
||||
<tr className="w-full text-xs items-center flex flex-row justify-between">
|
||||
<div className="flex flex-row space-x-2 text-gray-500 items-center">
|
||||
<td>
|
||||
<UserIcon className="h-4 w-4" />
|
||||
</td>
|
||||
<td className="w-32">Username</td>
|
||||
</div>
|
||||
<td className="w-3/4 w-3/4 p-2 pl-0">
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
value={tempRowContent.username}
|
||||
onChange={handleTempRowContentChange}
|
||||
onKeyDown={handleEnterPress}
|
||||
className="ml-2 w-full p-1 focus:outline-gray-200 hover:bg-gray-50"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="w-full text-xs items-center flex flex-row justify-between">
|
||||
<div className="flex flex-row space-x-2 text-gray-500 items-center">
|
||||
<td>
|
||||
<ListBulletIcon className="h-4 w-4" />
|
||||
</td>
|
||||
<td className="w-32">Role</td>
|
||||
</div>
|
||||
<td className="w-3/4 hover:bg-gray-50">
|
||||
<TagsInput
|
||||
presetValue={tempRowContent.role}
|
||||
presetOptions={presetOptions}
|
||||
setPresetOptions={setPresetOptions}
|
||||
getTagColor={getTagColor}
|
||||
setTagColors={setTagColors}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="w-full text-xs items-center flex flex-row justify-between">
|
||||
<div className="flex flex-row space-x-2 text-gray-500 items-center">
|
||||
<td>
|
||||
<EnvelopeIcon className="h-4 w-4" />
|
||||
</td>
|
||||
<td className="w-32">Email</td>
|
||||
</div>
|
||||
<td className="w-3/4 p-2 pl-0">
|
||||
<input
|
||||
type="text"
|
||||
name="email"
|
||||
value={tempRowContent.email}
|
||||
onChange={handleTempRowContentChange}
|
||||
onKeyDown={handleEnterPress}
|
||||
className="ml-2 w-80 p-1 font-normal hover:text-gray-400 focus:outline-gray-200 hover:bg-gray-50 underline text-gray-500"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="w-full text-xs items-center flex flex-row justify-between">
|
||||
<div className="flex flex-row space-x-2 text-gray-500 items-center">
|
||||
<td>
|
||||
<ListBulletIcon className="h-4 w-4" />
|
||||
</td>
|
||||
<td className="w-32">Type of Program</td>
|
||||
</div>
|
||||
<td className="w-3/4 hover:bg-gray-50">
|
||||
{/* {rowContent.program} */}
|
||||
<TagsInput
|
||||
presetValue={tempRowContent.program}
|
||||
presetOptions={rolePresetOptions}
|
||||
setPresetOptions={setRolePresetOptions}
|
||||
getTagColor={getTagColor}
|
||||
setTagColors={setTagColors}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Drawer;
|
|
@ -15,7 +15,7 @@ export const PageLayout: React.FC<PageLayoutProps> = ({ icon, title, children })
|
|||
</div>
|
||||
</div>
|
||||
{/* data */}
|
||||
<div className="px-8 py-8">
|
||||
<div className="px-8">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
|
67
compass/components/Sidebar/Sidebar.tsx
Normal file
67
compass/components/Sidebar/Sidebar.tsx
Normal file
|
@ -0,0 +1,67 @@
|
|||
import React from "react";
|
||||
import {
|
||||
HomeIcon,
|
||||
ChevronDoubleLeftIcon,
|
||||
BookmarkIcon,
|
||||
ClipboardIcon,
|
||||
BookOpenIcon,
|
||||
UserGroupIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import { SidebarItem } from "./SidebarItem";
|
||||
import { UserProfile } from "../resource/UserProfile";
|
||||
|
||||
interface SidebarProps {
|
||||
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
isAdmin: boolean;
|
||||
}
|
||||
|
||||
const Sidebar: React.FC<SidebarProps> = ({ setIsSidebarOpen, isAdmin }) => {
|
||||
return (
|
||||
<div className="w-64 h-full border border-gray-200 bg-gray-50 px-4">
|
||||
{/* button to close sidebar */}
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
onClick={() => setIsSidebarOpen(false)}
|
||||
className="py-2 text-gray-500 hover:text-gray-800"
|
||||
aria-label="Close sidebar"
|
||||
>
|
||||
<ChevronDoubleLeftIcon className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-8">
|
||||
{/* user + logout button */}
|
||||
<div className="flex items-center p-4 space-x-2 border border-gray-200 rounded-md ">
|
||||
<UserProfile />
|
||||
</div>
|
||||
{/* navigation menu */}
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-xs font-semibold text-gray-500">Pages</h4>
|
||||
<nav className="flex flex-col">
|
||||
{!isAdmin && (
|
||||
<SidebarItem active={false} icon={<HomeIcon />} text="Home" />
|
||||
)}
|
||||
{isAdmin && (
|
||||
<SidebarItem
|
||||
active={false}
|
||||
icon={<UserGroupIcon />}
|
||||
text="Users"
|
||||
/>
|
||||
)}
|
||||
<SidebarItem
|
||||
active={false}
|
||||
icon={<BookmarkIcon />}
|
||||
text="Resources"
|
||||
/>
|
||||
<SidebarItem
|
||||
active={false}
|
||||
icon={<ClipboardIcon />}
|
||||
text="Services"
|
||||
/>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
|
@ -1,45 +0,0 @@
|
|||
import { Component } from "react"
|
||||
|
||||
// interface TableHeader {
|
||||
// title: string,
|
||||
// type: string
|
||||
// }
|
||||
|
||||
// interface TableRow {
|
||||
// [key: string]: any,
|
||||
// }
|
||||
interface TableProps {
|
||||
headersData: string[];
|
||||
data: { [key: string]: any }[];
|
||||
}
|
||||
|
||||
const Table: React.FC<TableProps> = ({ headersData, data }) => {
|
||||
const headers = headersData.map((header, i) => {
|
||||
return <th key={"header-" + i} >{header}</th>
|
||||
})
|
||||
|
||||
console.log(data);
|
||||
|
||||
const rows = data.map((item) => {
|
||||
const row = headersData.map(key => {
|
||||
return <td key={"item-" + item.id + key}>{item[key]}</td>
|
||||
});
|
||||
return <tr key={"item-" + item.id}>{row}</tr>
|
||||
})
|
||||
|
||||
return (<>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
{headers}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows}
|
||||
</tbody>
|
||||
</table>
|
||||
</>);
|
||||
|
||||
}
|
||||
|
||||
export default Table
|
|
@ -1,11 +1,11 @@
|
|||
/* An extension of TableCell.tsx that includes an "open" button and the drawer.
|
||||
For cells in the "primary" (or first) column of the table. */
|
||||
import Drawer from "@/components/page/Drawer";
|
||||
import Drawer from "@/components/Drawer/Drawer";
|
||||
import { TableCell } from "./TableCell";
|
||||
import { SetStateAction, useState } from "react";
|
||||
|
||||
export const PrimaryTableCell = ({ getValue, row, column, table }) => {
|
||||
const [pageContent, setPageContent] = useState("")
|
||||
const [pageContent, setPageContent] = useState("");
|
||||
|
||||
const handleDrawerContentChange = (newContent: SetStateAction<string>) => {
|
||||
setPageContent(newContent);
|
||||
|
@ -15,7 +15,13 @@ export const PrimaryTableCell = ({ getValue, row, column, table }) => {
|
|||
<div className="font-semibold group">
|
||||
<TableCell getValue={getValue} row={row} column={column} table={table} />
|
||||
<span className="absolute right-1 top-1">
|
||||
<Drawer title={getValue()} editableContent={pageContent} onSave={handleDrawerContentChange}>{pageContent}</Drawer>
|
||||
<Drawer
|
||||
title={getValue()}
|
||||
editableContent={pageContent}
|
||||
onSave={handleDrawerContentChange}
|
||||
>
|
||||
{pageContent}
|
||||
</Drawer>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
import Drawer from "@/components/page/Drawer";
|
||||
import {ChangeEvent, useState} from "react";
|
||||
import Drawer from "@/components/Drawer/Drawer";
|
||||
import { ChangeEvent, useState } from "react";
|
||||
|
||||
export const RowOpenAction = ({ title, rowData, onRowUpdate }) => {
|
||||
const [pageContent, setPageContent] = useState("")
|
||||
|
||||
const handleDrawerContentChange = (newContent) => {
|
||||
setPageContent(newContent);
|
||||
};
|
||||
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 >
|
||||
<span>
|
||||
{/* Added OnRowUpdate to drawer */}
|
||||
<Drawer title="My Drawer Title" editableContent={pageContent} rowContent={rowData} onSave={handleDrawerContentChange} onRowUpdate={onRowUpdate}>{pageContent}</Drawer>
|
||||
</span>
|
||||
<Drawer
|
||||
title="My Drawer Title"
|
||||
editableContent={pageContent}
|
||||
rowContent={rowData}
|
||||
onSave={handleDrawerContentChange}
|
||||
onRowUpdate={onRowUpdate}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import { TrashIcon, DocumentDuplicateIcon, ArrowUpRightIcon, EyeSlashIcon } from
|
|||
|
||||
export const RowOption = ({ icon: Icon, label, onClick }) => {
|
||||
return (
|
||||
<button onClick={onClick} className="hover:bg-gray-100 flex items-center gap-2 p-2 w-full">
|
||||
<button onClick={onClick} className="hover:bg-gray-100 flex items-center gap-1 p-1 w-full">
|
||||
<Icon className="inline h-4" /> {label}
|
||||
</button>
|
||||
);
|
||||
|
|
|
@ -19,12 +19,12 @@ export const RowOptionMenu = ({ onDelete, onHide }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<button className="align-center" onClick={() => setMenuOpen(!menuOpen)}>
|
||||
<button className="items-end" onClick={() => setMenuOpen(!menuOpen)}>
|
||||
<EllipsisVerticalIcon className="h-4" />
|
||||
</button>
|
||||
<div
|
||||
className={
|
||||
"justify-start border border-gray-200 shadow-lg flex flex-col absolute bg-white w-auto p-2 rounded [&>*]:rounded z-10" +
|
||||
"justify-start border border-gray-200 shadow-lg flex flex-col absolute bg-white w-auto p-1 rounded [&>*]:rounded z-10" +
|
||||
(!menuOpen ? " invisible" : "")
|
||||
}
|
||||
>
|
||||
|
|
|
@ -116,7 +116,7 @@ const TagsInput: React.FC<TagsInputProps> = ({
|
|||
<TagsArray handleDelete={handleDeleteTag} tags={tags} />
|
||||
) : (
|
||||
<div ref={dropdown}>
|
||||
<div className="absolute w-64 z-50 -ml-3 -mt-7">
|
||||
<div className="absolute w-64 z-50 -ml-1 -mt-5">
|
||||
<div className="rounded-md border border-gray-200 shadow">
|
||||
<div className="flex flex-wrap rounded-t-md items-center gap-2 bg-gray-50 p-2">
|
||||
<TagsArray handleDelete={handleDeleteTag} active tags={tags} />
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import React, { ReactNode, useState } from "react";
|
||||
|
||||
|
||||
interface TagProps {
|
||||
text: string;
|
||||
icon: React.ReactNode;
|
||||
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
|
||||
const Card: React.FC<TagProps> = ({children, text, icon, onClick }) => {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="flex flex-row space-x-2 items-start justify-start border border-gray-200 bg-white hover:bg-gray-50 shadow rounded-md p-4 focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-opacity-50 w-1/4"
|
||||
>
|
||||
<span className="h-5 text-purple-700 w-5">
|
||||
{icon}
|
||||
</span>
|
||||
<span className="text-sm text-gray-800 font-semibold">
|
||||
{text}
|
||||
</span>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default Card;
|
|
@ -1,30 +0,0 @@
|
|||
import React, { ChangeEvent, FunctionComponent } from 'react';
|
||||
|
||||
// Define the shape of a single option
|
||||
interface DropdownOption {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
// Define the props for the Dropdown component
|
||||
interface DropdownProps {
|
||||
options: DropdownOption[];
|
||||
onChange: (event: ChangeEvent<HTMLSelectElement>) => void; // Type for change event on <select>
|
||||
defaultValue?: string | number;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
// Dropdown Component
|
||||
const Dropdown: FunctionComponent<DropdownProps> = ({ options, onChange, defaultValue, id }) => {
|
||||
return (
|
||||
<select id={id} defaultValue={defaultValue} onChange={onChange} className="form-select form-select-lg mb-3">
|
||||
{options.map((option, index) => (
|
||||
<option key={index} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dropdown;
|
|
@ -1,46 +0,0 @@
|
|||
import React from 'react';
|
||||
import { HomeIcon, ChevronDoubleLeftIcon, BookmarkIcon, ClipboardIcon, BookOpenIcon } from '@heroicons/react/24/solid';
|
||||
import { SidebarItem } from './SidebarItem';
|
||||
import { UserProfile } from './UserProfile';
|
||||
|
||||
interface SidebarProps {
|
||||
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const Sidebar: React.FC<SidebarProps> = ({ setIsSidebarOpen }) => {
|
||||
return (
|
||||
<div className="w-64 h-full border border-gray-200 bg-gray-50 px-4">
|
||||
{/* button to close sidebar */}
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
onClick={() => setIsSidebarOpen(false)}
|
||||
className="py-2 text-gray-500 hover:text-gray-800"
|
||||
aria-label="Close sidebar"
|
||||
>
|
||||
<ChevronDoubleLeftIcon className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-8">
|
||||
|
||||
{/* user + logout button */}
|
||||
<div className="flex items-center p-4 space-x-2 border border-gray-200 rounded-md ">
|
||||
|
||||
<UserProfile />
|
||||
</div>
|
||||
{/* navigation menu */}
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-xs font-semibold text-gray-500">Pages</h4>
|
||||
<nav className="flex flex-col">
|
||||
<SidebarItem active={true} icon={<HomeIcon />} text="Home" />
|
||||
<SidebarItem icon={<BookmarkIcon />} text="Resources" />
|
||||
<SidebarItem icon={<ClipboardIcon />} text="Services" />
|
||||
<SidebarItem icon={<BookOpenIcon />} text="Training Manuals" />
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default Sidebar;
|
Loading…
Reference in New Issue
Block a user