From 25f29d1016a6083f97d3ed094142ff1ca9faf775 Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Wed, 31 Dec 2025 13:31:46 +0900
Subject: feat(client): add EditNoteModal for editing note-based cards
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Create EditNoteModal component that loads note and field values
- Update DeckDetailPage to use EditNoteModal for cards with noteId
- Keep EditCardModal for legacy cards without note association
- Add visual indicator for reversed cards in card list
- Add comprehensive tests for EditNoteModal

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

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

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

diff --git a/src/client/pages/DeckDetailPage.tsx b/src/client/pages/DeckDetailPage.tsx
index 9a158f6..a06fcc7 100644
--- a/src/client/pages/DeckDetailPage.tsx
+++ b/src/client/pages/DeckDetailPage.tsx
@@ -14,10 +14,13 @@ import { ApiClientError, apiClient } from "../api";
 import { CreateNoteModal } from "../components/CreateNoteModal";
 import { DeleteCardModal } from "../components/DeleteCardModal";
 import { EditCardModal } from "../components/EditCardModal";
+import { EditNoteModal } from "../components/EditNoteModal";
 
 interface Card {
 	id: string;
 	deckId: string;
+	noteId: string | null;
+	isReversed: boolean | null;
 	front: string;
 	back: string;
 	state: number;
@@ -56,6 +59,7 @@ export function DeckDetailPage() {
 	const [error, setError] = useState<string | null>(null);
 	const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
 	const [editingCard, setEditingCard] = useState<Card | null>(null);
+	const [editingNoteId, setEditingNoteId] = useState<string | null>(null);
 	const [deletingCard, setDeletingCard] = useState<Card | null>(null);
 
 	const fetchDeck = useCallback(async () => {
@@ -311,6 +315,11 @@ export function DeckDetailPage() {
 													>
 														{CardStateLabels[card.state] || "Unknown"}
 													</span>
+													{card.isReversed && (
+														<span className="px-2 py-0.5 rounded-full font-medium bg-slate/10 text-slate">
+															Reversed
+														</span>
+													)}
 													<span className="text-muted">
 														{card.reps} reviews
 													</span>
@@ -326,9 +335,15 @@ export function DeckDetailPage() {
 											<div className="flex items-center gap-1 shrink-0">
 												<button
 													type="button"
-													onClick={() => setEditingCard(card)}
+													onClick={() => {
+														if (card.noteId) {
+															setEditingNoteId(card.noteId);
+														} else {
+															setEditingCard(card);
+														}
+													}}
 													className="p-2 text-muted hover:text-slate hover:bg-ivory rounded-lg transition-colors"
-													title="Edit card"
+													title={card.noteId ? "Edit note" : "Edit card"}
 												>
 													<FontAwesomeIcon
 														icon={faPen}
@@ -378,6 +393,16 @@ export function DeckDetailPage() {
 				/>
 			)}
 
+			{deckId && (
+				<EditNoteModal
+					isOpen={editingNoteId !== null}
+					deckId={deckId}
+					noteId={editingNoteId}
+					onClose={() => setEditingNoteId(null)}
+					onNoteUpdated={fetchCards}
+				/>
+			)}
+
 			{deckId && (
 				<DeleteCardModal
 					isOpen={deletingCard !== null}
-- 
cgit v1.2.3-70-g09d2

