Added a list for codes, for users to delete unused ones

This commit is contained in:
Tiago Ribeiro
2024-04-04 23:05:12 +01:00
parent 11e2ea3249
commit fe2abaacae
4 changed files with 137 additions and 1 deletions

View File

@@ -0,0 +1,106 @@
import useCodes from "@/hooks/useCodes";
import {Code, User} from "@/interfaces/user";
import {createColumnHelper, flexRender, getCoreRowModel, useReactTable} from "@tanstack/react-table";
import axios from "axios";
import {BsTrash} from "react-icons/bs";
import {toast} from "react-toastify";
const columnHelper = createColumnHelper<Code>();
export default function CodeList({user}: {user: User}) {
const {codes, reload} = useCodes(user?.type === "corporate" ? user?.id : undefined);
const deleteCode = async (code: Code) => {
if (!confirm(`Are you sure you want to delete this "${code.code}" code?`)) return;
axios
.delete(`/api/code/${code.code}`)
.then(() => toast.success(`Deleted the "${code.code}" exam`))
.catch((reason) => {
if (reason.response.status === 404) {
toast.error("Code not found!");
return;
}
if (reason.response.status === 403) {
toast.error("You do not have permission to delete this code!");
return;
}
toast.error("Something went wrong, please try again later.");
})
.finally(reload);
};
const defaultColumns = [
columnHelper.accessor("code", {
header: "Code",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("email", {
header: "Invited E-mail",
cell: (info) => info.getValue() || "N/A",
}),
columnHelper.accessor("userId", {
header: "Availability",
cell: (info) =>
info.getValue() ? (
<span className="flex gap-1 items-center text-mti-green">
<div className="w-2 h-2 rounded-full bg-mti-green" /> In Use
</span>
) : (
<span className="flex gap-1 items-center text-mti-red">
<div className="w-2 h-2 rounded-full bg-mti-red" /> Unused
</span>
),
}),
{
header: "",
id: "actions",
cell: ({row}: {row: {original: Code}}) => {
return (
<div className="flex gap-4">
{!row.original.userId && (
<div data-tip="Delete" className="cursor-pointer tooltip" onClick={() => deleteCode(row.original)}>
<BsTrash className="hover:text-mti-purple-light transition ease-in-out duration-300" />
</div>
)}
</div>
);
},
},
];
const table = useReactTable({
data: codes,
columns: defaultColumns,
getCoreRowModel: getCoreRowModel(),
});
return (
<table className="rounded-xl bg-mti-purple-ultralight/40 w-full">
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th className="p-4 text-left" key={header.id}>
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
</th>
))}
</tr>
))}
</thead>
<tbody className="px-2">
{table.getRowModel().rows.map((row) => (
<tr className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2" key={row.id}>
{row.getVisibleCells().map((cell) => (
<td className="px-4 py-2" key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
);
}

View File

@@ -1,6 +1,7 @@
import {User} from "@/interfaces/user";
import {Tab} from "@headlessui/react";
import clsx from "clsx";
import CodeList from "./CodeList";
import ExamList from "./ExamList";
import GroupList from "./GroupList";
import PackageList from "./PackageList";
@@ -45,6 +46,19 @@ export default function Lists({user}: {user: User}) {
}>
Group List
</Tab>
{user && ["developer", "admin", "corporate"].includes(user.type) && (
<Tab
className={({selected}) =>
clsx(
"w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-mti-purple-light",
"ring-white ring-opacity-60 ring-offset-2 ring-offset-mti-purple-light focus:outline-none focus:ring-2",
"transition duration-300 ease-in-out",
selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark",
)
}>
Code List
</Tab>
)}
{user && ["developer", "admin"].includes(user.type) && (
<Tab
className={({selected}) =>
@@ -71,6 +85,11 @@ export default function Lists({user}: {user: User}) {
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<GroupList user={user} />
</Tab.Panel>
{user && ["developer", "admin", "corporate"].includes(user.type) && (
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<CodeList user={user} />
</Tab.Panel>
)}
{user && ["developer", "admin"].includes(user.type) && (
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<PackageList user={user} />