aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/pages/DeckDetailPage.tsx
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-12-07 18:25:40 +0900
committernsfisis <nsfisis@gmail.com>2025-12-07 18:25:40 +0900
commitdeef992b8cc7e57b880c1c38f994d38825240ca1 (patch)
tree7309c798df469fb249eb6a30da350712ce38f66f /src/client/pages/DeckDetailPage.tsx
parentaf9a4912f914bb198fe13bd3421ea33ff3bf9d45 (diff)
downloadkioku-deef992b8cc7e57b880c1c38f994d38825240ca1.tar.gz
kioku-deef992b8cc7e57b880c1c38f994d38825240ca1.tar.zst
kioku-deef992b8cc7e57b880c1c38f994d38825240ca1.zip
feat(client): add create card modal with form validation
Add CreateCardModal component to allow users to create new flashcards with front and back text fields. Integrate the modal into DeckDetailPage with an "Add Card" button. Include comprehensive unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/pages/DeckDetailPage.tsx')
-rw-r--r--src/client/pages/DeckDetailPage.tsx14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/client/pages/DeckDetailPage.tsx b/src/client/pages/DeckDetailPage.tsx
index c713ab0..9fce7b7 100644
--- a/src/client/pages/DeckDetailPage.tsx
+++ b/src/client/pages/DeckDetailPage.tsx
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useState } from "react";
import { Link, useParams } from "wouter";
import { ApiClientError, apiClient } from "../api";
+import { CreateCardModal } from "../components/CreateCardModal";
interface Card {
id: string;
@@ -34,6 +35,7 @@ export function DeckDetailPage() {
const [cards, setCards] = useState<Card[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
+ const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const fetchDeck = useCallback(async () => {
if (!deckId) return;
@@ -158,6 +160,9 @@ export function DeckDetailPage() {
}}
>
<h2 style={{ margin: 0 }}>Cards ({cards.length})</h2>
+ <button type="button" onClick={() => setIsCreateModalOpen(true)}>
+ Add Card
+ </button>
</div>
{cards.length === 0 && (
@@ -241,6 +246,15 @@ export function DeckDetailPage() {
)}
</main>
)}
+
+ {deckId && (
+ <CreateCardModal
+ isOpen={isCreateModalOpen}
+ deckId={deckId}
+ onClose={() => setIsCreateModalOpen(false)}
+ onCardCreated={fetchCards}
+ />
+ )}
</div>
);
}