From 03a6b7b455c73e0fedaf2e0484085d52c7f1e339 Mon Sep 17 00:00:00 2001 From: gilles Date: Mon, 21 Sep 2026 19:06:38 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20page=20=C3=A9dition=20d'une=20carte?= =?UTF-8?q?=20pr=C3=A9-remplie=20(P3-5,=20F-06)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Page /cards/:id/edit : charge la carte via cardsApi, pré-remplit CardForm en mode edit et enregistre via cardsApi.update. Ajoute un test F-06 au form (pré-remplissage + update + navigation). Coche P3-5 dans TODO. --- src/app/cards/[id]/edit/page.tsx | 45 +++++++++++++++++++++++++++++++ src/components/card-form.test.tsx | 22 +++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/app/cards/[id]/edit/page.tsx diff --git a/src/app/cards/[id]/edit/page.tsx b/src/app/cards/[id]/edit/page.tsx new file mode 100644 index 0000000..7cc784f --- /dev/null +++ b/src/app/cards/[id]/edit/page.tsx @@ -0,0 +1,45 @@ +import type { Metadata } from 'next' +import Link from 'next/link' +import { notFound } from 'next/navigation' +import { CardForm } from '@/components/card-form' +import type { Card, CardInput } from '@/domain/card' +import { ApiClientError, cardsApi } from '@/lib/api-client' + +export const metadata: Metadata = { title: 'Modifier la carte' } + +export default async function EditCardPage({ + params, +}: { + params: Promise<{ id: string }> +}) { + const { id } = await params + let card: Card | null = null + try { + card = await cardsApi.get(id) + } catch (e) { + if (e instanceof ApiClientError && e.status === 404) notFound() + throw e + } + + const initial: CardInput = { + question: card.question, + response: card.response, + theme: card.theme, + tags: card.tags, + } + + return ( +
+
+ + ← Retour au détail + +

{card.question}

+
+ +
+ ) +} diff --git a/src/components/card-form.test.tsx b/src/components/card-form.test.tsx index e846901..6631281 100644 --- a/src/components/card-form.test.tsx +++ b/src/components/card-form.test.tsx @@ -36,3 +36,25 @@ it('crée une carte puis navigue vers son détail (F-05)', async () => { }) await screen.findByText('Enregistrement…') }) + +it('pré-remplit le formulaire et enregistre une modification (F-06 édition)', async () => { + vi.mocked(cardsApi.update).mockResolvedValue({ id: 'c1' } as never) + render( + , + ) + const question = screen.getByLabelText('Question') + expect(question).toHaveValue('Ancienne question') + await userEvent.clear(question) + await userEvent.type(question, 'Nouvelle question') + await userEvent.click(screen.getByRole('button', { name: 'Enregistrer' })) + expect(vi.mocked(cardsApi.update)).toHaveBeenCalledWith('c1', { + question: 'Nouvelle question', + response: 'Ancienne réponse', + theme: 'git', + }) + expect(routerMock.push).toHaveBeenCalledWith('/cards/c1') +})