From fe101104cdd50256d4ef5c61e1bf099ed2da68e3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 7 Dec 2025 19:16:48 +0900 Subject: feat(server): add POST /api/sync/push endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement sync push endpoint with Last-Write-Wins conflict resolution. Includes Zod validation for decks, cards, and review logs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/client/pages/StudyPage.tsx | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src/client') diff --git a/src/client/pages/StudyPage.tsx b/src/client/pages/StudyPage.tsx index 05e9943..c6f8665 100644 --- a/src/client/pages/StudyPage.tsx +++ b/src/client/pages/StudyPage.tsx @@ -144,17 +144,14 @@ export function StudyPage() { throw new ApiClientError("Not authenticated", 401); } - const res = await fetch( - `/api/decks/${deckId}/study/${currentCard.id}`, - { - method: "POST", - headers: { - ...authHeader, - "Content-Type": "application/json", - }, - body: JSON.stringify({ rating, durationMs }), + const res = await fetch(`/api/decks/${deckId}/study/${currentCard.id}`, { + method: "POST", + headers: { + ...authHeader, + "Content-Type": "application/json", }, - ); + body: JSON.stringify({ rating, durationMs }), + }); if (!res.ok) { const errorBody = await res.json().catch(() => ({})); @@ -312,7 +309,13 @@ export function StudyPage() { {completedCount}{" "} card{completedCount !== 1 ? "s" : ""}.

-
+
@@ -336,7 +339,9 @@ export function StudyPage() { }} role="button" tabIndex={0} - aria-label={isFlipped ? "Card showing answer" : "Click to reveal answer"} + aria-label={ + isFlipped ? "Card showing answer" : "Click to reveal answer" + } style={{ border: "1px solid #ccc", borderRadius: "8px", -- cgit v1.2.3-70-g09d2