Spaces:
Running
Running
| 'use client' | |
| import { useEffect } from 'react' | |
| import { useForm } from 'react-hook-form' | |
| import { zodResolver } from '@hookform/resolvers/zod' | |
| import { z } from 'zod' | |
| import { | |
| Dialog, | |
| DialogContent, | |
| DialogDescription, | |
| DialogFooter, | |
| DialogHeader, | |
| DialogTitle, | |
| } from '@/components/ui/dialog' | |
| import { Button } from '@/components/ui/button' | |
| import { Input } from '@/components/ui/input' | |
| import { Textarea } from '@/components/ui/textarea' | |
| import { Label } from '@/components/ui/label' | |
| import { useCreateNotebook } from '@/lib/hooks/use-notebooks' | |
| const createNotebookSchema = z.object({ | |
| name: z.string().min(1, 'Name is required'), | |
| description: z.string().optional(), | |
| }) | |
| type CreateNotebookFormData = z.infer<typeof createNotebookSchema> | |
| interface CreateNotebookDialogProps { | |
| open: boolean | |
| onOpenChange: (open: boolean) => void | |
| } | |
| export function CreateNotebookDialog({ open, onOpenChange }: CreateNotebookDialogProps) { | |
| const createNotebook = useCreateNotebook() | |
| const { | |
| register, | |
| handleSubmit, | |
| formState: { errors, isValid }, | |
| reset, | |
| } = useForm<CreateNotebookFormData>({ | |
| resolver: zodResolver(createNotebookSchema), | |
| mode: 'onChange', | |
| defaultValues: { | |
| name: '', | |
| description: '', | |
| }, | |
| }) | |
| const closeDialog = () => onOpenChange(false) | |
| const onSubmit = async (data: CreateNotebookFormData) => { | |
| await createNotebook.mutateAsync(data) | |
| closeDialog() | |
| reset() | |
| } | |
| useEffect(() => { | |
| if (!open) { | |
| reset() | |
| } | |
| }, [open, reset]) | |
| return ( | |
| <Dialog open={open} onOpenChange={onOpenChange}> | |
| <DialogContent className="sm:max-w-[480px]"> | |
| <DialogHeader> | |
| <DialogTitle>Create New Notebook</DialogTitle> | |
| <DialogDescription> | |
| Start organizing your research with a dedicated space for related sources and notes. | |
| </DialogDescription> | |
| </DialogHeader> | |
| <form onSubmit={handleSubmit(onSubmit)} className="space-y-4"> | |
| <div className="space-y-2"> | |
| <Label htmlFor="notebook-name">Name *</Label> | |
| <Input | |
| id="notebook-name" | |
| {...register('name')} | |
| placeholder="Enter notebook name" | |
| autoFocus | |
| /> | |
| {errors.name && ( | |
| <p className="text-sm text-destructive">{errors.name.message}</p> | |
| )} | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="notebook-description">Description</Label> | |
| <Textarea | |
| id="notebook-description" | |
| {...register('description')} | |
| placeholder="Describe the purpose and scope of this notebook..." | |
| rows={4} | |
| /> | |
| </div> | |
| <DialogFooter className="gap-2 sm:gap-0"> | |
| <Button type="button" variant="outline" onClick={closeDialog}> | |
| Cancel | |
| </Button> | |
| <Button type="submit" disabled={!isValid || createNotebook.isPending}> | |
| {createNotebook.isPending ? 'Creating…' : 'Create Notebook'} | |
| </Button> | |
| </DialogFooter> | |
| </form> | |
| </DialogContent> | |
| </Dialog> | |
| ) | |
| } | |