From c2609af9d8bac65d3e70b3860160ac8bfe097241 Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Sun, 7 Dec 2025 18:33:16 +0900
Subject: feat(client): add delete card modal with confirmation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Completes Phase 5 card management by adding the ability to delete cards
with a confirmation dialog. Includes unit tests for the modal component
and integration tests for the delete flow in DeckDetailPage.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---
 src/client/pages/DeckDetailPage.tsx | 45 ++++++++++++++++++++++++++++++++-----
 1 file changed, 39 insertions(+), 6 deletions(-)

(limited to 'src/client/pages/DeckDetailPage.tsx')

diff --git a/src/client/pages/DeckDetailPage.tsx b/src/client/pages/DeckDetailPage.tsx
index 57e4af9..cdc216a 100644
--- a/src/client/pages/DeckDetailPage.tsx
+++ b/src/client/pages/DeckDetailPage.tsx
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useState } from "react";
 import { Link, useParams } from "wouter";
 import { ApiClientError, apiClient } from "../api";
 import { CreateCardModal } from "../components/CreateCardModal";
+import { DeleteCardModal } from "../components/DeleteCardModal";
 import { EditCardModal } from "../components/EditCardModal";
 
 interface Card {
@@ -38,6 +39,7 @@ export function DeckDetailPage() {
 	const [error, setError] = useState<string | null>(null);
 	const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
 	const [editingCard, setEditingCard] = useState<Card | null>(null);
+	const [deletingCard, setDeletingCard] = useState<Card | null>(null);
 
 	const fetchDeck = useCallback(async () => {
 		if (!deckId) return;
@@ -241,13 +243,34 @@ export function DeckDetailPage() {
 												<span>Lapses: {card.lapses}</span>
 											</div>
 										</div>
-										<button
-											type="button"
-											onClick={() => setEditingCard(card)}
-											style={{ marginLeft: "1rem" }}
+										<div
+											style={{
+												display: "flex",
+												gap: "0.5rem",
+												marginLeft: "1rem",
+											}}
 										>
-											Edit
-										</button>
+											<button
+												type="button"
+												onClick={() => setEditingCard(card)}
+											>
+												Edit
+											</button>
+											<button
+												type="button"
+												onClick={() => setDeletingCard(card)}
+												style={{
+													backgroundColor: "#dc3545",
+													color: "white",
+													border: "none",
+													padding: "0.5rem 1rem",
+													borderRadius: "4px",
+													cursor: "pointer",
+												}}
+											>
+												Delete
+											</button>
+										</div>
 									</div>
 								</li>
 							))}
@@ -274,6 +297,16 @@ export function DeckDetailPage() {
 					onCardUpdated={fetchCards}
 				/>
 			)}
+
+			{deckId && (
+				<DeleteCardModal
+					isOpen={deletingCard !== null}
+					deckId={deckId}
+					card={deletingCard}
+					onClose={() => setDeletingCard(null)}
+					onCardDeleted={fetchCards}
+				/>
+			)}
 		</div>
 	);
 }
-- 
cgit v1.2.3-70-g09d2

