diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx index 85cb5073..d822ae66 100644 --- a/src/pages/settings.tsx +++ b/src/pages/settings.tsx @@ -22,16 +22,16 @@ export const getServerSideProps = withIronSessionSsr(({req, res}) => { redirect: { destination: "/login", permanent: false, - } + }, }; } - if (shouldRedirectHome(user) || user.type !== "developer") { + if (shouldRedirectHome(user) || !["developer", "admin", "corporate", "agent"].includes(user.type)) { return { redirect: { destination: "/", permanent: false, - } + }, }; } diff --git a/src/pages/tickets.tsx b/src/pages/tickets.tsx index 128058e4..1f640547 100644 --- a/src/pages/tickets.tsx +++ b/src/pages/tickets.tsx @@ -5,388 +5,308 @@ 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, - TicketWithCorporate, -} from "@/interfaces/ticket"; -import { sessionOptions } from "@/lib/session"; -import { shouldRedirectHome } from "@/utils/navigation.disabled"; -import { - createColumnHelper, - flexRender, - getCoreRowModel, - useReactTable, -} from "@tanstack/react-table"; +import {Ticket, TicketStatus, TicketStatusLabel, TicketType, TicketTypeLabel, TicketWithCorporate} 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 {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"; +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; +export const getServerSideProps = withIronSessionSsr(({req, res}) => { + const user = req.session.user; - if (!user || !user.isVerified) { + if (!user || !user.isVerified) { return { redirect: { destination: "/login", permanent: false, - } + }, }; - } + } - if ( - shouldRedirectHome(user) || - ["admin", "developer", "agent"].includes(user.type) - ) { + if (shouldRedirectHome(user) || !["admin", "developer", "agent"].includes(user.type)) { return { redirect: { destination: "/", permanent: false, - } + }, }; - } + } - return { - props: { user: req.session.user }, - }; + 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 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", +const TypesClassNames: {[key in TicketType]: string} = { + feedback: "bg-mti-green-light", + bug: "bg-mti-red-dark", + help: "bg-mti-blue-light", }; -const escapedURL = process.env.NEXT_PUBLIC_WEBSITE_URL || ''.replace( - /[.*+?^${}()|[\]\\]/g, - "\\$&" -); +const escapedURL = process.env.NEXT_PUBLIC_WEBSITE_URL || "".replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const fromHomepage = [new RegExp(`^${escapedURL}`), /\/contact$/]; type Source = "webpage" | "platform" | ""; const SOURCE_OPTIONS = [ - { value: "", label: "All" }, - { value: "webpage", label: "Webpage" }, - { value: "platform", label: "Platform" }, -] + {value: "", label: "All"}, + {value: "webpage", label: "Webpage"}, + {value: "platform", label: "Platform"}, +]; export default function Tickets() { - const [filteredTickets, setFilteredTickets] = useState([]); - const [selectedTicket, setSelectedTicket] = useState(); - const [assigneeFilter, setAssigneeFilter] = useState(); - const [sourceFilter, setSourceFilter] = useState(""); + const [filteredTickets, setFilteredTickets] = useState([]); + const [selectedTicket, setSelectedTicket] = useState(); + const [assigneeFilter, setAssigneeFilter] = useState(); + const [sourceFilter, setSourceFilter] = useState(""); - const [dateSorting, setDateSorting] = useState<"asc" | "desc">("desc"); + const [dateSorting, setDateSorting] = useState<"asc" | "desc">("desc"); - const [typeFilter, setTypeFilter] = useState(); - const [statusFilter, setStatusFilter] = useState(); + const [typeFilter, setTypeFilter] = useState(); + const [statusFilter, setStatusFilter] = useState(); - const { user } = useUser({ redirectTo: "/login" }); - const { users } = useUsers(); - const { tickets, reload } = useTickets(); + 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) - ); - }; + const sortByDate = (a: Ticket, b: Ticket) => { + return moment((dateSorting === "desc" ? b : a).date).diff(moment((dateSorting === "desc" ? a : b).date)); + }; - useEffect(() => { - const filters = []; - if (user?.type === "agent") - filters.push((x: Ticket) => x.assignedTo === user.id); - 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); - if (sourceFilter) { - if (sourceFilter === "webpage") - filters.push((x: Ticket) => fromHomepage.some((r) => r.test(x.reportedFrom))); - if (sourceFilter === "platform") - filters.push((x: Ticket) => !fromHomepage.some((r) => r.test(x.reportedFrom))); - } - setFilteredTickets( - [...filters.reduce((d, f) => d.filter(f), tickets)].sort(sortByDate) - ); - }, [tickets, typeFilter, statusFilter, assigneeFilter, dateSorting, user, sourceFilter]); + useEffect(() => { + const filters = []; + if (user?.type === "agent") filters.push((x: Ticket) => x.assignedTo === user.id); + 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); + if (sourceFilter) { + if (sourceFilter === "webpage") filters.push((x: Ticket) => fromHomepage.some((r) => r.test(x.reportedFrom))); + if (sourceFilter === "platform") filters.push((x: Ticket) => !fromHomepage.some((r) => r.test(x.reportedFrom))); + } + setFilteredTickets([...filters.reduce((d, f) => d.filter(f), tickets)].sort(sortByDate)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [tickets, typeFilter, statusFilter, assigneeFilter, dateSorting, user, sourceFilter]); - 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 || "", - }), - columnHelper.accessor("corporate", { - header: "Corporate", - cell: (info) => info.getValue(), - }), - ]; + 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 || "", + }), + columnHelper.accessor("corporate", { + header: "Corporate", + cell: (info) => info.getValue(), + }), + ]; - const getAssigneeValue = () => { - if (user && user.type === "agent") - return { value: user.id, label: `${user.name} - ${user.email}` }; + const getAssigneeValue = () => { + if (user && user.type === "agent") return {value: user.id, label: `${user.name} - ${user.email}`}; - if (assigneeFilter) { - const assigneeUser = users.find((x) => x.id === assigneeFilter); - return assigneeUser - ? { - value: assigneeFilter, - label: `${assigneeUser.name} - ${assigneeUser.email}`, - } - : null; - } + if (assigneeFilter) { + const assigneeUser = users.find((x) => x.id === assigneeFilter); + return assigneeUser + ? { + value: assigneeFilter, + label: `${assigneeUser.name} - ${assigneeUser.email}`, + } + : null; + } - return null; - }; + return null; + }; - const table = useReactTable({ - data: filteredTickets, - columns: columns, - getCoreRowModel: getCoreRowModel(), - }); + const table = useReactTable({ + data: filteredTickets, + columns: columns, + getCoreRowModel: getCoreRowModel(), + }); - return ( - <> - { - reload(); - setSelectedTicket(undefined); - }} - > - {selectedTicket && ( - { - reload(); - setSelectedTicket(undefined); - }} - /> - )} - + return ( + <> + { + reload(); + setSelectedTicket(undefined); + }}> + {selectedTicket && ( + { + reload(); + setSelectedTicket(undefined); + }} + /> + )} + - - Tickets Panel | EnCoach - - - - - - {user && ( - -

Tickets

+ + 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..." - /> -
-
- - x.value === sourceFilter)} - onChange={(value) => setSourceFilter(value?.value as Source) - } - /> -
-
+
+
+ + ({ + 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..." + /> +
+
+ + x.value === sourceFilter)} + onChange={(value) => setSourceFilter(value?.value as Source)} + /> +
+
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - - ))} - - ))} - - - {table.getRowModel().rows.map((row) => ( - setSelectedTicket(row.original)} - key={row.id} - > - {row.getVisibleCells().map((cell) => ( - - ))} - - ))} - -
- {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} -
- {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} -
-
- )} - - ); + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + ))} + + ))} + + + {table.getRowModel().rows.map((row) => ( + setSelectedTicket(row.original)} + key={row.id}> + {row.getVisibleCells().map((cell) => ( + + ))} + + ))} + +
+ {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} +
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+
+ )} + + ); }