'use client' import { useEffect, useState } from 'react' import { nanoid } from 'nanoid' import { createClient } from '@/lib/supabase/client' import type { Character, Variable } from '@/types/flowchart' type ImportMode = 'characters' | 'variables' type ProjectListItem = { id: string name: string } type ImportFromProjectModalProps = { mode: ImportMode currentProjectId: string existingCharacters: Character[] existingVariables: Variable[] onImportCharacters: (characters: Character[]) => void onImportVariables: (variables: Variable[]) => void onClose: () => void } export default function ImportFromProjectModal({ mode, currentProjectId, existingCharacters, existingVariables, onImportCharacters, onImportVariables, onClose, }: ImportFromProjectModalProps) { const [projects, setProjects] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [selectedProjectId, setSelectedProjectId] = useState(null) const [sourceCharacters, setSourceCharacters] = useState([]) const [sourceVariables, setSourceVariables] = useState([]) const [loadingSource, setLoadingSource] = useState(false) const [selectedIds, setSelectedIds] = useState>(new Set()) const [warnings, setWarnings] = useState([]) // Load user's projects on mount useEffect(() => { async function fetchProjects() { const supabase = createClient() const { data, error: fetchError } = await supabase .from('projects') .select('id, name') .neq('id', currentProjectId) .order('name') if (fetchError) { setError('Failed to load projects') setLoading(false) return } setProjects(data || []) setLoading(false) } fetchProjects() }, [currentProjectId]) // Load source project's characters/variables when a project is selected const handleSelectProject = async (projectId: string) => { setSelectedProjectId(projectId) setLoadingSource(true) setWarnings([]) setSelectedIds(new Set()) const supabase = createClient() const { data, error: fetchError } = await supabase .from('projects') .select('flowchart_data') .eq('id', projectId) .single() if (fetchError || !data) { setError('Failed to load project data') setLoadingSource(false) return } const flowchartData = data.flowchart_data || {} const chars: Character[] = flowchartData.characters || [] const vars: Variable[] = flowchartData.variables || [] setSourceCharacters(chars) setSourceVariables(vars) setLoadingSource(false) // Select all by default const items = mode === 'characters' ? chars : vars setSelectedIds(new Set(items.map((item) => item.id))) } const handleToggleItem = (id: string) => { setSelectedIds((prev) => { const next = new Set(prev) if (next.has(id)) { next.delete(id) } else { next.add(id) } return next }) } const handleSelectAll = () => { const items = mode === 'characters' ? sourceCharacters : sourceVariables setSelectedIds(new Set(items.map((item) => item.id))) } const handleSelectNone = () => { setSelectedIds(new Set()) } const handleImport = () => { const importWarnings: string[] = [] if (mode === 'characters') { const selectedCharacters = sourceCharacters.filter((c) => selectedIds.has(c.id)) const existingNames = new Set(existingCharacters.map((c) => c.name.toLowerCase())) const toImport: Character[] = [] for (const char of selectedCharacters) { if (existingNames.has(char.name.toLowerCase())) { importWarnings.push(`Skipped "${char.name}" (already exists)`) } else { // Create new ID to avoid conflicts toImport.push({ ...char, id: nanoid() }) existingNames.add(char.name.toLowerCase()) } } if (importWarnings.length > 0) { setWarnings(importWarnings) } if (toImport.length > 0) { onImportCharacters(toImport) } if (importWarnings.length === 0) { onClose() } } else { const selectedVariables = sourceVariables.filter((v) => selectedIds.has(v.id)) const existingNames = new Set(existingVariables.map((v) => v.name.toLowerCase())) const toImport: Variable[] = [] for (const variable of selectedVariables) { if (existingNames.has(variable.name.toLowerCase())) { importWarnings.push(`Skipped "${variable.name}" (already exists)`) } else { // Create new ID to avoid conflicts toImport.push({ ...variable, id: nanoid() }) existingNames.add(variable.name.toLowerCase()) } } if (importWarnings.length > 0) { setWarnings(importWarnings) } if (toImport.length > 0) { onImportVariables(toImport) } if (importWarnings.length === 0) { onClose() } } } const items = mode === 'characters' ? sourceCharacters : sourceVariables return (