'use client' import { useState, useEffect, useMemo } from 'react' import { LoaderIcon, BookOpen, Check } from 'lucide-react' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { ScrollArea } from '@/components/ui/scroll-area' import { useNotebooks } from '@/lib/hooks/use-notebooks' import { useAddSourcesToNotebook, useRemoveSourceFromNotebook } from '@/lib/hooks/use-sources' interface NotebookAssociationsProps { sourceId: string currentNotebookIds: string[] onSave?: () => void } export function NotebookAssociations({ sourceId, currentNotebookIds, onSave, }: NotebookAssociationsProps) { const [selectedNotebookIds, setSelectedNotebookIds] = useState(currentNotebookIds) const [isSaving, setIsSaving] = useState(false) const { data: notebooks, isLoading } = useNotebooks() const addSources = useAddSourcesToNotebook() const removeFromNotebook = useRemoveSourceFromNotebook() // Update selected notebooks when current changes (after save) useEffect(() => { setSelectedNotebookIds(currentNotebookIds) }, [currentNotebookIds]) const hasChanges = useMemo(() => { const current = new Set(currentNotebookIds) const selected = new Set(selectedNotebookIds) if (current.size !== selected.size) return true for (const id of current) { if (!selected.has(id)) return true } return false }, [currentNotebookIds, selectedNotebookIds]) const handleToggleNotebook = (notebookId: string) => { setSelectedNotebookIds(prev => prev.includes(notebookId) ? prev.filter(id => id !== notebookId) : [...prev, notebookId] ) } const handleSave = async () => { if (!hasChanges) return try { setIsSaving(true) const current = new Set(currentNotebookIds) const selected = new Set(selectedNotebookIds) // Determine which notebooks to add and remove const toAdd = selectedNotebookIds.filter(id => !current.has(id)) const toRemove = currentNotebookIds.filter(id => !selected.has(id)) // Execute additions if (toAdd.length > 0) { await Promise.allSettled( toAdd.map(notebookId => addSources.mutateAsync({ notebookId, sourceIds: [sourceId], }) ) ) } // Execute removals if (toRemove.length > 0) { await Promise.allSettled( toRemove.map(notebookId => removeFromNotebook.mutateAsync({ notebookId, sourceId, }) ) ) } onSave?.() } catch (error) { console.error('Error saving notebook associations:', error) } finally { setIsSaving(false) } } const handleCancel = () => { setSelectedNotebookIds(currentNotebookIds) } if (isLoading) { return ( Notebooks Manage which notebooks contain this source
) } if (!notebooks || notebooks.length === 0) { return ( Notebooks Manage which notebooks contain this source

No notebooks available

) } return ( Notebooks Manage which notebooks contain this source
{notebooks .filter(nb => !nb.archived) .map((notebook) => { const isSelected = selectedNotebookIds.includes(notebook.id) const isCurrentlyLinked = currentNotebookIds.includes(notebook.id) return (
handleToggleNotebook(notebook.id)} className="mt-0.5" />

{notebook.name}

{isCurrentlyLinked && !hasChanges && ( )}
{notebook.description && (

{notebook.description}

)}
) })}
{hasChanges && (
)}
) }