// ===================================================================== // MAESTRO — Project detail drawer + Login screen // ===================================================================== const { useState: useState_dl, useEffect: useEffect_dl } = React; const D_dl = window.MAESTRO_DATA; const I_dl = window.MAESTRO_ICONS; const _cfg_dl = window.MAESTRO_CONFIG || {}; const API_BASE_DL = _cfg_dl.API_BASE || "http://localhost:8000"; function EditProjectForm({ project, onSave, onCancel }) { const [desc, setDesc] = useState_dl(project.description || ""); const [priority, setPriority] = useState_dl(project.priority || "media"); const [hours, setHours] = useState_dl(project.estimatedHours ? String(project.estimatedHours) : ""); const [deadline, setDeadline] = useState_dl(project.deadline || ""); const [fechaInicio, setFechaInicio] = useState_dl(project.fechaInicio || ""); const [responsable, setResponsable] = useState_dl(project.responsable || ""); const [specsText, setSpecsText] = useState_dl(project.specsText || ""); const [saving, setSaving] = useState_dl(false); const inputStyle = { width: "100%", boxSizing: "border-box", padding: "7px 10px", borderRadius: "var(--r-sm)", border: "1px solid var(--border)", background: "var(--bg-base)", color: "var(--text-primary)", fontSize: 13 }; const submit = async (e) => { e.preventDefault(); setSaving(true); try { await onSave({ descripcion: desc || undefined, prioridad: priority, estimated_hours: hours ? parseFloat(hours) : undefined, deadline: deadline || undefined, fecha_inicio: fechaInicio || undefined, responsable: responsable || undefined, specs_text: specsText || undefined, }); } finally { setSaving(false); } }; return (
); } const NOTE_TYPE_COLOR = { learning: "var(--accent)", decision: "var(--warning)", reflection: "var(--success)", otro: "var(--fg-subtle)" }; const NOTE_TYPE_ICON = { learning: "💡", decision: "🎯", reflection: "🔍", otro: "📝" }; function Drawer({ project, onClose, onToggleTask, onResolveBlocker, onChangeState, onEditProject, onDeleteProject, onAddHours, onAddNote, onOpenDetail, onArchiveProject, onDuplicateProject }) { const [editMode, setEditMode] = useState_dl(false); const [deleteConfirm, setDeleteConfirm] = useState_dl(false); const [showHoursForm, setShowHoursForm] = useState_dl(false); const [showNoteForm, setShowNoteForm] = useState_dl(false); const [hoursVal, setHoursVal] = useState_dl(""); const [hoursDesc, setHoursDesc] = useState_dl(""); const [noteText, setNoteText] = useState_dl(""); const [noteType, setNoteType] = useState_dl("otro"); const [savingHours, setSavingHours] = useState_dl(false); const [savingNote, setSavingNote] = useState_dl(false); useEffect_dl(() => { const onEsc = e => { if (e.key === "Escape") onClose(); }; window.addEventListener("keydown", onEsc); return () => window.removeEventListener("keydown", onEsc); }, [onClose]); if (!project) return null; const ratio = project.actualHours / project.estimatedHours; const stateClass = ratio > 1.3 ? "over" : ratio < 0.9 ? "ok" : ""; const submitHours = async (e) => { e.preventDefault(); if (!hoursVal || parseFloat(hoursVal) <= 0) return; setSavingHours(true); try { await onAddHours(project.id, parseFloat(hoursVal), hoursDesc); setHoursVal(""); setHoursDesc(""); setShowHoursForm(false); } finally { setSavingHours(false); } }; const submitNote = async (e) => { e.preventDefault(); if (!noteText.trim()) return; setSavingNote(true); try { await onAddNote(project.id, noteText.trim(), noteType); setNoteText(""); setNoteType("otro"); setShowNoteForm(false); } finally { setSavingNote(false); } }; const handleDelete = async () => { await onDeleteProject(project.id); onClose(); }; const inStyle = { padding: "7px 10px", borderRadius: "var(--r-sm)", border: "1px solid var(--border)", background: "var(--bg-base)", color: "var(--text-primary)", fontSize: 13 }; return ( <>