import { useState } from 'react' import { PrismaModel, PrismaField } from '@/types/project' import { Card } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Switch } from '@/components/ui/switch' import { ScrollArea } from '@/components/ui/scroll-area' import { Plus, Trash, Database, Sparkle, Lightbulb } from '@phosphor-icons/react' import { Badge } from '@/components/ui/badge' import { AIService } from '@/lib/ai-service' import { toast } from 'sonner' interface ModelDesignerProps { models: PrismaModel[] onModelsChange: (models: PrismaModel[]) => void } const FIELD_TYPES = [ 'String', 'Int', 'Float', 'Boolean', 'DateTime', 'Json', 'Bytes', ] export function ModelDesigner({ models, onModelsChange }: ModelDesignerProps) { const [selectedModelId, setSelectedModelId] = useState( models[0]?.id || null ) const selectedModel = models.find((m) => m.id === selectedModelId) const addModel = () => { const newModel: PrismaModel = { id: `model-${Date.now()}`, name: `Model${models.length + 1}`, fields: [ { id: `field-${Date.now()}`, name: 'id', type: 'String', isRequired: true, isUnique: true, isArray: false, defaultValue: 'cuid()', }, ], } onModelsChange([...models, newModel]) setSelectedModelId(newModel.id) } const deleteModel = (modelId: string) => { const newModels = models.filter((m) => m.id !== modelId) onModelsChange(newModels) if (selectedModelId === modelId) { setSelectedModelId(newModels[0]?.id || null) } } const updateModel = (modelId: string, updates: Partial) => { onModelsChange( models.map((m) => (m.id === modelId ? { ...m, ...updates } : m)) ) } const addField = () => { if (!selectedModel) return const newField: PrismaField = { id: `field-${Date.now()}`, name: `field${selectedModel.fields.length + 1}`, type: 'String', isRequired: false, isUnique: false, isArray: false, } updateModel(selectedModel.id, { fields: [...selectedModel.fields, newField], }) } const updateField = (fieldId: string, updates: Partial) => { if (!selectedModel) return updateModel(selectedModel.id, { fields: selectedModel.fields.map((f) => f.id === fieldId ? { ...f, ...updates } : f ), }) } const deleteField = (fieldId: string) => { if (!selectedModel) return updateModel(selectedModel.id, { fields: selectedModel.fields.filter((f) => f.id !== fieldId), }) } const generateModelWithAI = async () => { const description = prompt('Describe the database model you want to create:') if (!description) return try { toast.info('Generating model with AI...') const model = await AIService.generatePrismaModel(description, models) if (model) { onModelsChange([...models, model]) setSelectedModelId(model.id) toast.success(`Model "${model.name}" created successfully!`) } else { toast.error('AI generation failed. Please try again.') } } catch (error) { toast.error('Failed to generate model') console.error(error) } } const suggestFields = async () => { if (!selectedModel) return try { toast.info('Getting field suggestions...') const existingFieldNames = selectedModel.fields.map(f => f.name) const suggestions = await AIService.suggestFieldsForModel(selectedModel.name, existingFieldNames) if (suggestions && suggestions.length > 0) { const newFields: PrismaField[] = suggestions.map((fieldName, index) => ({ id: `field-${Date.now()}-${index}`, name: fieldName, type: 'String', isRequired: false, isUnique: false, isArray: false, })) updateModel(selectedModel.id, { fields: [...selectedModel.fields, ...newFields], }) toast.success(`Added ${suggestions.length} suggested fields!`) } else { toast.error('No suggestions available') } } catch (error) { toast.error('Failed to get suggestions') console.error(error) } } return (

Models

{models.map((model) => ( ))}
{selectedModel ? (
updateModel(selectedModel.id, { name: e.target.value }) } className="text-lg font-semibold" />

Fields

{selectedModel.fields.map((field) => (
updateField(field.id, { name: e.target.value }) } />
updateField(field.id, { isRequired: checked }) } />
updateField(field.id, { isUnique: checked }) } />
updateField(field.id, { isArray: checked }) } />
updateField(field.id, { defaultValue: e.target.value, }) } placeholder="e.g., now(), cuid(), autoincrement()" />
))}
) : (

Create a model to get started

)}
) }