Create session scheduling page
parent
9607c3f83f
commit
6b4b1aea55
|
|
@ -10,6 +10,7 @@ import { BuyReturn } from "./pages/buy/BuyReturn.tsx";
|
||||||
import { Grid, Paper } from "@mui/material";
|
import { Grid, Paper } from "@mui/material";
|
||||||
import { AuthenticatedRoute } from "./pages/auth/AuthenticatedRoute.tsx";
|
import { AuthenticatedRoute } from "./pages/auth/AuthenticatedRoute.tsx";
|
||||||
import { InvoicePage } from "./pages/invoice/InvoicePage.tsx";
|
import { InvoicePage } from "./pages/invoice/InvoicePage.tsx";
|
||||||
|
import { SchedulerPage } from "./pages/scheduling/SchedulerPage.tsx";
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<Paper
|
<Paper
|
||||||
|
|
@ -40,6 +41,7 @@ const App = () => (
|
||||||
<Route path="/buy" element={<Buy />} />
|
<Route path="/buy" element={<Buy />} />
|
||||||
<Route path="/buy/return" element={<BuyReturn />} />
|
<Route path="/buy/return" element={<BuyReturn />} />
|
||||||
<Route path="/summary" element={<InvoicePage />} />
|
<Route path="/summary" element={<InvoicePage />} />
|
||||||
|
<Route path="/schedule" element={<SchedulerPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
|
||||||
|
|
@ -106,3 +106,10 @@ export const getInvoicingSummary = () =>
|
||||||
AxiosResponse<InvoiceSummary>
|
AxiosResponse<InvoiceSummary>
|
||||||
>
|
>
|
||||||
).then((response) => response.data);
|
).then((response) => response.data);
|
||||||
|
|
||||||
|
export const openSession = (sessionId: string) =>
|
||||||
|
axios.post("/session/open", { sessionId }, getJwtHeader());
|
||||||
|
export const closeSession = (sessionId: string) =>
|
||||||
|
axios.post("/session/close", { sessionId }, getJwtHeader());
|
||||||
|
export const cancelSession = (sessionId: string) =>
|
||||||
|
axios.post("/session/cancel", { sessionId }, getJwtHeader());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Button } from "@mui/material";
|
||||||
|
import { cancelSession, type Session } from "../../api/client";
|
||||||
|
|
||||||
|
export const CancellingAction = (props: { session: Session }) => {
|
||||||
|
const { session } = props;
|
||||||
|
const { status, id } = session;
|
||||||
|
|
||||||
|
if (status === "CANCELLED" || status === "CLOSED") {
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
onClick={() => cancelSession(id)}
|
||||||
|
>
|
||||||
|
CANCEL
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
import {
|
||||||
|
Grid,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TablePagination,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { FormattedDate } from "react-intl";
|
||||||
|
import { getAllSessions, type Session } from "../../api/client";
|
||||||
|
import { Async } from "react-async";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { SchedulingAction } from "./SchedulingAction";
|
||||||
|
import { CancellingAction } from "./CancellingAction";
|
||||||
|
|
||||||
|
export const SchedulerPage = () => {
|
||||||
|
const sessionsPromise = getAllSessions();
|
||||||
|
const [page, setPage] = useState(0);
|
||||||
|
const rowsPerPage = 10;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Async promise={sessionsPromise}>
|
||||||
|
<Async.Fulfilled<Session[]>>
|
||||||
|
{(sessions) => (
|
||||||
|
<Grid container direction="column" spacing={2} alignItems="center">
|
||||||
|
<Typography variant="h3">All sessions</Typography>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell align="center" sx={{ fontWeight: "bold" }}>
|
||||||
|
Date
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" sx={{ fontWeight: "bold" }}>
|
||||||
|
Slots
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" sx={{ fontWeight: "bold" }}>
|
||||||
|
Status
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" sx={{ fontWeight: "bold" }}>
|
||||||
|
Scheduling
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" sx={{ fontWeight: "bold" }}>
|
||||||
|
Cancel
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{sessions
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((session) => (
|
||||||
|
<TableRow key={session.id}>
|
||||||
|
<TableCell align="center">
|
||||||
|
<FormattedDate
|
||||||
|
value={new Date(session.date)}
|
||||||
|
day="numeric"
|
||||||
|
month="short"
|
||||||
|
year="numeric"
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
{session.userCount}/{session.size}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center">{session.status}</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
<SchedulingAction session={session} />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
<CancellingAction session={session} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
component="div"
|
||||||
|
count={sessions.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={(_, newPage) => setPage(newPage)}
|
||||||
|
rowsPerPageOptions={[]}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
</Async.Fulfilled>
|
||||||
|
</Async>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { Button } from "@mui/material";
|
||||||
|
import { closeSession, openSession, type Session } from "../../api/client";
|
||||||
|
|
||||||
|
export const SchedulingAction = (props: { session: Session }) => {
|
||||||
|
const { session } = props;
|
||||||
|
const { status, id } = session;
|
||||||
|
|
||||||
|
if (status === "CANCELLED" || status === "CLOSED") {
|
||||||
|
return ("N/A");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === "SCHEDULED") {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
onClick={() => openSession(id)}
|
||||||
|
>
|
||||||
|
OPEN
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === "OPEN") {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
onClick={() => closeSession(id)}
|
||||||
|
>
|
||||||
|
CLOSE
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue