@mytec: iter9.1 ready for test
This commit is contained in:
@@ -3,6 +3,7 @@ import type { Site } from '@/types/index.ts';
|
||||
import { useSitesStore } from '@/store/sites.ts';
|
||||
import { useToastStore } from '@/components/ui/Toast.tsx';
|
||||
import Button from '@/components/ui/Button.tsx';
|
||||
import ConfirmDialog from '@/components/ui/ConfirmDialog.tsx';
|
||||
import BatchEdit from './BatchEdit.tsx';
|
||||
|
||||
interface SiteListProps {
|
||||
@@ -58,10 +59,49 @@ export default function SiteList({ onEditSite, onAddSite }: SiteListProps) {
|
||||
setTimeout(() => setFlashIds(new Set()), 700);
|
||||
}, []);
|
||||
|
||||
const handleDelete = async (id: string, name: string) => {
|
||||
// Delete confirmation dialog state
|
||||
const [deleteTarget, setDeleteTarget] = useState<{ id: string; name: string } | null>(null);
|
||||
|
||||
const handleDeleteConfirmed = useCallback(async () => {
|
||||
if (!deleteTarget) return;
|
||||
const { id, name } = deleteTarget;
|
||||
|
||||
// Snapshot the site data before deleting (for undo)
|
||||
const siteData = sites.find((s) => s.id === id);
|
||||
setDeleteTarget(null);
|
||||
|
||||
await deleteSite(id);
|
||||
addToast(`"${name}" deleted`, 'info');
|
||||
};
|
||||
|
||||
// Toast with undo action
|
||||
if (siteData) {
|
||||
addToast(`"${name}" deleted`, 'info', {
|
||||
duration: 10000,
|
||||
action: {
|
||||
label: 'Undo',
|
||||
onClick: async () => {
|
||||
// Restore the deleted site
|
||||
await useSitesStore.getState().addSite({
|
||||
name: siteData.name,
|
||||
lat: siteData.lat,
|
||||
lon: siteData.lon,
|
||||
height: siteData.height,
|
||||
power: siteData.power,
|
||||
gain: siteData.gain,
|
||||
frequency: siteData.frequency,
|
||||
antennaType: siteData.antennaType,
|
||||
azimuth: siteData.azimuth,
|
||||
beamwidth: siteData.beamwidth,
|
||||
color: siteData.color,
|
||||
visible: siteData.visible,
|
||||
notes: siteData.notes,
|
||||
equipment: siteData.equipment,
|
||||
});
|
||||
addToast(`"${name}" restored`, 'success');
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [deleteTarget, sites, deleteSite, addToast]);
|
||||
|
||||
const allSelected = sites.length > 0 && selectedSiteIds.length === sites.length;
|
||||
|
||||
@@ -148,7 +188,7 @@ export default function SiteList({ onEditSite, onAddSite }: SiteListProps) {
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDelete(site.id, site.name);
|
||||
setDeleteTarget({ id: site.id, name: site.name });
|
||||
}}
|
||||
className="px-2 py-1 text-xs text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 rounded min-w-[32px] min-h-[32px] flex items-center justify-center"
|
||||
title="Delete site"
|
||||
@@ -245,6 +285,18 @@ export default function SiteList({ onEditSite, onAddSite }: SiteListProps) {
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{/* Delete confirmation dialog */}
|
||||
{deleteTarget && (
|
||||
<ConfirmDialog
|
||||
title="Delete Site?"
|
||||
message={`Are you sure you want to delete "${deleteTarget.name}"? This action can be undone for 10 seconds.`}
|
||||
confirmLabel="Delete"
|
||||
cancelLabel="Cancel"
|
||||
danger
|
||||
onConfirm={handleDeleteConfirmed}
|
||||
onCancel={() => setDeleteTarget(null)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user