import Layout from "@/components/High/Layout"; import TicketDisplay from "@/components/High/TicketDisplay"; import Select from "@/components/Low/Select"; import Modal from "@/components/Modal"; import useTickets from "@/hooks/useTickets"; import useUser from "@/hooks/useUser"; import useUsers from "@/hooks/useUsers"; import { Ticket, TicketStatus, TicketStatusLabel, TicketType, TicketTypeLabel, } from "@/interfaces/ticket"; import { sessionOptions } from "@/lib/session"; import { shouldRedirectHome } from "@/utils/navigation.disabled"; import { createColumnHelper, flexRender, getCoreRowModel, useReactTable, } from "@tanstack/react-table"; import clsx from "clsx"; import { withIronSessionSsr } from "iron-session/next"; import moment from "moment"; import Head from "next/head"; import { useEffect, useState } from "react"; import { BsArrowDown, BsArrowUp } from "react-icons/bs"; import { ToastContainer } from "react-toastify"; const columnHelper = createColumnHelper(); export const getServerSideProps = withIronSessionSsr(({ req, res }) => { const user = req.session.user; if (!user || !user.isVerified) { res.setHeader("location", "/login"); res.statusCode = 302; res.end(); return { props: { user: null, }, }; } if (shouldRedirectHome(user) || user.type !== "developer") { res.setHeader("location", "/"); res.statusCode = 302; res.end(); return { props: { user: null, }, }; } return { props: { user: req.session.user }, }; }, sessionOptions); const StatusClassNames: { [key in TicketStatus]: string } = { submitted: "bg-mti-gray-dim", "in-progress": "bg-mti-blue-dark", completed: "bg-mti-green-dark", }; const TypesClassNames: { [key in TicketType]: string } = { feedback: "bg-mti-green-light", bug: "bg-mti-red-dark", help: "bg-mti-blue-light", }; export default function Tickets() { const [filteredTickets, setFilteredTickets] = useState([]); const [selectedTicket, setSelectedTicket] = useState(); const [assigneeFilter, setAssigneeFilter] = useState(); const [dateSorting, setDateSorting] = useState<"asc" | "desc">("desc"); const [typeFilter, setTypeFilter] = useState(); const [statusFilter, setStatusFilter] = useState(); const { user } = useUser({ redirectTo: "/login" }); const { users } = useUsers(); const { tickets, reload } = useTickets(); const sortByDate = (a: Ticket, b: Ticket) => { return moment((dateSorting === "desc" ? b : a).date).diff( moment((dateSorting === "desc" ? a : b).date), ); }; useEffect(() => { const filters = []; if (typeFilter) filters.push((x: Ticket) => x.type === typeFilter); if (statusFilter) filters.push((x: Ticket) => x.status === statusFilter); if (assigneeFilter) filters.push((x: Ticket) => x.assignedTo === assigneeFilter); setFilteredTickets( [...filters.reduce((d, f) => d.filter(f), tickets)].sort(sortByDate), ); }, [tickets, typeFilter, statusFilter, assigneeFilter, dateSorting]); const columns = [ columnHelper.accessor("id", { header: "ID", cell: (info) => info.getValue(), }), columnHelper.accessor("type", { header: "Type", cell: (info) => ( {TicketTypeLabel[info.getValue()]} ), }), columnHelper.accessor("reporter", { header: "Reporter", cell: (info) => info.getValue().email, }), columnHelper.accessor("reportedFrom", { header: "Reported From", cell: (info) => info.getValue(), }), columnHelper.accessor("date", { id: "date", header: ( ) as any, cell: (info) => moment(info.getValue()).format("DD/MM/YYYY - HH:mm"), }), columnHelper.accessor("subject", { header: "Subject", cell: (info) => info.getValue().substring(0, 12) + (info.getValue().length > 12 ? "..." : ""), }), columnHelper.accessor("status", { header: "Status", cell: (info) => ( {TicketStatusLabel[info.getValue()]} ), }), columnHelper.accessor("assignedTo", { header: "Assignee", cell: (info) => users.find((x) => x.id === info.getValue())?.name || "", }), ]; const table = useReactTable({ data: filteredTickets, columns: columns, getCoreRowModel: getCoreRowModel(), }); return ( <> { reload(); setSelectedTicket(undefined); }} > {selectedTicket && ( { reload(); setSelectedTicket(undefined); }} /> )} Tickets Panel | EnCoach {user && (

Tickets

({ value: x, label: TicketTypeLabel[x as keyof typeof TicketTypeLabel], }))} value={ typeFilter ? { value: typeFilter, label: TicketTypeLabel[typeFilter] } : undefined } onChange={(value) => setTypeFilter((value?.value as TicketType) ?? undefined) } isClearable placeholder="Type..." />