Implement join/leave session and simplify UI
parent
703408fc12
commit
f96d20eaf2
|
|
@ -38,3 +38,17 @@ export const getAllSessions = (userId: string) =>
|
||||||
(
|
(
|
||||||
axios.get(`/session?userId=${userId}`) as Promise<AxiosResponse<Session[]>>
|
axios.get(`/session?userId=${userId}`) as Promise<AxiosResponse<Session[]>>
|
||||||
).then((response) => response.data);
|
).then((response) => response.data);
|
||||||
|
|
||||||
|
export const joinSession = (userId: string, sessionId: string) =>
|
||||||
|
(
|
||||||
|
axios.post("/session/join", { userId, sessionId }) as Promise<
|
||||||
|
AxiosResponse<Session[]>
|
||||||
|
>
|
||||||
|
).then((response) => response.data);
|
||||||
|
|
||||||
|
export const leaveSession = (userId: string, sessionId: string) =>
|
||||||
|
(
|
||||||
|
axios.post("/session/leave", { userId, sessionId }) as Promise<
|
||||||
|
AxiosResponse<Session[]>
|
||||||
|
>
|
||||||
|
).then((response) => response.data);
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,33 @@
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
Button,
|
Button,
|
||||||
FormControlLabel,
|
|
||||||
Grid,
|
Grid,
|
||||||
Paper,
|
Paper,
|
||||||
Radio,
|
Table,
|
||||||
RadioGroup,
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { useContext, useMemo, useState } from "react";
|
import { useContext, useMemo } from "react";
|
||||||
import { FormattedDate } from "react-intl";
|
import { FormattedDate } from "react-intl";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { Async } from "react-async";
|
import { Async } from "react-async";
|
||||||
import { getAllSessions, type Session } from "../api/client";
|
import {
|
||||||
|
getAllSessions,
|
||||||
|
joinSession,
|
||||||
|
leaveSession,
|
||||||
|
type Session,
|
||||||
|
} from "../api/client";
|
||||||
import { LoggedInPageContext } from "../context/logged-in-page-context";
|
import { LoggedInPageContext } from "../context/logged-in-page-context";
|
||||||
|
|
||||||
export const SignUp = () => {
|
export const SignUp = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { userId } = useContext(LoggedInPageContext)!;
|
const { userId } = useContext(LoggedInPageContext)!;
|
||||||
const sessionsPromise = useMemo(() => getAllSessions(userId), [])
|
const sessionsPromise = useMemo(() => getAllSessions(userId), []);
|
||||||
const [selectedSession, setSelectedSession] = useState<Session | null>(null);
|
|
||||||
|
|
||||||
const setSelectedSessionFromId = (sessions: Session[], id: string) => setSelectedSession(
|
|
||||||
sessions.find(s => s.id === id) || null);
|
|
||||||
|
|
||||||
const selectedSessionId = selectedSession && selectedSession.id;
|
|
||||||
const selectedDate = selectedSession && new Date(selectedSession.date);
|
|
||||||
const availableSlots = selectedSession && selectedSession?.size - selectedSession.userCount;
|
|
||||||
const availableTokens: number = 0;
|
const availableTokens: number = 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -47,32 +48,63 @@ export const SignUp = () => {
|
||||||
sessions.length === 0 ? (
|
sessions.length === 0 ? (
|
||||||
<Alert severity="warning">No sessions are available</Alert>
|
<Alert severity="warning">No sessions are available</Alert>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<TableContainer component={Paper}>
|
||||||
<RadioGroup
|
<Table>
|
||||||
value={selectedSessionId}
|
<TableHead>
|
||||||
onChange={(e) => setSelectedSessionFromId(sessions, e.target.value)}
|
<TableRow>
|
||||||
>
|
<TableCell>Date</TableCell>
|
||||||
{sessions.map((session) => {
|
<TableCell>Slots</TableCell>
|
||||||
const date = new Date(session.date);
|
<TableCell>Sign-in/out</TableCell>
|
||||||
return (
|
</TableRow>
|
||||||
<FormControlLabel
|
</TableHead>
|
||||||
key={session.id}
|
<TableBody>
|
||||||
value={session.id}
|
{sessions.map((session) => (
|
||||||
control={<Radio />}
|
<TableRow key={session.id}>
|
||||||
label={
|
<TableCell>
|
||||||
<FormattedDate
|
<FormattedDate
|
||||||
value={date}
|
value={new Date(session.date)}
|
||||||
day="numeric"
|
day="numeric"
|
||||||
month="long"
|
month="short"
|
||||||
year="numeric"
|
year="numeric"
|
||||||
/>
|
/>
|
||||||
}
|
</TableCell>
|
||||||
/>
|
<TableCell>
|
||||||
);
|
{session.userCount}/{session.size}
|
||||||
})}
|
</TableCell>
|
||||||
</RadioGroup>
|
<TableCell>
|
||||||
<Button></Button>
|
{session.includesRequester ? (
|
||||||
</>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
onClick={async () => {
|
||||||
|
await leaveSession(userId, session.id);
|
||||||
|
window.location.reload();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign out
|
||||||
|
</Button>
|
||||||
|
) : session.userCount >= session.size ? (
|
||||||
|
"UNAVAILABLE"
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
onClick={async () => {
|
||||||
|
await joinSession(userId, session.id);
|
||||||
|
window.location.reload();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign in
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Async.Fulfilled>
|
</Async.Fulfilled>
|
||||||
|
|
@ -81,44 +113,6 @@ export const SignUp = () => {
|
||||||
</Async.Rejected>
|
</Async.Rejected>
|
||||||
</Async>
|
</Async>
|
||||||
</Paper>
|
</Paper>
|
||||||
{selectedDate && (
|
|
||||||
<Paper
|
|
||||||
variant="outlined"
|
|
||||||
sx={{
|
|
||||||
p: 3,
|
|
||||||
bgcolor: "aliceblue",
|
|
||||||
borderRadius: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography variant="h5">
|
|
||||||
<FormattedDate
|
|
||||||
value={selectedDate}
|
|
||||||
day="numeric"
|
|
||||||
month="long"
|
|
||||||
year="numeric"
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
{!availableSlots ? (
|
|
||||||
<Typography variant="subtitle1">
|
|
||||||
There are no available slots for this date.
|
|
||||||
</Typography>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Typography variant="subtitle1">
|
|
||||||
There are {availableSlots} available slots for this date.
|
|
||||||
</Typography>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
sx={{ width: "100%" }}
|
|
||||||
disabled={!availableTokens}
|
|
||||||
>
|
|
||||||
Sign up
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Paper>
|
|
||||||
)}
|
|
||||||
{!availableTokens && (
|
{!availableTokens && (
|
||||||
<Paper
|
<Paper
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue