/* eslint-disable */ /* timing-projects.jsx — панель «Проекты»: список сохранённых таймингов с открытием, созданием, переименованием и удалением. Работает через window.TimingAuth.api (с прозрачным офлайн-фолбэком на localStorage в превью). */ (function () { const R = window.React; const { useState, useEffect } = R; const A = window.TimingAuth; function fmtDate(iso) { if (!iso) return '—'; try { const d = new Date(iso); const date = d.toLocaleDateString('ru-RU', { day: '2-digit', month: 'short', year: 'numeric' }); const time = d.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); return date + ', ' + time; } catch (e) { return '—'; } } function ProjectsPanel({ onClose, onOpen, onNew, currentId }) { const [list, setList] = useState(null); const [renaming, setRenaming] = useState(null); const [renameVal, setRenameVal] = useState(''); const [confirmDel, setConfirmDel] = useState(null); const [working, setWorking] = useState(false); async function refresh() { const l = await A.api.list(); setList(Array.isArray(l) ? l : []); } useEffect(() => { refresh(); }, []); async function doOpen(p) { setWorking(true); const full = await A.api.get(p.id); setWorking(false); if (full && full.data) onOpen(full); else alert('Не удалось загрузить проект'); } async function doRename(p) { const t = (renameVal || '').trim(); setRenaming(null); if (!t || t === p.title) return; await A.api.update(p.id, { title: t }); refresh(); } async function doDelete(p) { await A.api.del(p.id); setConfirmDel(null); refresh(); } const iconBtn = (danger) => ({ width: 30, height: 30, borderRadius: 'var(--radius-input)', border: '1px solid var(--color-line-subtle)', background: 'var(--color-surface)', color: danger ? 'var(--color-danger-700)' : 'var(--color-ink-500)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', }); return ReactDOM.createPortal(