2025-04-27 15:25:45 -03:00
|
|
|
|
|
|
|
"use client";
|
|
|
|
|
2025-03-30 16:42:51 -03:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
import { useForm, Controller } from 'react-hook-form';
|
|
|
|
import { z } from 'zod';
|
|
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
|
|
|
|
|
|
const accountFormSchema = z.object({
|
|
|
|
name: z
|
|
|
|
.string()
|
|
|
|
.min(2, {
|
|
|
|
message: "Name must be at least 2 characters.",
|
|
|
|
})
|
|
|
|
.max(30, {
|
|
|
|
message: "Name must not be longer than 30 characters.",
|
|
|
|
}),
|
|
|
|
dob: z.date({
|
|
|
|
required_error: "A date of birth is required.",
|
|
|
|
}),
|
|
|
|
language: z.string({
|
|
|
|
required_error: "Please select a language.",
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
|
|
|
|
type AccountFormValues = z.infer<typeof accountFormSchema>;
|
|
|
|
|
|
|
|
const defaultValues: Partial<AccountFormValues> = {
|
|
|
|
name: "Your name",
|
|
|
|
dob: new Date("2000-01-01"),
|
|
|
|
language: "en",
|
|
|
|
};
|
|
|
|
|
|
|
|
const languages = [
|
|
|
|
{ label: "English", value: "en" },
|
|
|
|
{ label: "French", value: "fr" },
|
|
|
|
{ label: "German", value: "de" },
|
|
|
|
{ label: "Spanish", value: "es" },
|
|
|
|
{ label: "Portuguese", value: "pt" },
|
|
|
|
{ label: "Russian", value: "ru" },
|
|
|
|
{ label: "Japanese", value: "ja" },
|
|
|
|
{ label: "Korean", value: "ko" },
|
|
|
|
{ label: "Chinese", value: "zh" },
|
|
|
|
];
|
|
|
|
|
|
|
|
export function AccountForm() {
|
|
|
|
const [showDatePicker, setShowDatePicker] = useState(false);
|
|
|
|
const { control, handleSubmit } = useForm<AccountFormValues>({
|
|
|
|
resolver: zodResolver(accountFormSchema),
|
|
|
|
defaultValues,
|
|
|
|
});
|
|
|
|
|
|
|
|
const onSubmit = (data: AccountFormValues) => {
|
|
|
|
console.log(JSON.stringify(data, null, 2));
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="space-y-4">
|
2025-03-30 16:42:51 -03:00
|
|
|
<Controller
|
|
|
|
control={control}
|
|
|
|
name="name"
|
|
|
|
render={({ field: { onChange, value } }) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="mb-4">
|
|
|
|
<label className="block text-sm font-medium mb-1">Name</label>
|
|
|
|
<input
|
|
|
|
className="w-full p-2 border rounded"
|
|
|
|
onChange={(e) => onChange(e.target.value)}
|
2025-03-30 16:42:51 -03:00
|
|
|
value={value}
|
|
|
|
placeholder="Your name"
|
|
|
|
/>
|
2025-03-30 19:39:59 -03:00
|
|
|
<p className="text-sm text-gray-500 mt-1">
|
2025-03-30 16:42:51 -03:00
|
|
|
This is the name that will be displayed on your profile and in emails.
|
2025-03-30 19:39:59 -03:00
|
|
|
</p>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
)}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Controller
|
|
|
|
control={control}
|
|
|
|
name="dob"
|
|
|
|
render={({ field: { onChange, value } }) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="mb-4">
|
|
|
|
<label className="block text-sm font-medium mb-1">Date of birth</label>
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
className="w-full p-2 border rounded text-left"
|
|
|
|
onClick={() => setShowDatePicker(true)}
|
2025-03-30 16:42:51 -03:00
|
|
|
>
|
2025-03-30 19:39:59 -03:00
|
|
|
{value.toDateString()}
|
|
|
|
</button>
|
2025-03-30 16:42:51 -03:00
|
|
|
{showDatePicker && (
|
2025-03-30 19:39:59 -03:00
|
|
|
<input
|
|
|
|
type="date"
|
|
|
|
value={value.toISOString().split('T')[0]}
|
|
|
|
onChange={(e) => {
|
2025-03-30 16:42:51 -03:00
|
|
|
setShowDatePicker(false);
|
2025-03-30 19:39:59 -03:00
|
|
|
if (e.target.value) {
|
|
|
|
onChange(new Date(e.target.value));
|
2025-03-30 16:42:51 -03:00
|
|
|
}
|
|
|
|
}}
|
2025-03-30 19:39:59 -03:00
|
|
|
className="mt-1 p-1 border rounded"
|
2025-03-30 16:42:51 -03:00
|
|
|
/>
|
|
|
|
)}
|
2025-03-30 19:39:59 -03:00
|
|
|
<p className="text-sm text-gray-500 mt-1">
|
2025-03-30 16:42:51 -03:00
|
|
|
Your date of birth is used to calculate your age.
|
2025-03-30 19:39:59 -03:00
|
|
|
</p>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
)}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Controller
|
|
|
|
control={control}
|
|
|
|
name="language"
|
|
|
|
render={({ field: { onChange, value } }) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="mb-4">
|
|
|
|
<label className="block text-sm font-medium mb-1">Language</label>
|
|
|
|
<select
|
|
|
|
className="w-full p-2 border rounded"
|
|
|
|
value={value}
|
|
|
|
onChange={(e) => onChange(e.target.value)}
|
2025-03-30 16:42:51 -03:00
|
|
|
>
|
|
|
|
{languages.map((language) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<option key={language.value} value={language.value}>
|
|
|
|
{language.label}
|
|
|
|
</option>
|
2025-03-30 16:42:51 -03:00
|
|
|
))}
|
2025-03-30 19:39:59 -03:00
|
|
|
</select>
|
|
|
|
<p className="text-sm text-gray-500 mt-1">
|
2025-03-30 16:42:51 -03:00
|
|
|
This is the language that will be used in the dashboard.
|
2025-03-30 19:39:59 -03:00
|
|
|
</p>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
)}
|
|
|
|
/>
|
|
|
|
|
2025-03-30 19:39:59 -03:00
|
|
|
<button
|
|
|
|
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
|
|
|
|
onClick={handleSubmit(onSubmit)}
|
2025-03-30 16:42:51 -03:00
|
|
|
>
|
2025-03-30 19:39:59 -03:00
|
|
|
Update account
|
|
|
|
</button>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
);
|
|
|
|
}
|