// Create / edit a project. Minimal modal: name, description, status. import { el } from '../dom.js'; import { api } from '../api.js'; const STATUSES = ['idea', 'active', 'paused', 'done', 'abandoned']; const slugify = (s) => (s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '').slice(0, 50) || 'project'); export function openProjectModal(spaceId, project, onSaved) { const editing = !!project; const name = el('input', { class: 'pm-input', value: project?.name || '', placeholder: 'Project name' }); const desc = el('textarea', { class: 'pm-input', rows: 3, placeholder: 'Description (optional)' }); desc.value = project?.description || ''; const status = el('select', { class: 'pm-input' }, STATUSES.map(s => el('option', { value: s, selected: s === (project?.status || 'active') }, s))); const errEl = el('div', { class: 'err', style: { minHeight: '15px' } }, ''); async function save() { const nm = name.value.trim(); if (!nm) { errEl.textContent = 'Name required'; return; } try { if (editing) { await api.patch('/api/projects/' + project.id, { name: nm, description: desc.value.trim() || null, status: status.value }); } else { await api.post(`/api/spaces/${spaceId}/projects`, { slug: slugify(nm) + '-' + Date.now().toString(36).slice(-4), name: nm, description: desc.value.trim() || undefined, status: status.value }); } modal.remove(); onSaved && onSaved(); } catch (e) { errEl.textContent = 'Save failed: ' + e.message; } } const modal = el('div', { class: 'rev-overlay', onclick: (e) => { if (e.target === modal) modal.remove(); } }, el('div', { class: 'pm-modal' }, el('div', { class: 'pm-head' }, editing ? 'Edit project' : 'New project'), el('label', { class: 'pm-label' }, 'Name'), name, el('label', { class: 'pm-label' }, 'Description'), desc, el('label', { class: 'pm-label' }, 'Status'), status, errEl, el('div', { class: 'pm-foot' }, el('button', { class: 'ghost', onclick: () => modal.remove() }, 'Cancel'), el('button', { class: 'primary', onclick: save }, editing ? 'Save' : 'Create')))); document.body.appendChild(modal); name.focus(); }