From b074a4901c630ee5c5f7dcff79fa6ff911a14ded Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 31 Dec 2025 14:19:22 +0900 Subject: feat(schema): make note_id and is_reversed NOT NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All cards now require note association - legacy card support removed. This aligns with the note-based card architecture introduced in Phase 8. - Add database migration for NOT NULL constraints - Update client Dexie schema to version 3 - Remove LegacyCardItem component and legacy card handling - Update sync schemas and type definitions - Update all tests to use note-based cards 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/client/pages/DeckDetailPage.tsx | 156 +++++------------------------------- 1 file changed, 20 insertions(+), 136 deletions(-) (limited to 'src/client/pages/DeckDetailPage.tsx') diff --git a/src/client/pages/DeckDetailPage.tsx b/src/client/pages/DeckDetailPage.tsx index 87f9dc3..d018d1f 100644 --- a/src/client/pages/DeckDetailPage.tsx +++ b/src/client/pages/DeckDetailPage.tsx @@ -21,8 +21,8 @@ import { EditNoteModal } from "../components/EditNoteModal"; interface Card { id: string; deckId: string; - noteId: string | null; - isReversed: boolean | null; + noteId: string; + isReversed: boolean; front: string; back: string; state: number; @@ -33,10 +33,8 @@ interface Card { updatedAt: string; } -/** Combined type for display: either a note group or a legacy card */ -type CardDisplayItem = - | { type: "note"; noteId: string; cards: Card[] } - | { type: "legacy"; card: Card }; +/** Combined type for display: note group */ +type CardDisplayItem = { type: "note"; noteId: string; cards: Card[] }; interface Deck { id: string; @@ -178,95 +176,6 @@ function NoteGroupCard({ ); } -/** Component for displaying a legacy card (without note association) */ -function LegacyCardItem({ - card, - index, - onEdit, - onDelete, -}: { - card: Card; - index: number; - onEdit: () => void; - onDelete: () => void; -}) { - return ( -
-
-
- {/* Front/Back Preview */} -
-
- - Front - -

- {card.front} -

-
-
- - Back - -

- {card.back} -

-
-
- - {/* Card Stats */} -
- - {CardStateLabels[card.state] || "Unknown"} - - - Legacy - - {card.reps} reviews - {card.lapses > 0 && ( - {card.lapses} lapses - )} -
-
- - {/* Actions */} -
- - -
-
-
- ); -} - export function DeckDetailPage() { const { deckId } = useParams<{ deckId: string }>(); const [deck, setDeck] = useState(null); @@ -282,24 +191,17 @@ export function DeckDetailPage() { // Group cards by note for display const displayItems = useMemo((): CardDisplayItem[] => { const noteGroups = new Map(); - const legacyCards: Card[] = []; for (const card of cards) { - if (card.noteId) { - const existing = noteGroups.get(card.noteId); - if (existing) { - existing.push(card); - } else { - noteGroups.set(card.noteId, [card]); - } + const existing = noteGroups.get(card.noteId); + if (existing) { + existing.push(card); } else { - legacyCards.push(card); + noteGroups.set(card.noteId, [card]); } } - const items: CardDisplayItem[] = []; - - // Add note groups first, sorted by earliest card creation + // Sort note groups by earliest card creation (newest first) const sortedNoteGroups = Array.from(noteGroups.entries()).sort( ([, cardsA], [, cardsB]) => { const minA = Math.min( @@ -312,6 +214,7 @@ export function DeckDetailPage() { }, ); + const items: CardDisplayItem[] = []; for (const [noteId, noteCards] of sortedNoteGroups) { // Sort cards within group: normal first, then reversed noteCards.sort((a, b) => { @@ -321,15 +224,6 @@ export function DeckDetailPage() { items.push({ type: "note", noteId, cards: noteCards }); } - // Add legacy cards, newest first - legacyCards.sort( - (a, b) => - new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(), - ); - for (const card of legacyCards) { - items.push({ type: "legacy", card }); - } - return items; }, [cards]); @@ -551,26 +445,16 @@ export function DeckDetailPage() { {/* Card List - Grouped by Note */} {cards.length > 0 && (
- {displayItems.map((item, index) => - item.type === "note" ? ( - setEditingNoteId(item.noteId)} - onDeleteNote={() => setDeletingNoteId(item.noteId)} - /> - ) : ( - setEditingCard(item.card)} - onDelete={() => setDeletingCard(item.card)} - /> - ), - )} + {displayItems.map((item, index) => ( + setEditingNoteId(item.noteId)} + onDeleteNote={() => setDeletingNoteId(item.noteId)} + /> + ))}
)} -- cgit v1.2.3-70-g09d2