feat(web): add reusable ConfirmDialog and polish delete interactions

Extracts reusable ConfirmDialog component, refactors ship delete to show
the ship name in confirmation, and improves interaction consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bas van Rossem
2026-02-19 16:27:43 +01:00
parent 1ef2f6338c
commit b3a55d9fac
2 changed files with 49 additions and 25 deletions

View File

@@ -3,6 +3,7 @@ import TopBar from '../components/layout/TopBar';
import PageContainer from '../components/layout/PageContainer';
import ShipCard from '../components/ships/ShipCard';
import CreateShipModal from '../components/ships/CreateShipModal';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import { useShipsList } from '../store/use-ships-list';
export default function ShipListPage() {
@@ -14,9 +15,9 @@ export default function ShipListPage() {
fetchShips();
}, [fetchShips]);
const handleDelete = async (id: string) => {
setPendingDelete(id);
};
const pendingShipName = pendingDelete
? ships.find((s) => s.id === pendingDelete)?.name ?? 'this ship'
: '';
const confirmDelete = async () => {
if (!pendingDelete) return;
@@ -42,33 +43,21 @@ export default function ShipListPage() {
<div className="ship-list">
{ships.map((ship) => (
<ShipCard key={ship.id} ship={ship} onDelete={handleDelete} />
<ShipCard key={ship.id} ship={ship} onDelete={(id) => setPendingDelete(id)} />
))}
</div>
<CreateShipModal open={showCreate} onClose={() => setShowCreate(false)} />
{/* Simple delete confirmation */}
{pendingDelete && (
<div className="modal-overlay" onClick={() => setPendingDelete(null)}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h2 className="modal-title">Delete Ship?</h2>
</div>
<p style={{ margin: 'var(--spacing-md) 0' }}>
This will permanently delete this ship and all its weapons.
</p>
<div className="modal-actions">
<button className="btn-secondary" onClick={() => setPendingDelete(null)}>
Cancel
</button>
<button className="btn-danger" onClick={confirmDelete}>
Delete
</button>
</div>
</div>
</div>
)}
<ConfirmDialog
open={!!pendingDelete}
onClose={() => setPendingDelete(null)}
onConfirm={confirmDelete}
title="Delete Ship?"
message={`Permanently delete "${pendingShipName}" and all its weapons?`}
confirmLabel="Delete"
danger
/>
</PageContainer>
</>
);