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 { 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<TicketDetailProps> = ({ 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<TicketDetailProps> = ({ id }) => {
<>
<MainContainer>
<ChatContainer>
<ConversationHeader>
{!mobile && (<ConversationHeader>
<ConversationHeader.Content>
<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.number} (created ${new Date(
ticket.createdAt,
).toLocaleDateString()})`}</Typography>
</Box>
<TicketHeader ticket={ticket} />
</ConversationHeader.Content>
</ConversationHeader>
</ConversationHeader>)}
<MessageList style={{ marginBottom: 80 }}>
{ticketArticles.edges.map(({ node: article }: any) => (
<Message

View file

@ -110,7 +110,7 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
const shouldRender = !!ticket;
return (
<Box sx={{ height: "100vh", background: "#ddd", p: 2 }}>
<Box sx={{ background: "#ddd", p: 2 }}>
{shouldRender && (
<Grid container direction="column" spacing={3}>
<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";
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 (
<Grid container spacing={0} sx={{ height: "100%" }} direction="row">
<Grid item sx={{ height: "100%" }} xs={9}>
<Grid container spacing={0} sx={{ height: "100%" }} direction="row" wrap="wrap">
<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}
</Grid>
<Grid item xs={3} sx={{ height: "100%" }}>
<Grid item xs={12} md={3} sx={{ height: {xs: "auto", md: "100%"}, order: 2 }}>
{edit}
</Grid>
</Grid>