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.
This commit is contained in:
N-Pex 2024-09-12 15:45:20 +02:00
parent 047ef094fc
commit 6440c402cf
5 changed files with 107 additions and 34 deletions

View file

@ -2,7 +2,7 @@
import { FC, useState, useEffect } from "react"; import { FC, useState, useEffect } from "react";
import { getTicketAction, getTicketArticlesAction } from "app/_actions/tickets"; 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 { Button, fonts, colors } from "@link-stack/ui";
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css"; import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import { import {
@ -13,6 +13,7 @@ import {
ConversationHeader, ConversationHeader,
} from "@chatscope/chat-ui-kit-react"; } from "@chatscope/chat-ui-kit-react";
import { ArticleCreateDialog } from "./ArticleCreateDialog"; import { ArticleCreateDialog } from "./ArticleCreateDialog";
import { TicketHeader } from "../../_components/TicketHeader";
interface TicketDetailProps { interface TicketDetailProps {
id: string; id: string;
@ -26,6 +27,9 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
const [dialogOpen, setDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false);
const [articleKind, setArticleKind] = useState("note"); const [articleKind, setArticleKind] = useState("note");
const theme = useTheme();
const mobile = useMediaQuery(theme.breakpoints.down("md"));
useEffect(() => { useEffect(() => {
const fetchTicket = async () => { const fetchTicket = async () => {
const result = await getTicketAction(id); const result = await getTicketAction(id);
@ -66,36 +70,11 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
<> <>
<MainContainer> <MainContainer>
<ChatContainer> <ChatContainer>
<ConversationHeader> {!mobile && (<ConversationHeader>
<ConversationHeader.Content> <ConversationHeader.Content>
<Box <TicketHeader ticket={ticket} />
sx={{
width: "100%",
textAlign: "center",
fontWeight: "bold",
}}
>
<Typography
variant="h5"
sx={{
fontFamily: poppins.style.fontFamily,
fontWeight: 700,
}}
>
{ticket.title}
</Typography>
<Typography
variant="h6"
sx={{
fontFamily: roboto.style.fontFamily,
fontWeight: 400,
}}
>{`Ticket #${ticket.number} (created ${new Date(
ticket.createdAt,
).toLocaleDateString()})`}</Typography>
</Box>
</ConversationHeader.Content> </ConversationHeader.Content>
</ConversationHeader> </ConversationHeader>)}
<MessageList style={{ marginBottom: 80 }}> <MessageList style={{ marginBottom: 80 }}>
{ticketArticles.edges.map(({ node: article }: any) => ( {ticketArticles.edges.map(({ node: article }: any) => (
<Message <Message

View file

@ -110,7 +110,7 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
const shouldRender = !!ticket; const shouldRender = !!ticket;
return ( return (
<Box sx={{ height: "100vh", background: "#ddd", p: 2 }}> <Box sx={{ background: "#ddd", p: 2 }}>
{shouldRender && ( {shouldRender && (
<Grid container direction="column" spacing={3}> <Grid container direction="column" spacing={3}>
<Grid item> <Grid item>

View file

@ -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 (<TicketHeader id={id} />);
}

View file

@ -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<ConversationHeaderProps & TicketHeaderProps> = (
props,
) => {
const { poppins, roboto } = fonts;
const [ticket, setTicket] = useState<any>(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 (
<>
<Box
sx={{
width: "100%",
textAlign: "center",
fontWeight: "bold",
}}
>
<Typography
variant="h5"
sx={{
fontFamily: poppins.style.fontFamily,
fontWeight: 700,
}}
>
{ticket?.title}
</Typography>
<Typography
variant="h6"
sx={{
fontFamily: roboto.style.fontFamily,
fontWeight: 400,
}}
>
{ticket
? `Ticket #${ticket.number} (created ${new Date(
ticket.createdAt,
).toLocaleDateString()})`
: ""}
</Typography>
</Box>
</>
);
};

View file

@ -1,22 +1,31 @@
"use client"; "use client";
import { ConversationHeader } from "@chatscope/chat-ui-kit-react";
import { Grid } from "@mui/material"; import { Grid } from "@mui/material";
type LayoutProps = { type LayoutProps = {
detail: any; detail: any;
edit: any; edit: any;
header: any;
params: { params: {
id: string; id: string;
}; };
}; };
export default function Layout({ detail, edit, params: { id } }: LayoutProps) { export default function Layout({ detail, edit, header, params: { id } }: LayoutProps) {
return ( return (
<Grid container spacing={0} sx={{ height: "100%" }} direction="row"> <Grid container spacing={0} sx={{ height: "100%" }} direction="row" wrap="wrap">
<Grid item sx={{ height: "100%" }} xs={9}> <Grid item sx={{ order: 0, display: { xs: "block", md: "none" } }} xs={12}>
<ConversationHeader>
<ConversationHeader.Content>
{header}
</ConversationHeader.Content>
</ConversationHeader>
</Grid>
<Grid item sx={{ height: {xs: "auto", md: "100%"}, order: {xs: 3, md: 1} }} xs={12} md={9}>
{detail} {detail}
</Grid> </Grid>
<Grid item xs={3} sx={{ height: "100%" }}> <Grid item xs={12} md={3} sx={{ height: {xs: "auto", md: "100%"}, order: 2 }}>
{edit} {edit}
</Grid> </Grid>
</Grid> </Grid>