import Button from "@/components/Low/Button"; import Checkbox from "@/components/Low/Checkbox"; import useUsers from "@/hooks/useUsers"; import { Code, User } from "@/interfaces/user"; import { USER_TYPE_LABELS } from "@/resources/user"; import { createColumnHelper } from "@tanstack/react-table"; import axios from "axios"; import moment from "moment"; import { useState, useMemo } from "react"; import { BsTrash } from "react-icons/bs"; import { toast } from "react-toastify"; import { EntityWithRoles } from "@/interfaces/entity"; import { isAdmin } from "@/utils/users"; import { findBy, mapBy } from "@/utils"; import useEntitiesCodes from "@/hooks/useEntitiesCodes"; import Table from "@/components/High/Table"; type TableData = Code & { entity?: EntityWithRoles; creator?: User }; const columnHelper = createColumnHelper(); export default function CodeList({ user, entities, canDeleteCodes, }: { user: User; entities: EntityWithRoles[]; canDeleteCodes?: boolean; }) { const [selectedCodes, setSelectedCodes] = useState([]); const entityIDs = useMemo(() => mapBy(entities, "id"), [entities]); const { users } = useUsers(); const { codes, reload, isLoading } = useEntitiesCodes( isAdmin(user) ? undefined : entityIDs ); const data: TableData[] = useMemo( () => codes.map((code) => ({ ...code, entity: findBy(entities, "id", code.entity), creator: findBy(users, "id", code.creator), })) as TableData[], [codes, entities, users] ); const toggleCode = (id: string) => { setSelectedCodes((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id] ); }; // const toggleAllCodes = (checked: boolean) => { // if (checked) return setSelectedCodes(visibleRows.filter((x) => !x.userId).map((x) => x.code)); // return setSelectedCodes([]); // }; const deleteCodes = async (codes: string[]) => { if (!canDeleteCodes) return; if ( !confirm(`Are you sure you want to delete these ${codes.length} code(s)?`) ) return; const params = new URLSearchParams(); codes.forEach((code) => params.append("code", code)); axios .delete(`/api/code?${params.toString()}`) .then(() => { toast.success(`Deleted the codes!`); setSelectedCodes([]); }) .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 deleteCode = async (code: Code) => { if (!canDeleteCodes) return; 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", { id: "codeCheckbox", enableSorting: false, header: () => "", cell: (info) => !info.row.original.userId ? ( toggleCode(info.getValue())} > {""} ) : null, }), columnHelper.accessor("code", { header: "Code", cell: (info) => info.getValue(), }), columnHelper.accessor("creationDate", { header: "Creation Date", cell: (info) => info.getValue() ? moment(info.getValue()).format("DD/MM/YYYY") : "N/A", }), columnHelper.accessor("email", { header: "E-mail", cell: (info) => info.getValue() || "N/A", }), columnHelper.accessor("creator", { header: "Creator", cell: (info) => info.getValue() ? `${info.getValue().name} (${ USER_TYPE_LABELS[info.getValue().type] })` : "N/A", }), columnHelper.accessor("entity", { header: "Entity", cell: (info) => info.getValue()?.label || "N/A", }), columnHelper.accessor("userId", { header: "Availability", cell: (info) => info.getValue() ? (
In Use ) : (
Unused ), }), { header: "", id: "actions", cell: ({ row }: { row: { original: Code } }) => { return (
{canDeleteCodes && !row.original.userId && (
deleteCode(row.original)} >
)}
); }, }, ]; return ( <>
{canDeleteCodes && (
{selectedCodes.length} code(s) selected
)}
data={data} columns={defaultColumns} isLoading={isLoading} searchFields={[ ["code"], ["email"], ["entity", "label"], ["creator", "name"], ["creator", "type"], ]} /> ); }