diff options
Diffstat (limited to 'makima/frontend/src/components/templates/TemplateEditor.tsx')
| -rw-r--r-- | makima/frontend/src/components/templates/TemplateEditor.tsx | 257 |
1 files changed, 0 insertions, 257 deletions
diff --git a/makima/frontend/src/components/templates/TemplateEditor.tsx b/makima/frontend/src/components/templates/TemplateEditor.tsx deleted file mode 100644 index c8e1f98..0000000 --- a/makima/frontend/src/components/templates/TemplateEditor.tsx +++ /dev/null @@ -1,257 +0,0 @@ -import { useState } from "react"; -import type { ContractTemplate, Phase, Deliverable } from "../../types/templates"; - -interface Props { - template: ContractTemplate; - onSave: (template: ContractTemplate) => void; - onCancel: () => void; - readOnly?: boolean; -} - -export function TemplateEditor({ template, onSave, onCancel, readOnly = false }: Props) { - const [editedTemplate, setEditedTemplate] = useState<ContractTemplate>({ - ...template, - phases: template.phases.map((p) => ({ - ...p, - deliverables: [...p.deliverables], - })), - }); - const [newDeliverableName, setNewDeliverableName] = useState<{ - [phaseId: string]: string; - }>({}); - - const handlePhaseNameChange = (phaseId: string, newName: string) => { - setEditedTemplate((prev) => ({ - ...prev, - phases: prev.phases.map((p) => - p.id === phaseId ? { ...p, name: newName } : p - ), - })); - }; - - const handleDeliverableNameChange = ( - phaseId: string, - deliverableId: string, - newName: string - ) => { - setEditedTemplate((prev) => ({ - ...prev, - phases: prev.phases.map((p) => - p.id === phaseId - ? { - ...p, - deliverables: p.deliverables.map((d) => - d.id === deliverableId ? { ...d, name: newName } : d - ), - } - : p - ), - })); - }; - - const handleAddDeliverable = (phaseId: string) => { - const name = newDeliverableName[phaseId]?.trim(); - if (!name) return; - - const newDeliverable: Deliverable = { - id: `deliverable-${Date.now()}`, - name, - }; - - setEditedTemplate((prev) => ({ - ...prev, - phases: prev.phases.map((p) => - p.id === phaseId - ? { ...p, deliverables: [...p.deliverables, newDeliverable] } - : p - ), - })); - setNewDeliverableName((prev) => ({ ...prev, [phaseId]: "" })); - }; - - const handleRemoveDeliverable = (phaseId: string, deliverableId: string) => { - setEditedTemplate((prev) => ({ - ...prev, - phases: prev.phases.map((p) => - p.id === phaseId - ? { - ...p, - deliverables: p.deliverables.filter((d) => d.id !== deliverableId), - } - : p - ), - })); - }; - - const handleAddPhase = () => { - const newPhase: Phase = { - id: `phase-${Date.now()}`, - name: "New Phase", - deliverables: [], - }; - setEditedTemplate((prev) => ({ - ...prev, - phases: [...prev.phases, newPhase], - })); - }; - - const handleRemovePhase = (phaseId: string) => { - setEditedTemplate((prev) => ({ - ...prev, - phases: prev.phases.filter((p) => p.id !== phaseId), - })); - }; - - return ( - <div className="bg-[#0d1b2d] border border-[rgba(117,170,252,0.35)] p-6"> - {/* Header */} - <div className="mb-6 pb-4 border-b border-[rgba(117,170,252,0.15)]"> - <h2 className="text-sm font-mono uppercase tracking-wide text-[#9bc3ff] mb-1"> - {readOnly ? "View" : "Edit"} Template: {template.name} - </h2> - <p className="text-xs font-mono text-[#75aafc] opacity-70"> - {template.description} - </p> - {readOnly && ( - <p className="text-xs font-mono text-amber-400 mt-2"> - Built-in templates are read-only - </p> - )} - </div> - - {/* Phases */} - <div className="space-y-4 mb-6"> - {editedTemplate.phases.map((phase, phaseIndex) => ( - <div - key={phase.id} - className="bg-[rgba(0,0,0,0.3)] border border-[rgba(117,170,252,0.2)] p-4" - > - {/* Phase Header */} - <div className="flex items-center gap-3 mb-3"> - <span className="w-6 h-6 flex items-center justify-center bg-[rgba(117,170,252,0.2)] text-[#9bc3ff] text-xs font-mono"> - {phaseIndex + 1} - </span> - <input - type="text" - className="flex-1 px-3 py-1.5 bg-transparent border border-[rgba(117,170,252,0.25)] text-white font-mono text-sm placeholder-[#556677] focus:outline-none focus:border-[#3f6fb3] disabled:opacity-60" - value={phase.name} - onChange={(e) => handlePhaseNameChange(phase.id, e.target.value)} - placeholder="Phase name" - disabled={readOnly} - /> - {!template.isBuiltIn && ( - <button - type="button" - onClick={() => handleRemovePhase(phase.id)} - className="w-7 h-7 flex items-center justify-center border border-[rgba(255,100,100,0.3)] text-[#ff6464] hover:bg-[rgba(255,100,100,0.1)] transition-colors text-sm" - title="Remove phase" - > - x - </button> - )} - </div> - - {/* Deliverables */} - <div className="ml-9 space-y-2"> - {phase.deliverables.length === 0 ? ( - <div className="text-xs font-mono text-[#556677] italic"> - No deliverables - </div> - ) : ( - phase.deliverables.map((deliverable) => ( - <div - key={deliverable.id} - className="flex items-center gap-2" - > - <span className="text-[#75aafc] text-xs">-</span> - <input - type="text" - className="flex-1 px-2 py-1 bg-transparent border border-[rgba(117,170,252,0.15)] text-[#dbe7ff] font-mono text-xs focus:outline-none focus:border-[#3f6fb3]" - value={deliverable.name} - onChange={(e) => - handleDeliverableNameChange( - phase.id, - deliverable.id, - e.target.value - ) - } - /> - <button - type="button" - onClick={() => - handleRemoveDeliverable(phase.id, deliverable.id) - } - className="w-5 h-5 flex items-center justify-center text-[#ff6464] hover:bg-[rgba(255,100,100,0.1)] transition-colors text-xs" - title="Remove deliverable" - > - x - </button> - </div> - )) - )} - - {/* Add Deliverable */} - <div className="flex items-center gap-2 pt-2"> - <input - type="text" - className="flex-1 px-2 py-1 bg-transparent border border-[rgba(117,170,252,0.15)] text-[#dbe7ff] font-mono text-xs placeholder-[#445566] focus:outline-none focus:border-[#3f6fb3]" - placeholder="New deliverable name..." - value={newDeliverableName[phase.id] || ""} - onChange={(e) => - setNewDeliverableName((prev) => ({ - ...prev, - [phase.id]: e.target.value, - })) - } - onKeyPress={(e) => { - if (e.key === "Enter") { - handleAddDeliverable(phase.id); - } - }} - /> - <button - type="button" - onClick={() => handleAddDeliverable(phase.id)} - className="px-2 py-1 border border-[rgba(117,170,252,0.3)] text-[#9bc3ff] font-mono text-xs hover:border-[#3f6fb3] hover:bg-[rgba(117,170,252,0.1)] transition-colors" - > - + Add - </button> - </div> - </div> - </div> - ))} - </div> - - {/* Add Phase (only for custom templates) */} - {!template.isBuiltIn && ( - <button - type="button" - onClick={handleAddPhase} - className="w-full mb-6 px-4 py-2 border border-dashed border-[rgba(117,170,252,0.3)] text-[#9bc3ff] font-mono text-xs uppercase tracking-wide hover:border-[#3f6fb3] hover:bg-[rgba(117,170,252,0.05)] transition-colors" - > - + Add Phase - </button> - )} - - {/* Footer Actions */} - <div className="flex gap-3 justify-end pt-4 border-t border-[rgba(117,170,252,0.15)]"> - <button - type="button" - onClick={onCancel} - className="px-4 py-2 border border-[rgba(117,170,252,0.25)] text-[#9bc3ff] font-mono text-xs uppercase tracking-wide hover:border-[#3f6fb3] transition-colors" - > - {readOnly ? "Close" : "Cancel"} - </button> - {!readOnly && ( - <button - type="button" - onClick={() => onSave(editedTemplate)} - className="px-4 py-2 border border-[#3f6fb3] bg-[rgba(117,170,252,0.15)] text-[#9bc3ff] font-mono text-xs uppercase tracking-wide hover:bg-[rgba(117,170,252,0.25)] transition-colors" - > - Save Changes - </button> - )} - </div> - </div> - ); -} |
