gbclient/app/settings/notifications/notifications-form.tsx

178 lines
6.2 KiB
TypeScript

import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
const notificationsFormSchema = z.object({
type: z.enum(['all', 'mentions', 'none'], {
required_error: 'You need to select a notification type.',
}),
mobile: z.boolean().default(false).optional(),
communication_emails: z.boolean().default(false).optional(),
social_emails: z.boolean().default(false).optional(),
marketing_emails: z.boolean().default(false).optional(),
security_emails: z.boolean(),
});
type NotificationsFormValues = z.infer<typeof notificationsFormSchema>;
const defaultValues: Partial<NotificationsFormValues> = {
communication_emails: false,
marketing_emails: false,
social_emails: true,
security_emails: true,
};
export function NotificationsForm() {
const { control, handleSubmit } = useForm<NotificationsFormValues>({
resolver: zodResolver(notificationsFormSchema),
defaultValues,
});
const onSubmit = (data: NotificationsFormValues) => {
console.log(JSON.stringify(data, null, 2));
};
return (
<div className="space-y-4">
<div className="mb-4">
<label className="block text-sm font-medium mb-1">Notify me about...</label>
<Controller
control={control}
name="type"
render={({ field: { onChange, value } }) => (
<div className="space-y-2">
<div className="flex items-center">
<input
type="radio"
id="all"
checked={value === 'all'}
onChange={() => onChange('all')}
className="h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<label htmlFor="all" className="ml-2">
All new messages
</label>
</div>
<div className="flex items-center">
<input
type="radio"
id="mentions"
checked={value === 'mentions'}
onChange={() => onChange('mentions')}
className="h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<label htmlFor="mentions" className="ml-2">
Direct messages and mentions
</label>
</div>
<div className="flex items-center">
<input
type="radio"
id="none"
checked={value === 'none'}
onChange={() => onChange('none')}
className="h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<label htmlFor="none" className="ml-2">
Nothing
</label>
</div>
</div>
)}
/>
</div>
<div className="mb-4">
<h3 className="text-sm font-medium mb-4">Email Notifications</h3>
<Controller
control={control}
name="communication_emails"
render={({ field: { onChange, value } }) => (
<div className="flex justify-between items-center mb-3">
<div>
<label className="text-sm font-medium">Communication emails</label>
<p className="text-sm text-gray-500">
Receive emails about your account activity.
</p>
</div>
<input
type="checkbox"
checked={value}
onChange={(e) => onChange(e.target.checked)}
className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
</div>
)}
/>
<Controller
control={control}
name="marketing_emails"
render={({ field: { onChange, value } }) => (
<div className="flex justify-between items-center mb-3">
<div>
<label className="text-sm font-medium">Marketing emails</label>
<p className="text-sm text-gray-500">
Receive emails about new products, features, and more.
</p>
</div>
<input
type="checkbox"
checked={value}
onChange={(e) => onChange(e.target.checked)}
className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
</div>
)}
/>
<Controller
control={control}
name="social_emails"
render={({ field: { onChange, value } }) => (
<div className="flex justify-between items-center mb-3">
<div>
<label className="text-sm font-medium">Social emails</label>
<p className="text-sm text-gray-500">
Receive emails for friend requests, follows, and more.
</p>
</div>
<input
type="checkbox"
checked={value}
onChange={(e) => onChange(e.target.checked)}
className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
</div>
)}
/>
<Controller
control={control}
name="security_emails"
render={({ field: { value } }) => (
<div className="flex justify-between items-center">
<div>
<label className="text-sm font-medium">Security emails</label>
<p className="text-sm text-gray-500">
Receive emails about your account activity and security.
</p>
</div>
<input
type="checkbox"
checked={value}
disabled
className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
</div>
)}
/>
</div>
<button
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
onClick={handleSubmit(onSubmit)}
>
Update notifications
</button>
</div>
);
}