open-notebook / frontend /src /components /notebooks /CreateNotebookDialog.tsx
baveshraam's picture
FIX: SurrealDB 2.0 migration syntax and Frontend/CORS link
f871fed
'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>
)
}