From 6440c402cf8b1f0d1330c1bd3bdacf2d17372465 Mon Sep 17 00:00:00 2001 From: N-Pex Date: Thu, 12 Sep 2024 15:45:20 +0200 Subject: [PATCH] Mobile friendly version of ticket view Refactor the header into own component, so it can be shown at "page top" for the mobile one column view. --- .../[id]/@detail/_components/TicketDetail.tsx | 37 ++-------- .../[id]/@edit/_components/TicketEdit.tsx | 2 +- .../app/(main)/tickets/[id]/@header/page.tsx | 12 +++ .../tickets/[id]/_components/TicketHeader.tsx | 73 +++++++++++++++++++ apps/link/app/(main)/tickets/[id]/layout.tsx | 17 ++++- 5 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 apps/link/app/(main)/tickets/[id]/@header/page.tsx create mode 100644 apps/link/app/(main)/tickets/[id]/_components/TicketHeader.tsx diff --git a/apps/link/app/(main)/tickets/[id]/@detail/_components/TicketDetail.tsx b/apps/link/app/(main)/tickets/[id]/@detail/_components/TicketDetail.tsx index d24d34a..86b8aab 100644 --- a/apps/link/app/(main)/tickets/[id]/@detail/_components/TicketDetail.tsx +++ b/apps/link/app/(main)/tickets/[id]/@detail/_components/TicketDetail.tsx @@ -2,7 +2,7 @@ import { FC, useState, useEffect } from "react"; import { getTicketAction, getTicketArticlesAction } from "app/_actions/tickets"; -import { Grid, Box, Typography } from "@mui/material"; +import { Grid, Box, Typography, useTheme, useMediaQuery } from "@mui/material"; import { Button, fonts, colors } from "@link-stack/ui"; import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css"; import { @@ -13,6 +13,7 @@ import { ConversationHeader, } from "@chatscope/chat-ui-kit-react"; import { ArticleCreateDialog } from "./ArticleCreateDialog"; +import { TicketHeader } from "../../_components/TicketHeader"; interface TicketDetailProps { id: string; @@ -26,6 +27,9 @@ export const TicketDetail: FC = ({ id }) => { const [dialogOpen, setDialogOpen] = useState(false); const [articleKind, setArticleKind] = useState("note"); + const theme = useTheme(); + const mobile = useMediaQuery(theme.breakpoints.down("md")); + useEffect(() => { const fetchTicket = async () => { const result = await getTicketAction(id); @@ -66,36 +70,11 @@ export const TicketDetail: FC = ({ id }) => { <> - + {!mobile && ( - - - {ticket.title} - - {`Ticket #${ticket.number} (created ${new Date( - ticket.createdAt, - ).toLocaleDateString()})`} - + - + )} {ticketArticles.edges.map(({ node: article }: any) => ( = ({ id }) => { const shouldRender = !!ticket; return ( - + {shouldRender && ( diff --git a/apps/link/app/(main)/tickets/[id]/@header/page.tsx b/apps/link/app/(main)/tickets/[id]/@header/page.tsx new file mode 100644 index 0000000..78f8710 --- /dev/null +++ b/apps/link/app/(main)/tickets/[id]/@header/page.tsx @@ -0,0 +1,12 @@ +import { getTicketAction } from "@/app/_actions/tickets"; +import { TicketHeader } from "../_components/TicketHeader"; + +type PageProps = { + params: { + id: string; + }; +}; + +export default function Page({ params: { id } }: PageProps) { + return (); +} diff --git a/apps/link/app/(main)/tickets/[id]/_components/TicketHeader.tsx b/apps/link/app/(main)/tickets/[id]/_components/TicketHeader.tsx new file mode 100644 index 0000000..0f4831e --- /dev/null +++ b/apps/link/app/(main)/tickets/[id]/_components/TicketHeader.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { FC, useState, useEffect } from "react"; +import { Box, Typography } from "@mui/material"; +import { fonts } from "@link-stack/ui"; +import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css"; +import { + ConversationHeader, + ConversationHeaderProps, +} from "@chatscope/chat-ui-kit-react"; +import { getTicketAction } from "@/app/_actions/tickets"; + +interface TicketHeaderProps { + id?: string; + ticket?: any; +} + +export const TicketHeader: FC = ( + props, +) => { + const { poppins, roboto } = fonts; + + const [ticket, setTicket] = useState(props.ticket || null); + + useEffect(() => { + if (!ticket) { + const fetchTicket = async () => { + const result = await getTicketAction(props.id); + setTicket(result); + }; + + fetchTicket(); + + const interval = setInterval(fetchTicket, 20000); + return () => clearInterval(interval); + } + }, [props.id]); + + return ( + <> + + + {ticket?.title} + + + {ticket + ? `Ticket #${ticket.number} (created ${new Date( + ticket.createdAt, + ).toLocaleDateString()})` + : ""} + + + + ); +}; diff --git a/apps/link/app/(main)/tickets/[id]/layout.tsx b/apps/link/app/(main)/tickets/[id]/layout.tsx index d3ba633..9f475c9 100644 --- a/apps/link/app/(main)/tickets/[id]/layout.tsx +++ b/apps/link/app/(main)/tickets/[id]/layout.tsx @@ -1,22 +1,31 @@ "use client"; +import { ConversationHeader } from "@chatscope/chat-ui-kit-react"; import { Grid } from "@mui/material"; type LayoutProps = { detail: any; edit: any; + header: any; params: { id: string; }; }; -export default function Layout({ detail, edit, params: { id } }: LayoutProps) { +export default function Layout({ detail, edit, header, params: { id } }: LayoutProps) { return ( - - + + + + + {header} + + + + {detail} - + {edit}