link-stack/apps/link/app/(main)/_components/Sidebar.tsx

679 lines
20 KiB
TypeScript
Raw Normal View History

2023-06-26 10:07:12 +00:00
"use client";
2023-10-16 09:20:40 +02:00
import { FC, useEffect, useState } from "react";
2023-06-07 08:02:29 +00:00
import useSWR from "swr";
2022-12-02 10:55:56 +00:00
import {
Box,
Grid,
Typography,
List,
2022-12-14 13:24:50 +01:00
ListItemButton,
2022-12-02 10:55:56 +00:00
ListItemIcon,
ListItemText,
2022-12-14 13:24:50 +01:00
ListItemSecondaryAction,
2022-12-02 10:55:56 +00:00
Drawer,
2022-12-14 13:24:50 +01:00
Collapse,
2022-12-02 10:55:56 +00:00
} from "@mui/material";
2022-12-02 17:45:14 +01:00
import {
FeaturedPlayList as FeaturedPlayListIcon,
Person as PersonIcon,
2023-08-25 07:11:33 +00:00
Insights as InsightsIcon,
2022-12-02 17:45:14 +01:00
Logout as LogoutIcon,
Cottage as CottageIcon,
Settings as SettingsIcon,
2023-01-11 16:18:56 +01:00
ExpandCircleDown as ExpandCircleDownIcon,
2023-06-07 08:02:29 +00:00
Dvr as DvrIcon,
2023-08-25 07:11:33 +00:00
Assessment as AssessmentIcon,
LibraryBooks as LibraryBooksIcon,
2023-10-02 14:22:48 +02:00
School as SchoolIcon,
2023-10-16 09:20:40 +02:00
Search as SearchIcon,
2022-12-02 17:45:14 +01:00
} from "@mui/icons-material";
2023-06-26 10:07:12 +00:00
import { usePathname } from "next/navigation";
2022-12-02 10:55:56 +00:00
import Link from "next/link";
2022-12-14 13:24:50 +01:00
import Image from "next/image";
import LinkLogo from "public/link-logo-small.png";
2023-06-07 08:02:29 +00:00
import { useSession, signOut } from "next-auth/react";
2023-07-11 13:48:05 +00:00
import { getTicketOverviewCountsQuery } from "app/_graphql/getTicketOverviewCountsQuery";
2023-10-16 09:20:40 +02:00
import { SearchBox } from "./SearchBox";
2024-05-09 07:42:44 +02:00
import { fonts } from "ui";
2022-12-02 10:55:56 +00:00
2022-12-14 13:24:50 +01:00
const openWidth = 270;
2024-05-09 07:42:44 +02:00
const closedWidth = 70;
2022-12-14 13:24:50 +01:00
const MenuItem = ({
name,
href,
Icon,
iconSize,
inset = false,
selected = false,
2023-01-11 16:18:56 +01:00
open = true,
2022-12-14 13:24:50 +01:00
badge,
2024-05-09 07:42:44 +02:00
depth = 0,
2023-06-07 08:02:29 +00:00
target = "_self",
2024-03-20 17:51:21 +01:00
}: any) => {
const { roboto } = fonts;
2024-04-21 09:44:30 +02:00
return (
<Link href={href} target={target}>
<ListItemButton
sx={{
p: 0,
mb: 1,
bl: iconSize === 0 ? "1px solid white" : "inherit",
}}
selected={selected}
>
{iconSize > 0 ? (
<ListItemIcon
2022-12-14 13:24:50 +01:00
sx={{
2024-04-21 09:44:30 +02:00
color: `white`,
minWidth: 0,
mr: 2,
textAlign: "center",
margin: open ? "0 8 0 0" : "0 auto",
2022-12-14 13:24:50 +01:00
}}
>
2024-04-21 09:44:30 +02:00
<Box
sx={{
width: iconSize,
height: iconSize,
mr: 0.5,
mt: "-4px",
}}
>
<Icon />
</Box>
</ListItemIcon>
) : (
2022-12-14 13:24:50 +01:00
<Box
sx={{
2024-04-21 09:44:30 +02:00
width: 30,
height: "28px",
position: "relative",
2024-05-09 07:42:44 +02:00
ml: "8px",
mr: "2px",
2022-12-14 13:24:50 +01:00
}}
2024-04-21 09:44:30 +02:00
>
<Box
sx={{
width: "1px",
height: "56px",
backgroundColor: "white",
position: "absolute",
left: "3px",
top: "-10px",
}}
/>
<Box
sx={{
width: "42px",
height: "42px",
position: "absolute",
top: "-27px",
left: "3px",
border: "solid 1px #fff",
borderColor: "transparent transparent transparent #fff",
borderRadius: "60px",
2024-05-09 07:42:44 +02:00
rotate: "-50deg",
2024-04-21 09:44:30 +02:00
}}
/>
2024-05-09 07:42:44 +02:00
{depth > 0 && (
<Box
sx={{
width: depth * 22,
height: "1px",
backgroundColor: "white",
position: "absolute",
left: "26px",
top: "14px",
}}
/>
)}
2024-04-21 09:44:30 +02:00
</Box>
)}
{open && (
<ListItemText
inset={inset}
primary={
<Typography
variant="body1"
sx={{
fontSize: 16,
fontFamily: roboto.style.fontFamily,
fontWeight: "bold",
border: 0,
textAlign: "left",
color: "white",
2024-05-09 07:42:44 +02:00
ml: depth * 3,
2024-04-21 09:44:30 +02:00
}}
>
{name}
</Typography>
}
2022-12-14 13:24:50 +01:00
/>
2024-04-21 09:44:30 +02:00
)}
{badge && badge > 0 ? (
<ListItemSecondaryAction>
2023-01-11 16:18:56 +01:00
<Typography
2024-04-21 09:44:30 +02:00
color="textSecondary"
2023-01-11 16:18:56 +01:00
variant="body1"
2024-04-21 09:44:30 +02:00
className="badge"
2023-01-11 16:18:56 +01:00
sx={{
2024-04-21 09:44:30 +02:00
backgroundColor: "#FFB620",
color: "black !important",
borderRadius: 10,
px: 1,
fontSize: 12,
2023-01-11 16:18:56 +01:00
fontWeight: "bold",
}}
>
2024-04-21 09:44:30 +02:00
{badge}
2023-01-11 16:18:56 +01:00
</Typography>
2024-04-21 09:44:30 +02:00
</ListItemSecondaryAction>
) : null}
</ListItemButton>
</Link>
);
};
2022-12-02 10:55:56 +00:00
interface SidebarProps {
open: boolean;
2023-01-11 16:18:56 +01:00
setOpen: (open: boolean) => void;
2022-12-02 10:55:56 +00:00
}
2023-01-11 16:18:56 +01:00
export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
2023-06-26 10:07:12 +00:00
const pathname = usePathname();
2023-05-25 12:37:14 +00:00
const { data: session } = useSession();
2024-03-20 17:51:21 +01:00
const { poppins } = fonts;
2023-05-25 12:37:14 +00:00
const username = session?.user?.name || "User";
2023-08-25 07:11:33 +00:00
// @ts-ignore
const roles = session?.user?.roles || [];
2023-06-07 08:02:29 +00:00
const { data: overviewData, error: overviewError }: any = useSWR(
{
document: getTicketOverviewCountsQuery,
},
2023-07-21 12:26:02 +00:00
{ refreshInterval: 10000 },
2023-06-07 08:02:29 +00:00
);
const findOverviewByName = (name: string) =>
overviewData?.ticketOverviews?.edges?.find(
(overview: any) => overview.node.name === name,
)?.node?.id;
const findOverviewCountByID = (id: string) =>
overviewData?.ticketOverviews?.edges?.find(
(overview: any) => overview.node.id === id,
2023-06-07 08:02:29 +00:00
)?.node?.ticketCount ?? 0;
2023-10-16 09:20:40 +02:00
const recentCount = 0;
const assignedID = findOverviewByName("My Assigned Tickets");
const assignedCount = findOverviewCountByID(assignedID);
const openID = findOverviewByName("Open Tickets");
const openCount = findOverviewCountByID(openID);
const urgentID = findOverviewByName("Escalated Tickets");
const urgentCount = findOverviewCountByID(urgentID);
const unassignedID = findOverviewByName("Unassigned & Open Tickets");
const unassignedCount = findOverviewCountByID(unassignedID);
2023-06-07 08:02:29 +00:00
const logout = () => {
signOut({ callbackUrl: "/login" });
};
2023-01-11 16:18:56 +01:00
2022-12-14 13:24:50 +01:00
return (
<Drawer
sx={{ width: open ? openWidth : closedWidth, flexShrink: 0 }}
variant="permanent"
anchor="left"
open={open}
PaperProps={{
sx: {
width: open ? openWidth : closedWidth,
border: 0,
2023-01-11 16:18:56 +01:00
overflow: "visible",
2022-12-14 13:24:50 +01:00
},
}}
2022-12-02 10:55:56 +00:00
>
2023-01-11 16:18:56 +01:00
<Box
sx={{
position: "absolute",
2024-05-09 07:42:44 +02:00
top: 24,
2023-01-11 16:18:56 +01:00
right: open ? -8 : -16,
color: "#1C75FD",
rotate: open ? "90deg" : "-90deg",
}}
onClick={() => {
setOpen!(!open);
}}
>
<ExpandCircleDownIcon
sx={{
2024-05-09 07:42:44 +02:00
width: 24,
height: 24,
2023-01-11 16:18:56 +01:00
background: "white",
borderRadius: 500,
}}
/>
</Box>
2022-12-14 13:24:50 +01:00
<Grid
container
direction="column"
justifyContent="space-between"
wrap="nowrap"
2023-10-16 09:20:40 +02:00
spacing={0}
2022-12-14 13:24:50 +01:00
sx={{ backgroundColor: "#25272A", height: "100%", p: 2 }}
>
<Grid item container>
2023-01-11 16:18:56 +01:00
<Grid item sx={{ width: open ? "40px" : "100%" }}>
<Box
sx={{
width: "40px",
height: "40px",
margin: open ? "0" : "0 auto",
}}
>
2022-12-14 13:24:50 +01:00
<Image
src={LinkLogo}
alt="Link logo"
width={40}
height={40}
style={{
objectFit: "cover",
filter: "grayscale(100) brightness(100)",
}}
/>
</Box>
.
</Grid>
2023-01-11 16:18:56 +01:00
{open && (
<Grid item>
<Typography
variant="h2"
sx={{
fontSize: 26,
color: "white",
fontWeight: 700,
mt: 1,
ml: 0.5,
2024-03-20 17:51:21 +01:00
fontFamily: poppins.style.fontFamily,
2023-01-11 16:18:56 +01:00
}}
>
CDR Link
</Typography>
</Grid>
)}
2022-12-14 13:24:50 +01:00
</Grid>
<Grid item>
<Box
2022-12-02 17:45:14 +01:00
sx={{
2022-12-14 13:24:50 +01:00
height: "0.5px",
width: "100%",
backgroundColor: "#666",
mb: 1,
2022-12-02 17:45:14 +01:00
}}
/>
2022-12-14 13:24:50 +01:00
</Grid>
<Grid item>
<Typography
variant="h6"
2023-01-11 16:18:56 +01:00
sx={{
fontSize: 12,
color: "#999",
fontWeight: "bold",
textAlign: open ? "left" : "center",
}}
2022-12-14 13:24:50 +01:00
>
Hello
</Typography>
</Grid>
<Grid item>
<Typography
variant="h2"
2023-01-11 16:18:56 +01:00
sx={{
fontSize: 22,
color: "white",
mb: 1.5,
fontWeight: "bold",
textAlign: open ? "left" : "center",
}}
2022-12-14 13:24:50 +01:00
>
2023-01-11 16:18:56 +01:00
{open
? username
: username
2023-05-25 12:37:14 +00:00
.split(" ")
.map((name) => name.substring(0, 1))
.join("")}
2022-12-14 13:24:50 +01:00
</Typography>
</Grid>
<Grid item>
<Box
2023-10-16 09:20:40 +02:00
sx={{
height: "0.5px",
width: "100%",
backgroundColor: "#666",
mb: 2,
}}
2022-12-02 17:45:14 +01:00
/>
2022-12-14 13:24:50 +01:00
</Grid>
2024-05-09 07:42:44 +02:00
<Grid item>{open && <SearchBox />}</Grid>
2023-09-12 14:33:37 +02:00
<Grid
item
container
direction="column"
sx={{
mt: "6px",
overflow: "scroll",
scrollbarWidth: "none",
msOverflowStyle: "none",
"&::-webkit-scrollbar": { display: "none" },
}}
flexGrow={1}
>
2022-12-14 13:24:50 +01:00
<List
component="nav"
sx={{
a: {
textDecoration: "none",
".MuiListItemButton-root": {
p: 1,
borderRadius: 2,
"&:hover": {
background: "#555",
},
".MuiTypography-root": {
p: {
color: "#999 !important",
fontSize: 16,
},
},
".badge": {
p: { fontSize: 12, color: "black !important" },
},
},
".Mui-selected": {
background: "#444",
color: "#fff !important",
".MuiTypography-root": {
p: {
color: "#fff !important",
fontSize: 16,
},
},
".badge": {
p: { fontSize: 12, color: "black !important" },
},
},
},
}}
>
<MenuItem
name="Home"
href="/"
Icon={CottageIcon}
iconSize={20}
selected={pathname.endsWith("/")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="Tickets"
2023-10-16 09:20:40 +02:00
href="/overview/recent"
2022-12-14 13:24:50 +01:00
Icon={FeaturedPlayListIcon}
2023-06-26 10:07:12 +00:00
selected={
pathname.startsWith("/overview") ||
pathname.startsWith("/tickets")
}
2022-12-14 13:24:50 +01:00
iconSize={20}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<Collapse
2023-06-26 10:07:12 +00:00
in={
pathname.startsWith("/overview") ||
pathname.startsWith("/tickets")
}
2022-12-14 13:24:50 +01:00
timeout="auto"
unmountOnExit
onClick={undefined}
>
<List component="div" disablePadding>
<MenuItem
2023-10-16 09:20:40 +02:00
name="Recent"
href="/overview/recent"
2022-12-14 13:24:50 +01:00
Icon={FeaturedPlayListIcon}
iconSize={0}
2023-10-16 09:20:40 +02:00
selected={pathname.endsWith("/overview/recent")}
badge={recentCount}
open={open}
/>
<MenuItem
name="Open"
href="/overview/open"
Icon={FeaturedPlayListIcon}
iconSize={0}
selected={pathname.endsWith("/overview/open")}
badge={openCount}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="Urgent"
2023-06-26 10:07:12 +00:00
href="/overview/urgent"
2022-12-14 13:24:50 +01:00
Icon={FeaturedPlayListIcon}
iconSize={0}
2023-06-26 10:07:12 +00:00
selected={pathname.endsWith("/overview/urgent")}
2023-06-07 08:02:29 +00:00
badge={urgentCount}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
2023-10-16 09:20:40 +02:00
name="Assigned"
href="/overview/assigned"
2022-12-14 13:24:50 +01:00
Icon={FeaturedPlayListIcon}
iconSize={0}
2023-10-16 09:20:40 +02:00
selected={pathname.endsWith("/overview/assigned")}
badge={assignedCount}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="Unassigned"
2023-06-26 10:07:12 +00:00
href="/overview/unassigned"
2022-12-14 13:24:50 +01:00
Icon={FeaturedPlayListIcon}
iconSize={0}
2023-06-26 10:07:12 +00:00
selected={pathname.endsWith("/overview/unassigned")}
2023-06-07 08:02:29 +00:00
badge={unassignedCount}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
</List>
</Collapse>
2023-05-25 12:37:14 +00:00
<MenuItem
name="Knowledge Base"
href="/knowledge"
2023-10-02 14:22:48 +02:00
Icon={SchoolIcon}
2023-05-25 12:37:14 +00:00
iconSize={20}
selected={pathname.endsWith("/knowledge")}
open={open}
/>
2023-10-02 14:22:48 +02:00
<MenuItem
name="Documentation"
href="/docs"
Icon={LibraryBooksIcon}
iconSize={20}
selected={pathname.endsWith("/docs")}
open={open}
/>
2023-08-25 07:11:33 +00:00
<MenuItem
name="Reporting"
href="/reporting"
Icon={AssessmentIcon}
iconSize={20}
selected={pathname.endsWith("/reporting")}
open={open}
/>
2022-12-14 13:24:50 +01:00
<MenuItem
name="Leafcutter"
2023-07-21 12:26:02 +00:00
href="/leafcutter"
2023-08-25 07:11:33 +00:00
Icon={InsightsIcon}
2022-12-14 13:24:50 +01:00
iconSize={20}
2023-08-25 07:11:33 +00:00
selected={false}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<Collapse
in={pathname.startsWith("/leafcutter")}
timeout="auto"
unmountOnExit
onClick={undefined}
>
<List component="div" disablePadding>
<MenuItem
name="Dashboard"
href="/leafcutter"
iconSize={0}
selected={pathname.endsWith("/leafcutter")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="Search and Create"
href="/leafcutter/create"
iconSize={0}
selected={pathname.endsWith("/leafcutter/create")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="Trends"
href="/leafcutter/trends"
iconSize={0}
selected={pathname.endsWith("/leafcutter/trends")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="FAQ"
href="/leafcutter/faq"
iconSize={0}
selected={pathname.endsWith("/leafcutter/faq")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
<MenuItem
name="About"
href="/leafcutter/about"
2023-08-25 07:11:33 +00:00
Icon={InsightsIcon}
2022-12-14 13:24:50 +01:00
iconSize={0}
selected={pathname.endsWith("/leafcutter/about")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
</List>
</Collapse>
<MenuItem
name="Profile"
href="/profile"
Icon={PersonIcon}
iconSize={20}
selected={pathname.endsWith("/profile")}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
2023-08-25 07:11:33 +00:00
{roles.includes("admin") && (
<>
2022-12-14 13:24:50 +01:00
<MenuItem
2023-08-25 07:11:33 +00:00
name="Admin"
2024-05-09 07:42:44 +02:00
href="/admin/bridge"
2023-08-25 07:11:33 +00:00
Icon={SettingsIcon}
iconSize={20}
2023-01-11 16:18:56 +01:00
open={open}
2022-12-14 13:24:50 +01:00
/>
2023-08-25 07:11:33 +00:00
<Collapse
in={pathname.startsWith("/admin/")}
timeout="auto"
unmountOnExit
onClick={undefined}
>
<List component="div" disablePadding>
2024-05-09 07:42:44 +02:00
<MenuItem
name="CDR Bridge"
href="/admin/bridge"
selected={pathname.endsWith("/admin/bridge")}
open={open}
/>
<Collapse
in={pathname.startsWith("/admin/bridge")}
timeout="auto"
unmountOnExit
onClick={undefined}
>
<List component="div" disablePadding>
<MenuItem
name="WhatsApp"
href="/admin/bridge/whatsapp"
depth={1}
selected={pathname.endsWith("/admin/bridge/whatsapp")}
open={open}
/>
<MenuItem
name="Signal"
href="/admin/bridge/signal"
depth={1}
selected={pathname.endsWith("/admin/bridge/signal")}
open={open}
/>
<MenuItem
name="Facebook"
href="/admin/bridge/facebook"
depth={1}
selected={pathname.endsWith("/admin/bridge/facebook")}
open={open}
/>
<MenuItem
name="Voice"
href="/admin/bridge/voice"
depth={1}
selected={pathname.endsWith("/admin/bridge/voice")}
open={open}
/>
<MenuItem
name="Webhooks"
href="/admin/bridge/webhooks"
depth={1}
selected={pathname.endsWith("/admin/bridge/webhooks")}
open={open}
/>
</List>
</Collapse>
2023-08-25 07:11:33 +00:00
<MenuItem
name="Zammad Settings"
href="/admin/zammad"
Icon={FeaturedPlayListIcon}
iconSize={0}
selected={pathname.endsWith("/admin/zammad")}
open={open}
/>
{roles.includes("label_studio") && (
<MenuItem
name="Label Studio"
href="/admin/label-studio"
Icon={FeaturedPlayListIcon}
iconSize={0}
selected={pathname.endsWith("/admin/label-studio")}
open={open}
/>
)}
</List>
</Collapse>
</>
)}
2023-06-07 08:02:29 +00:00
<MenuItem
name="Zammad Interface"
2023-08-25 07:11:33 +00:00
href="/zammad"
2023-06-07 08:02:29 +00:00
Icon={DvrIcon}
iconSize={20}
open={open}
target="_blank"
/>
2022-12-14 13:24:50 +01:00
<MenuItem
name="Logout"
href="/logout"
Icon={LogoutIcon}
iconSize={20}
2023-01-11 16:18:56 +01:00
open={open}
2023-06-07 08:02:29 +00:00
onClick={logout}
2022-12-14 13:24:50 +01:00
/>
</List>
</Grid>
2022-12-02 10:55:56 +00:00
</Grid>
2022-12-14 13:24:50 +01:00
</Drawer>
);
};