Files
GearBox/src/client/components/ConfirmDialog.tsx
Jean-Luc Makiola 672b17fd13 feat(i18n): extract strings from navigation, dialogs, onboarding, settings, and login
- Add useTranslation() to TopNav, BottomTabBar, FabMenu, UserMenu
- Internationalize ConfirmDialog, AuthPromptModal, ExternalLinkDialog
- Extract all onboarding flow strings (Welcome, HobbyPicker, ItemBrowser, Review, Done)
- Internationalize settings page (weight unit, currency, API keys, import/export)
- Internationalize login page and root error boundary
- All dialogs in __root.tsx use t() for UI chrome

Phase 34, Plan 02 (core navigation and global UI)
2026-04-13 18:19:29 +02:00

61 lines
1.9 KiB
TypeScript

import { useTranslation } from "react-i18next";
import { useDeleteItem, useItems } from "../hooks/useItems";
import { useUIStore } from "../stores/uiStore";
export function ConfirmDialog() {
const { t } = useTranslation();
const confirmDeleteItemId = useUIStore((s) => s.confirmDeleteItemId);
const closeConfirmDelete = useUIStore((s) => s.closeConfirmDelete);
const deleteItem = useDeleteItem();
const { data: items } = useItems();
if (confirmDeleteItemId == null) return null;
const item = items?.find((i) => i.id === confirmDeleteItemId);
const itemName = item?.name ?? "this item";
function handleDelete() {
if (confirmDeleteItemId == null) return;
deleteItem.mutate(confirmDeleteItemId, {
onSuccess: () => closeConfirmDelete(),
});
}
return (
<div className="fixed inset-0 z-50 flex items-center justify-center">
<div
className="absolute inset-0 bg-black/30"
onClick={closeConfirmDelete}
onKeyDown={(e) => {
if (e.key === "Escape") closeConfirmDelete();
}}
/>
<div className="relative bg-white rounded-xl shadow-lg p-6 max-w-sm mx-4 w-full">
<h3 className="text-lg font-semibold text-gray-900 mb-2">
{t("confirm.deleteItem")}
</h3>
<p className="text-sm text-gray-600 mb-6">
{t("confirm.deleteItemMessage", { name: itemName })}
</p>
<div className="flex justify-end gap-3">
<button
type="button"
onClick={closeConfirmDelete}
className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
>
{t("actions.cancel")}
</button>
<button
type="button"
onClick={handleDelete}
disabled={deleteItem.isPending}
className="px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 disabled:opacity-50 rounded-lg transition-colors"
>
{deleteItem.isPending ? t("actions.deleting") : t("actions.delete")}
</button>
</div>
</div>
</div>
);
}