Skip to content

Commit 06173ec

Browse files
author
Szymon Kozioł
committed
Validation for flashcardset pick name dialog
1 parent 8e45354 commit 06173ec

File tree

4 files changed

+53
-24
lines changed

4 files changed

+53
-24
lines changed

public/locales/en.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

public/locales/en/sets.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
},
1010
"pickName": {
1111
"title": "Pick a name for your flashcard set",
12-
"placeholder": "Flashcard set name",
12+
"name": "Flashcard set name",
1313
"create": "Create",
14-
"cancel": "Cancel"
14+
"cancel": "Cancel",
15+
"nameIsRequired": "Name is required"
1516
},
1617
"enterUsername": {
1718
"title": "Enter your name",

public/locales/pl/sets.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
},
1010
"pickName": {
1111
"title": "Wybierz nazwę dla swojego zestawu fiszek",
12-
"placeholder": "Nazwa zestawu fiszek",
12+
"name": "Nazwa zestawu fiszek",
1313
"create": "Utwórz",
14-
"cancel": "Anuluj"
14+
"cancel": "Anuluj",
15+
"nameIsRequired": "Nazwa jest wymagana"
1516
},
1617
"enterUsername": {
1718
"title": "Wpisz swoje imię",

src/components/flashcard-sets/EnterFlashcardSetName.tsx

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { type ReactNode, useId, useState, useEffect } from 'react';
22

3+
import { zodResolver } from '@hookform/resolvers/zod';
4+
import { useForm } from 'react-hook-form';
35
import { useTranslation } from 'react-i18next';
6+
import { z } from 'zod';
47

58
import { Button } from '@/components/base/Button';
69
import {
@@ -11,24 +14,48 @@ import {
1114
DialogTitle,
1215
DialogTrigger,
1316
} from '@/components/base/Dialog';
17+
import {
18+
Form,
19+
FormControl,
20+
FormField,
21+
FormItem,
22+
FormLabel,
23+
FormMessage,
24+
} from '@/components/base/Form';
1425
import { Input } from '@/components/base/Input';
1526

27+
const formSchema = z.object({
28+
name: z.string().min(1, { message: 'dialog.pickName.nameIsRequired' }),
29+
});
30+
type FormSchema = z.infer<typeof formSchema>;
31+
1632
export type EnterFlashcardSetNameProps = {
1733
children: ReactNode;
1834
onSetName?: (name: string) => void;
1935
};
2036

2137
export function EnterFlashcardSetName({ children, onSetName }: EnterFlashcardSetNameProps) {
2238
const [dialogOpen, setDialogOpen] = useState(false);
23-
const [name, setName] = useState('');
2439
const formId = useId();
2540
const { t } = useTranslation('sets');
41+
const form = useForm<FormSchema>({
42+
resolver: zodResolver(formSchema),
43+
defaultValues: {
44+
name: '',
45+
},
46+
});
47+
48+
const onSubmit = ({ name }: FormSchema) => {
49+
setDialogOpen(false);
50+
onSetName?.(name);
51+
};
52+
2653
useEffect(() => {
2754
if (dialogOpen) {
2855
// Reset the name when the dialog is opened
29-
setName('');
56+
form.reset();
3057
}
31-
}, [dialogOpen]);
58+
}, [dialogOpen, form, form.reset]);
3259

3360
return (
3461
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
@@ -37,22 +64,23 @@ export function EnterFlashcardSetName({ children, onSetName }: EnterFlashcardSet
3764
<DialogHeader>
3865
<DialogTitle>{t('dialog.pickName.title')}</DialogTitle>
3966
</DialogHeader>
40-
<form
41-
id={formId}
42-
onSubmit={(e) => {
43-
e.preventDefault();
44-
onSetName?.(name);
45-
setDialogOpen(false);
46-
}}
47-
>
48-
<Input
49-
placeholder={t('dialog.pickName.placeholder')}
50-
value={name}
51-
onChange={(e) => {
52-
setName(e.target.value);
53-
}}
54-
/>
55-
</form>
67+
<Form {...form}>
68+
<form id={formId} onSubmit={form.handleSubmit(onSubmit)}>
69+
<FormField
70+
control={form.control}
71+
name="name"
72+
render={({ field }) => (
73+
<FormItem>
74+
<FormLabel>{t('dialog.pickName.name')}</FormLabel>
75+
<FormControl>
76+
<Input {...field} />
77+
</FormControl>
78+
<FormMessage />
79+
</FormItem>
80+
)}
81+
/>
82+
</form>
83+
</Form>
5684

5785
<DialogFooter className="flex flex-row justify-between">
5886
<Button variant="outlined" onClick={() => setDialogOpen(false)}>

0 commit comments

Comments
 (0)