feat(tags): confirm deletion before removing tags
This commit is contained in:
@@ -324,6 +324,8 @@ export const en = {
|
|||||||
create: "Create Tag",
|
create: "Create Tag",
|
||||||
createTitle: "Create Tag",
|
createTitle: "Create Tag",
|
||||||
editTitle: "Edit Tag",
|
editTitle: "Edit Tag",
|
||||||
|
deleteTitle: "Delete Tag",
|
||||||
|
deleteConfirmMessage: (name: string) => `Are you sure you want to delete ${name}?`,
|
||||||
searchPlaceholder: "Search tags...",
|
searchPlaceholder: "Search tags...",
|
||||||
nameLabel: "Tag Name",
|
nameLabel: "Tag Name",
|
||||||
namePlaceholder: "e.g. Design",
|
namePlaceholder: "e.g. Design",
|
||||||
|
|||||||
@@ -321,6 +321,8 @@ export const fa = {
|
|||||||
create: "ایجاد تگ",
|
create: "ایجاد تگ",
|
||||||
createTitle: "ایجاد تگ",
|
createTitle: "ایجاد تگ",
|
||||||
editTitle: "ویرایش تگ",
|
editTitle: "ویرایش تگ",
|
||||||
|
deleteTitle: "حذف تگ",
|
||||||
|
deleteConfirmMessage: (name: string) => `آیا از حذف ${name} اطمینان دارید؟`,
|
||||||
searchPlaceholder: "جستوجوی تگها...",
|
searchPlaceholder: "جستوجوی تگها...",
|
||||||
nameLabel: "نام تگ",
|
nameLabel: "نام تگ",
|
||||||
namePlaceholder: "مثلاً طراحی",
|
namePlaceholder: "مثلاً طراحی",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export default function Tags() {
|
|||||||
const [formName, setFormName] = useState("");
|
const [formName, setFormName] = useState("");
|
||||||
const [formColor, setFormColor] = useState(DEFAULT_COLOR);
|
const [formColor, setFormColor] = useState(DEFAULT_COLOR);
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
const [deleteModal, setDeleteModal] = useState<{ isOpen: boolean; tag: Tag | null }>({ isOpen: false, tag: null });
|
||||||
|
|
||||||
const orderingOptions = [
|
const orderingOptions = [
|
||||||
{ value: "-updated_at", label: t.ordering?.updatedAtDesc || "Recently Updated" },
|
{ value: "-updated_at", label: t.ordering?.updatedAtDesc || "Recently Updated" },
|
||||||
@@ -191,7 +192,12 @@ export default function Tags() {
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{canDeleteTag && (
|
{canDeleteTag && (
|
||||||
<Button variant="ghost" size="icon" onClick={() => void handleDelete(tag)} title={t.actions?.delete || "Delete"}>
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => setDeleteModal({ isOpen: true, tag })}
|
||||||
|
title={t.actions?.delete || "Delete"}
|
||||||
|
>
|
||||||
<Trash2 className="w-4 h-4 text-red-500" />
|
<Trash2 className="w-4 h-4 text-red-500" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -250,6 +256,37 @@ export default function Tags() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
{deleteModal.tag && (
|
||||||
|
<Modal
|
||||||
|
isOpen={deleteModal.isOpen}
|
||||||
|
onClose={() => setDeleteModal({ isOpen: false, tag: null })}
|
||||||
|
title={t.tags?.deleteTitle || "Delete Tag"}
|
||||||
|
maxWidth="max-w-md"
|
||||||
|
footer={
|
||||||
|
<>
|
||||||
|
<Button variant="secondary" onClick={() => setDeleteModal({ isOpen: false, tag: null })}>
|
||||||
|
{t.actions?.cancel || "Cancel"}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
onClick={() => {
|
||||||
|
if (!deleteModal.tag) return;
|
||||||
|
void handleDelete(deleteModal.tag);
|
||||||
|
setDeleteModal({ isOpen: false, tag: null });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t.actions?.delete || "Delete"}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p className="text-sm leading-relaxed text-slate-600 dark:text-slate-400">
|
||||||
|
{(t.tags?.deleteConfirmMessage as ((name: string) => string) | undefined)?.(deleteModal.tag.name) ||
|
||||||
|
`Are you sure you want to delete "${deleteModal.tag.name}"?`}
|
||||||
|
</p>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user