diff --git a/api/Database/klapi.db b/api/Database/klapi.db
index 322d07f..167565f 100644
Binary files a/api/Database/klapi.db and b/api/Database/klapi.db differ
diff --git a/ui/src/components/ConfirmDialog.tsx b/ui/src/components/ConfirmDialog.tsx
new file mode 100644
index 0000000..1bba917
--- /dev/null
+++ b/ui/src/components/ConfirmDialog.tsx
@@ -0,0 +1,83 @@
+import { useEffect } from "react";
+
+type ConfirmDialogProps = {
+ open: boolean;
+ title: string;
+ description?: string;
+ contextText?: string;
+ confirmLabel: string;
+ cancelLabel: string;
+ busy?: boolean;
+ busyLabel?: string;
+ onConfirm: () => void;
+ onCancel: () => void;
+};
+
+export default function ConfirmDialog({
+ open,
+ title,
+ description,
+ contextText,
+ confirmLabel,
+ cancelLabel,
+ busy = false,
+ busyLabel,
+ onConfirm,
+ onCancel,
+}: ConfirmDialogProps) {
+ useEffect(() => {
+ if (!open) return;
+
+ const onKeyDown = (event: KeyboardEvent) => {
+ if (event.key === "Escape" && !busy) {
+ onCancel();
+ }
+ };
+
+ window.addEventListener("keydown", onKeyDown);
+ return () => {
+ window.removeEventListener("keydown", onKeyDown);
+ };
+ }, [open, busy, onCancel]);
+
+ if (!open) return null;
+
+ return (
+
{
+ if (!busy) onCancel();
+ }}
+ >
+
event.stopPropagation()}
+ >
+
{title}
+ {description &&
{description}
}
+ {contextText &&
{contextText}
}
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/ui/src/components/OpenHoursForm.tsx b/ui/src/components/OpenHoursForm.tsx
index 16dc9b2..fc4ff43 100644
--- a/ui/src/components/OpenHoursForm.tsx
+++ b/ui/src/components/OpenHoursForm.tsx
@@ -8,6 +8,7 @@ import {
updateLokOpenHours,
type LokOpenHours,
} from "~/api";
+import ConfirmDialog from "~/components/ConfirmDialog";
import { useT } from "~/i18n";
import { openHoursAtom, toastsAtom, type Toast } from "~/state/appState";
@@ -38,6 +39,7 @@ export default function OpenHoursForm() {
const [isEditing, setIsEditing] = useState(false);
const [editingVersionId, setEditingVersionId] = useState("");
const [deletingId, setDeletingId] = useState("");
+ const [confirmDeleteVersion, setConfirmDeleteVersion] = useState(null);
const [activatingId, setActivatingId] = useState("");
const [saving, setSaving] = useState(false);
const [form, setForm] = useState(EMPTY_FORM);
@@ -217,6 +219,21 @@ export default function OpenHoursForm() {
}
};
+ const askDeleteConfirmation = (version: LokOpenHours) => {
+ setConfirmDeleteVersion(version);
+ };
+
+ const cancelDeleteConfirmation = () => {
+ if (deletingId) return;
+ setConfirmDeleteVersion(null);
+ };
+
+ const confirmDelete = async () => {
+ if (!confirmDeleteVersion) return;
+ await onDelete(confirmDeleteVersion);
+ setConfirmDeleteVersion(null);
+ };
+
const onSetActive = async (version: LokOpenHours) => {
if (version.isActive) return;
@@ -328,7 +345,7 @@ export default function OpenHoursForm() {
disabled={active || deleting}
onClick={(event) => {
event.stopPropagation();
- void onDelete(version);
+ askDeleteConfirmation(version);
}}
className={`rounded-md border border-[#8E4F24] bg-[#EED5B8] px-3 py-1.5 text-sm text-[#70421E] disabled:cursor-not-allowed disabled:opacity-50 ${!active ? "hover:bg-[#E3A977]" : ""
}`}
@@ -416,6 +433,21 @@ export default function OpenHoursForm() {
+
+ {
+ void confirmDelete();
+ }}
+ />
);
}
diff --git a/ui/src/i18n.ts b/ui/src/i18n.ts
index a721bb9..8332e8a 100644
--- a/ui/src/i18n.ts
+++ b/ui/src/i18n.ts
@@ -44,6 +44,10 @@ const translations = {
"home.openHours.saved": "New version saved",
"home.openHours.updated": "Version updated",
"home.openHours.deleted": "Version deleted",
+ "home.openHours.deleting": "Deleting...",
+ "home.openHours.deleteConfirmTitle": "Delete version?",
+ "home.openHours.deleteConfirmMessage": "This action cannot be undone.",
+ "home.openHours.deleteConfirmAction": "Delete version",
"about.title": "About",
"about.description":
"Livonsaaren Tietokonepaja is a local project providing IT services for our dear archipelago.",
@@ -125,6 +129,10 @@ const translations = {
"home.openHours.saved": "Uusi versio tallennettu",
"home.openHours.updated": "Versio päivitetty",
"home.openHours.deleted": "Versio poistettu",
+ "home.openHours.deleting": "Poistetaan...",
+ "home.openHours.deleteConfirmTitle": "Poistetaanko versio?",
+ "home.openHours.deleteConfirmMessage": "Tätä toimintoa ei voi perua.",
+ "home.openHours.deleteConfirmAction": "Poista versio",
"about.title": "Tietoja",
"about.description":
"Livonsaaren Tietokonepaja on paikallisprojekti, joka tuottaa IT-palveluita rakkaalle lähisaaristollemme.",
@@ -207,6 +215,11 @@ const translations = {
"home.openHours.saved": "Nová verzia uložená",
"home.openHours.updated": "Verzia bola aktualizovaná",
"home.openHours.deleted": "Verzia bola odstránená",
+ "home.openHours.deleting": "Odstraňuje sa...",
+ "home.openHours.deleteConfirmTitle": "Odstrániť verziu?",
+ "home.openHours.deleteConfirmMessage":
+ "Túto akciu nie je možné vrátiť späť.",
+ "home.openHours.deleteConfirmAction": "Odstrániť verziu",
"about.title": "O aplikácii",
"about.description":
"Livonsaaren Tietokonepaja je lokálny projekt poskytujúci IT služby pre naše milované súostrovie.",