// Project / customer context — localStorage CRUD + switcher modal import { escHtml, uuid, formatDate } from './utils.js'; const STORAGE_KEY = 'migrator_projects'; // ── Data model ───────────────────────────────────────────────────────────── // localStorage schema: // { active: string|null, projects: Array<{ id, name, createdAt }> } function load() { try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || { active: null, projects: [] }; } catch { return { active: null, projects: [] }; } } function save(data) { localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); } export function listProjects() { return load().projects; } export function getActive() { const data = load(); return data.projects.find(p => p.id === data.active) || null; } export function createProject(name) { const data = load(); const project = { id: uuid(), name: name.trim(), createdAt: new Date().toISOString() }; data.projects.push(project); if (!data.active) data.active = project.id; save(data); return project; } export function deleteProject(id) { const data = load(); data.projects = data.projects.filter(p => p.id !== id); if (data.active === id) { data.active = data.projects[0]?.id || null; } save(data); } export function setActive(id) { const data = load(); if (data.projects.find(p => p.id === id)) { data.active = id; save(data); } } // ── Init: called on app startup ───────────────────────────────────────────── // onUpdate callback is called whenever the active project changes let _onUpdate = null; export function initProject(onUpdate) { _onUpdate = onUpdate; onUpdate(); // Show project modal on first run if no projects exist if (listProjects().length === 0) { showProjectModal(onUpdate); } } // ── Project switcher modal ───────────────────────────────────────────────── export function showProjectModal(onUpdate) { if (onUpdate) _onUpdate = onUpdate; const existing = document.getElementById('project-modal'); if (existing) existing.remove(); const wrapper = document.createElement('div'); wrapper.id = 'project-modal'; wrapper.innerHTML = ` `; document.body.appendChild(wrapper); renderProjectList(); document.getElementById('pm-close').onclick = () => wrapper.remove(); document.getElementById('pm-cancel').onclick = () => wrapper.remove(); document.getElementById('pm-create').onclick = handleCreate; document.getElementById('pm-new-name').addEventListener('keydown', e => { if (e.key === 'Enter') handleCreate(); }); // Focus name input setTimeout(() => document.getElementById('pm-new-name')?.focus(), 50); } function renderProjectList() { const list = document.getElementById('pm-project-list'); const active = getActive(); const projects = listProjects(); if (!projects.length) { list.innerHTML = `

No projects yet. Create one below to get started.

`; return; } list.innerHTML = projects.map(p => `
${escHtml(p.name.slice(0, 2).toUpperCase())}
${escHtml(p.name)}
Created ${formatDate(p.createdAt)}
${p.id === active?.id ? '● Active' : `` }
`).join(''); // Activate on row click list.querySelectorAll('.project-row').forEach(row => { row.addEventListener('click', e => { if (e.target.classList.contains('pm-delete-btn')) return; activateProject(row.dataset.id); }); }); // Delete buttons list.querySelectorAll('.pm-delete-btn').forEach(btn => { btn.addEventListener('click', e => { e.stopPropagation(); handleDelete(btn.dataset.id); }); }); } function activateProject(id) { setActive(id); if (_onUpdate) _onUpdate(); const modal = document.getElementById('project-modal'); if (modal) modal.remove(); } function handleDelete(id) { const project = listProjects().find(p => p.id === id); if (!project) return; if (!confirm(`Delete project "${project.name}"? This cannot be undone.`)) return; deleteProject(id); if (_onUpdate) _onUpdate(); renderProjectList(); } function handleCreate() { const input = document.getElementById('pm-new-name'); const errorEl = document.getElementById('pm-error'); const name = input?.value.trim(); if (!name) { if (errorEl) errorEl.textContent = 'Project name is required.'; input?.focus(); return; } if (errorEl) errorEl.textContent = ''; const project = createProject(name); setActive(project.id); if (_onUpdate) _onUpdate(); const modal = document.getElementById('project-modal'); if (modal) modal.remove(); }