180 lines
6.2 KiB
TypeScript
180 lines
6.2 KiB
TypeScript
"use client";
|
|
|
|
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>
|
|
);
|
|
}
|