feat(client-archive): bulk-archive wizard with per-high-stakes confirmation
Replaces the single window.confirm() with a 3-stage wizard: - preflight: counts auto/needs-reason/blocked (POST /bulk-archive-preflight) - reasons: carousel through high-stakes clients capturing per-client reason (≥5 chars) — bulk endpoint accepts reasonsByClientId map - confirm: shows the final archivable count and submits Low-stakes still auto-archives with safe defaults; blocked clients are skipped with a per-row reason in the preflight summary. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import { ArchiveConfirmDialog } from '@/components/shared/archive-confirm-dialog
|
||||
import { PermissionGate } from '@/components/shared/permission-gate';
|
||||
import { TagPicker } from '@/components/shared/tag-picker';
|
||||
import { BulkHardDeleteDialog } from '@/components/clients/bulk-hard-delete-dialog';
|
||||
import { BulkArchiveWizard } from '@/components/clients/bulk-archive-wizard';
|
||||
import { usePermissions } from '@/hooks/use-permissions';
|
||||
import {
|
||||
Dialog,
|
||||
@@ -46,6 +47,7 @@ export function ClientList() {
|
||||
);
|
||||
const [tagChoice, setTagChoice] = useState<string[]>([]);
|
||||
const [bulkDeleteIds, setBulkDeleteIds] = useState<string[]>([]);
|
||||
const [bulkArchiveIds, setBulkArchiveIds] = useState<string[]>([]);
|
||||
|
||||
const { can } = usePermissions();
|
||||
const canHardDelete = can('admin', 'permanently_delete_clients');
|
||||
@@ -183,14 +185,7 @@ export function ClientList() {
|
||||
variant: 'destructive',
|
||||
onClick: (ids) => {
|
||||
if (ids.length === 0) return;
|
||||
if (
|
||||
!window.confirm(
|
||||
`Archive ${ids.length} client${ids.length === 1 ? '' : 's'}? This can be undone from the archived list.`,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
bulkMutation.mutate({ action: 'archive', ids });
|
||||
setBulkArchiveIds(ids);
|
||||
},
|
||||
},
|
||||
...(canHardDelete
|
||||
@@ -298,6 +293,13 @@ export function ClientList() {
|
||||
clientIds={bulkDeleteIds}
|
||||
onDeleted={() => setBulkDeleteIds([])}
|
||||
/>
|
||||
|
||||
<BulkArchiveWizard
|
||||
open={bulkArchiveIds.length > 0}
|
||||
onOpenChange={(open) => !open && setBulkArchiveIds([])}
|
||||
clientIds={bulkArchiveIds}
|
||||
onSuccess={() => setBulkArchiveIds([])}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user