import { useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { FolderKanban, Loader2, Plus, Trash2, Edit3, Archive, ListTodo, Package, Layers, Clock, CheckCircle2, AlertTriangle, ChevronRight, MoreVertical, Download, Upload, } from 'lucide-react'; import { api } from '../api/client'; import type { ProjectListItem, ProjectCreate, ProjectUpdate, ProjectImport, Permission } from '../api/client'; import { Button } from '../components/Button'; import { ConfirmModal } from '../components/ConfirmModal'; import { useToast } from '../contexts/ToastContext'; import { useAuth } from '../contexts/AuthContext'; import { getCurrencySymbol } from '../utils/currency'; const PROJECT_COLORS = [ '#ef4444', // red '#f97316', // orange '#eab308', // yellow '#22c55e', // green '#06b6d4', // cyan '#3b82f6', // blue '#8b5cf6', // violet '#ec4899', // pink '#6b7280', // gray ]; type TFunction = (key: string, options?: Record) => string; interface ProjectModalProps { project?: ProjectListItem; onClose: () => void; onSave: (data: ProjectCreate | ProjectUpdate) => void; isLoading: boolean; currencySymbol: string; t: TFunction; } export function ProjectModal({ project, onClose, onSave, isLoading, currencySymbol, t }: ProjectModalProps) { const [name, setName] = useState(project?.name || ''); const [description, setDescription] = useState(project?.description || ''); const [color, setColor] = useState(project?.color || PROJECT_COLORS[0]); const [targetCount, setTargetCount] = useState(project?.target_count?.toString() || ''); const [targetPartsCount, setTargetPartsCount] = useState(project?.target_parts_count?.toString() || ''); const [status, setStatus] = useState(project?.status || 'active'); const [tags, setTags] = useState((project as ProjectListItem & { tags?: string })?.tags || ''); const [dueDate, setDueDate] = useState((project as ProjectListItem & { due_date?: string })?.due_date?.split('T')[0] || ''); const [priority, setPriority] = useState((project as ProjectListItem & { priority?: string })?.priority || 'normal'); const [budget, setBudget] = useState(project?.budget?.toString() || ''); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSave({ name: name.trim(), description: description.trim() || undefined, color, target_count: targetCount ? parseInt(targetCount, 10) : undefined, target_parts_count: targetPartsCount ? parseInt(targetPartsCount, 10) : undefined, tags: tags.trim() || undefined, due_date: dueDate || undefined, priority, budget: budget.trim() ? parseFloat(budget) : null, ...(project && { status }), }); }; return (

{project ? t('projects.editProject') : t('projects.newProject')}

setName(e.target.value)} className="w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green" placeholder={t('projects.namePlaceholder')} required />