chore: delete confirmation

This commit is contained in:
redglow
2026-06-21 14:17:03 +02:00
parent dc576d6b19
commit fb79565e27
2 changed files with 103 additions and 26 deletions
+19
View File
@@ -0,0 +1,19 @@
import { useCallback, useState } from "react";
export interface UsetBooleanResultOperators {
setTrue(): void;
setFalse(): void;
toggle(): void;
}
export type UseBooleanResult = [boolean, UsetBooleanResultOperators];
export function useBoolean(initialValue: boolean = false): UseBooleanResult {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue((x) => !x), []);
const setTrue = useCallback(() => setValue(true), []);
const setFalse = useCallback(() => setValue(false), []);
return [value, { setTrue, setFalse, toggle }];
}
+60 -2
View File
@@ -1,7 +1,15 @@
import DeleteIcon from "@mui/icons-material/Delete";
import { import {
Alert, Alert,
Box, Box,
Button,
CircularProgress, CircularProgress,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
IconButton,
Table, Table,
TableBody, TableBody,
TableCell, TableCell,
@@ -12,9 +20,10 @@ import {
} from "@mui/material"; } from "@mui/material";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { useEffect } from "react"; import { useCallback, useEffect, useState } from "react";
import z from "zod"; import z from "zod";
import { RouterButton } from "../components/RouterButton"; import { RouterButton } from "../components/RouterButton";
import { useBoolean } from "../components/use-boolean";
const Announcements = z.array( const Announcements = z.array(
z.object({ z.object({
@@ -26,6 +35,8 @@ const Announcements = z.array(
}), }),
); );
type Announcement = z.infer<typeof Announcements>[0];
export const Route = createFileRoute("/")({ export const Route = createFileRoute("/")({
component: RouteComponent, component: RouteComponent,
}); });
@@ -51,6 +62,27 @@ function RouteComponent() {
} }
}, [announcementsQuery.error]); }, [announcementsQuery.error]);
// delete confirmation dialog status
const [
isDeleteConfirmationOpen,
{
setTrue: openDeleteConfirmationDialog,
setFalse: closeDeleteConfirmation,
},
] = useBoolean();
const [
announcementForLatestDeleteAttempt,
setAnnouncementForLatestDeleteAttempt,
] = useState<Announcement | undefined>(undefined);
const openDeleteConfirmation = useCallback(
(a: Announcement) => {
openDeleteConfirmationDialog();
setAnnouncementForLatestDeleteAttempt(a);
},
[openDeleteConfirmationDialog],
);
// handle loading / error / show values // handle loading / error / show values
return ( return (
<Box sx={{ flexDirection: "column", display: "flex", gap: "3em" }}> <Box sx={{ flexDirection: "column", display: "flex", gap: "3em" }}>
@@ -67,7 +99,7 @@ function RouteComponent() {
) : announcementsQuery.status === "error" ? ( ) : announcementsQuery.status === "error" ? (
<Alert severity="error">Error (see console)</Alert> <Alert severity="error">Error (see console)</Alert>
) : ( ) : (
// <pre>{JSON.stringify(announcementsQuery.data, null, 2)}</pre> <>
<TableContainer> <TableContainer>
<Table> <Table>
<TableHead> <TableHead>
@@ -76,6 +108,7 @@ function RouteComponent() {
<TableCell>Title</TableCell> <TableCell>Title</TableCell>
<TableCell>Text</TableCell> <TableCell>Text</TableCell>
<TableCell>Publication Date</TableCell> <TableCell>Publication Date</TableCell>
<TableCell />
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@@ -88,11 +121,36 @@ function RouteComponent() {
(a.text.length > 50 ? "..." : "")} (a.text.length > 50 ? "..." : "")}
</TableCell> </TableCell>
<TableCell>{a.publication_date.toString()}</TableCell> <TableCell>{a.publication_date.toString()}</TableCell>
<TableCell>
<IconButton onClick={() => openDeleteConfirmation(a)}>
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>
<Dialog
open={isDeleteConfirmationOpen}
onClose={closeDeleteConfirmation}
role="alertdialog"
>
<DialogTitle>Delete announcement</DialogTitle>
<DialogContent>
<DialogContentText>
Do you want to delete the announcement{" "}
<strong>{announcementForLatestDeleteAttempt?.title}</strong>?
</DialogContentText>
<DialogActions>
<Button onClick={closeDeleteConfirmation} autoFocus>
No
</Button>
<Button onClick={closeDeleteConfirmation}>Yes</Button>
</DialogActions>
</DialogContent>
</Dialog>
</>
)} )}
</Box> </Box>
); );