2025-04-27 15:25:45 -03:00
|
|
|
"use client";
|
|
|
|
|
2025-03-30 16:42:51 -03:00
|
|
|
import React from 'react';
|
|
|
|
import { useForm, Controller } from 'react-hook-form';
|
|
|
|
import { z } from 'zod';
|
|
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
|
|
|
|
|
|
const profileFormSchema = z.object({
|
|
|
|
username: z
|
|
|
|
.string()
|
|
|
|
.min(2, {
|
|
|
|
message: "Username must be at least 2 characters.",
|
|
|
|
})
|
|
|
|
.max(30, {
|
|
|
|
message: "Username must not be longer than 30 characters.",
|
|
|
|
}),
|
|
|
|
email: z
|
|
|
|
.string({
|
|
|
|
required_error: "Please select an email to display.",
|
|
|
|
})
|
|
|
|
.email(),
|
|
|
|
bio: z.string().max(160).min(4),
|
|
|
|
});
|
|
|
|
|
|
|
|
type ProfileFormValues = z.infer<typeof profileFormSchema>;
|
|
|
|
|
|
|
|
const defaultValues: Partial<ProfileFormValues> = {
|
|
|
|
bio: "I own a computer.",
|
|
|
|
};
|
|
|
|
|
|
|
|
export function ProfileForm() {
|
|
|
|
const { control, handleSubmit } = useForm<ProfileFormValues>({
|
|
|
|
resolver: zodResolver(profileFormSchema),
|
|
|
|
defaultValues,
|
|
|
|
});
|
|
|
|
|
|
|
|
const onSubmit = (data: ProfileFormValues) => {
|
|
|
|
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="username"
|
|
|
|
render={({ field: { onChange, onBlur, value }, fieldState: { error } }) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="mb-4">
|
|
|
|
<label className="block text-sm font-medium mb-1">Username</label>
|
|
|
|
<input
|
|
|
|
className={`w-full p-2 border rounded ${error ? 'border-red-500' : 'border-gray-300'}`}
|
2025-03-30 16:42:51 -03:00
|
|
|
onBlur={onBlur}
|
2025-03-30 19:39:59 -03:00
|
|
|
onChange={(e) => onChange(e.target.value)}
|
2025-03-30 16:42:51 -03:00
|
|
|
value={value}
|
|
|
|
placeholder="Enter username"
|
|
|
|
/>
|
2025-03-30 19:39:59 -03:00
|
|
|
{error && <p className="text-red-500 text-xs mt-1">{error.message}</p>}
|
|
|
|
<p className="text-sm text-gray-500 mt-1">
|
2025-03-30 16:42:51 -03:00
|
|
|
This is your public display name. It can be your real name or a pseudonym. You can only change this once every 30 days.
|
2025-03-30 19:39:59 -03:00
|
|
|
</p>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
)}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Controller
|
|
|
|
control={control}
|
|
|
|
name="email"
|
|
|
|
render={({ field: { onChange, onBlur, value }, fieldState: { error } }) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="mb-4">
|
|
|
|
<label className="block text-sm font-medium mb-1">Email</label>
|
|
|
|
<input
|
|
|
|
className={`w-full p-2 border rounded ${error ? 'border-red-500' : 'border-gray-300'}`}
|
2025-03-30 16:42:51 -03:00
|
|
|
onBlur={onBlur}
|
2025-03-30 19:39:59 -03:00
|
|
|
onChange={(e) => onChange(e.target.value)}
|
2025-03-30 16:42:51 -03:00
|
|
|
value={value}
|
|
|
|
placeholder="Enter email"
|
2025-03-30 19:39:59 -03:00
|
|
|
type="email"
|
2025-03-30 16:42:51 -03:00
|
|
|
/>
|
2025-03-30 19:39:59 -03:00
|
|
|
{error && <p className="text-red-500 text-xs mt-1">{error.message}</p>}
|
|
|
|
<p className="text-sm text-gray-500 mt-1">
|
2025-03-30 16:42:51 -03:00
|
|
|
You can manage verified email addresses in your email settings.
|
2025-03-30 19:39:59 -03:00
|
|
|
</p>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
)}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Controller
|
|
|
|
control={control}
|
|
|
|
name="bio"
|
|
|
|
render={({ field: { onChange, onBlur, value }, fieldState: { error } }) => (
|
2025-03-30 19:39:59 -03:00
|
|
|
<div className="mb-4">
|
|
|
|
<label className="block text-sm font-medium mb-1">Bio</label>
|
|
|
|
<textarea
|
|
|
|
className={`w-full p-2 border rounded ${error ? 'border-red-500' : 'border-gray-300'}`}
|
2025-03-30 16:42:51 -03:00
|
|
|
onBlur={onBlur}
|
2025-03-30 19:39:59 -03:00
|
|
|
onChange={(e) => onChange(e.target.value)}
|
2025-03-30 16:42:51 -03:00
|
|
|
value={value}
|
|
|
|
placeholder="Tell us a little bit about yourself"
|
2025-03-30 19:39:59 -03:00
|
|
|
rows={4}
|
2025-03-30 16:42:51 -03:00
|
|
|
/>
|
2025-03-30 19:39:59 -03:00
|
|
|
{error && <p className="text-red-500 text-xs mt-1">{error.message}</p>}
|
|
|
|
<p className="text-sm text-gray-500 mt-1">
|
2025-03-30 16:42:51 -03:00
|
|
|
You can @mention other users and organizations to link to them.
|
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 profile
|
|
|
|
</button>
|
|
|
|
</div>
|
2025-03-30 16:42:51 -03:00
|
|
|
);
|
|
|
|
}
|