Started moving data manipulation into Table

This commit is contained in:
Nick A 2024-10-15 20:01:16 -04:00
parent b5b80e666a
commit 2e93d82abf
2 changed files with 191 additions and 5 deletions

View File

@ -0,0 +1,152 @@
import { PageLayout } from "@/components/PageLayout";
import { RowOpenAction } from "@/components/Table/RowOpenAction";
import { RowOptionMenu } from "@/components/Table/RowOptionMenu";
import { Table } from "@/components/Table/Table";
import TagsInput from "@/components/TagsInput/Index";
import Resource from "@/utils/models/Resource";
import { createClient } from "@/utils/supabase/client";
import { Bars2Icon, BookmarkIcon } from "@heroicons/react/24/solid";
import { ColumnDef, createColumnHelper } from "@tanstack/react-table";
import { useEffect, useState } from "react";
export function ResourceTable({ resources }: { resources: Resource[] }) {
const columnHelper = createColumnHelper<Resource>();
const [data, setData] = useState<Resource[]>([...resources]);
// TODO: Connect data manipulation methods to the database (deleteResource, hideResource, addResource)
const deleteUser = (userId: number) => {
console.log(data);
setData((currentData) =>
currentData.filter((user) => user.id !== userId)
);
};
const hideUser = (userId: number) => {
console.log(`Toggling visibility for user with ID: ${userId}`);
setData((currentData) => {
const newData = currentData
.map((user) => {
if (user.id === userId) {
return { ...user, visible: !user.visible };
}
return user;
})
.sort((a, b) =>
a.visible === b.visible ? 0 : a.visible ? -1 : 1
);
console.log(newData);
return newData;
});
};
const addUser = () => {
setData([...data]);
};
const [presetOptions, setPresetOptions] = useState([
"administrator",
"volunteer",
"employee",
]);
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);
};
const handleRowUpdate = (updatedRow: Resource) => {
const dataIndex = data.findIndex((row) => row.id === updatedRow.id);
if (dataIndex !== -1) {
const updatedData = [...data];
updatedData[dataIndex] = updatedRow;
setData(updatedData);
}
};
const columns: ColumnDef<Resource, any>[] = [
columnHelper.display({
id: "options",
cell: (props) => (
<RowOptionMenu
onDelete={() => {}}
onHide={() => hideUser(props.row.original.id)}
/>
),
}),
columnHelper.accessor("name", {
header: () => (
<>
<Bars2Icon className="inline align-top h-4" /> Name
</>
),
cell: (info) => (
<RowOpenAction
title={info.getValue()}
rowData={info.row.original}
onRowUpdate={handleRowUpdate}
/>
),
}),
columnHelper.accessor("link", {
header: () => (
<>
<Bars2Icon className="inline align-top h-4" /> Link
</>
),
cell: (info) => (
<a
href={info.getValue()}
target={"_blank"}
className="ml-2 text-gray-500 underline hover:text-gray-400"
>
{info.getValue()}
</a>
),
}),
columnHelper.accessor("program", {
header: () => (
<>
<Bars2Icon className="inline align-top h-4" /> Program
</>
),
cell: (info) => (
<TagsInput presetValue={info.getValue()} />
),
}),
columnHelper.accessor("summary", {
header: () => (
<>
<Bars2Icon className="inline align-top h-4" /> Summary
</>
),
cell: (info) => (
<span className="ml-2 text-gray-500">{info.getValue()}</span>
),
}),
];
return (
<div className="min-h-screen flex flex-col">
{/* icon + title */}
<PageLayout title="Resources" icon={<BookmarkIcon />}>
<Table initialData={resources} columns={columns}/>
</PageLayout>
</div>
);
}

View File

@ -11,6 +11,8 @@ import {
} from "@heroicons/react/24/solid";
import { rankItem } from "@tanstack/match-sorter-utils";
import Resource from "@/utils/models/Resource";
import Service from "@/utils/models/Service";
import User from "@/utils/models/User"
// For search
const fuzzyFilter = (
@ -37,7 +39,39 @@ export const Table = ({ initialData, columns }: { initialData: Resource[], colum
setData(sortedData);
}, [initialData]);
const [data, setData] = useState<Resource[]>([...initialData]);
const [data, setData] = useState<(Resource | User | Service)[]>([...initialData]);
// Data manipulation
// TODO: Connect data manipulation methods to the database (deleteResource, hideResource, addResource)
const deleteData = (dataId: number) => {
console.log(data);
setData((currentData) =>
currentData.filter((data) => data.id !== dataId)
);
};
const hideData = (dataId: number) => {
console.log(`Toggling visibility for data with ID: ${dataId}`);
setData((currentData) => {
const newData = currentData
.map((data) => {
if (data.id === dataId) {
return { ...data, visible: !data.visible };
}
return data;
})
.sort((a, b) =>
a.visible === b.visible ? 0 : a.visible ? -1 : 1
);
console.log(newData);
return newData;
});
};
const addData = () => {
setData([...data]);
};
// Searching
const [query, setQuery] = useState("");
@ -54,7 +88,7 @@ export const Table = ({ initialData, columns }: { initialData: Resource[], colum
// TODO: Filtering
// TODO: Sorting
const table = useReactTable({
columns,
data,
@ -113,9 +147,9 @@ export const Table = ({ initialData, columns }: { initialData: Resource[], colum
<tbody>
{table.getRowModel().rows.map((row) => {
// Individual row
const isUserVisible = row.original.visible;
const isDataVisible = row.original.visible;
const rowClassNames = `text-gray-800 border-y lowercase hover:bg-gray-50 ${
!isUserVisible ? "bg-gray-200 text-gray-500" : ""
!isDataVisible ? "bg-gray-200 text-gray-500" : ""
}`;
return (
<tr className={rowClassNames} key={row.id}>
@ -141,7 +175,7 @@ export const Table = ({ initialData, columns }: { initialData: Resource[], colum
<td
className="p-3 border-y border-gray-200 text-gray-600 hover:bg-gray-50"
colSpan={100}
onClick={addUser}
onClick={addData}
>
<span className="flex ml-1 text-gray-500">
<PlusIcon className="inline h-4 mr-1" />