From 6f3759d48d1b9c263c662f7e366d4c72541f4609 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Wed, 2 Sep 2026 17:30:43 +0200 Subject: [PATCH] feat: add confirmation modal when deleting a storage --- frontend/src/components/StorageRow.tsx | 164 ++++++++++-------- .../components/modals/DeleteConfirmation.tsx | 54 ++++++ frontend/src/utils/i18n/locales/de/de.json | 4 +- frontend/src/utils/i18n/locales/en/en.json | 4 +- 4 files changed, 151 insertions(+), 75 deletions(-) create mode 100644 frontend/src/components/modals/DeleteConfirmation.tsx diff --git a/frontend/src/components/StorageRow.tsx b/frontend/src/components/StorageRow.tsx index 473f38f..10d248b 100644 --- a/frontend/src/components/StorageRow.tsx +++ b/frontend/src/components/StorageRow.tsx @@ -8,6 +8,8 @@ import type { Storage } from "../misc/interfaces"; import { formatDate } from "../utils/uxFncs"; import { Mono } from "./Mono.tsx"; import { useTranslation } from "react-i18next"; +import { useState } from "react"; +import { DeleteConfirmation } from "./modals/DeleteConfirmation.tsx"; interface StorageRowProps { storage: Storage; @@ -17,6 +19,9 @@ interface StorageRowProps { export const StorageRow = ({ storage, onError }: StorageRowProps) => { const { t } = useTranslation(); + const [showModal, setShowModal] = useState(false); + const [storageToDelete, setStorageToDelete] = useState(null); + const queryClient = useQueryClient(); const mutation = useMutation({ @@ -28,6 +33,11 @@ export const StorageRow = ({ storage, onError }: StorageRowProps) => { onError, }); + const deleteStorageModalFnc = async (storage: Storage) => { + setStorageToDelete(storage); + setShowModal(true); + }; + const deleteMutation = useMutation({ mutationFn: (uuid: string) => deleteStorage(uuid), onSuccess: () => { @@ -52,82 +62,90 @@ export const StorageRow = ({ storage, onError }: StorageRowProps) => { (values.description ?? "") !== (storage.description ?? ""); return ( - - - - {(field) => ( - field.handleChange(e.target.value)} - onBlur={field.handleBlur} - size="sm" - variant="outlined" - className="rounded-xl shadow-none" - sx={{ - bgcolor: "var(--joy-palette-background-level1)", - color: "var(--joy-palette-text-secondary)", - "--Input-focusedHighlight": "var(--joy-palette-neutral-300)", - }} - /> - )} - - - - - {(field) => ( - field.handleChange(e.target.value)} - onBlur={field.handleBlur} - size="sm" - variant="outlined" - className="rounded-xl shadow-none" - sx={{ - bgcolor: "var(--joy-palette-background-level1)", - color: "var(--joy-palette-text-secondary)", - "--Input-focusedHighlight": "var(--joy-palette-neutral-300)", - }} - /> - )} - - - - {formatDate(storage.created_at)} - - - {formatDate(storage.updated_at)} - - -
- {isDirty && ( - + )} + deleteStorageModalFnc(storage)} disabled={mutation.isPending || deleteMutation.isPending} size="sm" className="rounded-xl" > - {mutation.isPending ? "..." : t("save")} - - )} - deleteMutation.mutateAsync(storage.uuid)} - disabled={mutation.isPending || deleteMutation.isPending} - size="sm" - className="rounded-xl" - > - - -
- - + + + + + + ); }; diff --git a/frontend/src/components/modals/DeleteConfirmation.tsx b/frontend/src/components/modals/DeleteConfirmation.tsx new file mode 100644 index 0000000..20e4d17 --- /dev/null +++ b/frontend/src/components/modals/DeleteConfirmation.tsx @@ -0,0 +1,54 @@ +import Button from "@mui/joy/Button"; +import Divider from "@mui/joy/Divider"; +import DialogTitle from "@mui/joy/DialogTitle"; +import DialogContent from "@mui/joy/DialogContent"; +import DialogActions from "@mui/joy/DialogActions"; +import Modal from "@mui/joy/Modal"; +import ModalDialog from "@mui/joy/ModalDialog"; +import type { Storage } from "../../misc/interfaces"; +import { useTranslation } from "react-i18next"; + +interface DeleteConfirmationProps { + open: boolean; + setOpen: (open: boolean) => void; + storage: Storage | null; + deleteStorageByUUID: (uuid: string) => void; +} + +export const DeleteConfirmation = (props: DeleteConfirmationProps) => { + const { t } = useTranslation(); + + return ( + props.setOpen(false)}> + + Confirmation + + + {t("delete-confirmation-text")} + {props.storage ? ` "${props.storage.name}"` : ""}? + + + + + + + + ); +}; diff --git a/frontend/src/utils/i18n/locales/de/de.json b/frontend/src/utils/i18n/locales/de/de.json index 76abdff..13a301d 100644 --- a/frontend/src/utils/i18n/locales/de/de.json +++ b/frontend/src/utils/i18n/locales/de/de.json @@ -129,5 +129,7 @@ "filter-soon": "Bald", "filter-low": "Niedrig", "products": "Produkte", - "units": "Einheiten" + "units": "Einheiten", + "cancel": "Abbrechen", + "delete-confirmation-text": "Bist du dir sicher das du diesen Storage löschen willst: " } diff --git a/frontend/src/utils/i18n/locales/en/en.json b/frontend/src/utils/i18n/locales/en/en.json index 8327d6f..63d61b6 100644 --- a/frontend/src/utils/i18n/locales/en/en.json +++ b/frontend/src/utils/i18n/locales/en/en.json @@ -129,5 +129,7 @@ "filter-soon": "Soon", "filter-low": "Low", "products": "products", - "units": "units" + "units": "units", + "cancel": "Cancel", + "delete-confirmation-text": "Are you sure you want to delete this storage: " }