Mer neon i appen, mobiltilpasning og gruppert søkbar planoversikt

- Neon-tema trukket videre inn i hoved-GUI: animert topp-stripe, glødende
  panel-kanter/overskrifter, KPI-glød, fokus-glød på input, kort-hover.
- Mobil (≤600px): fjerner horisontal overflyt — planner-header, filtre,
  hurtig-add, planoversikt-panel, admin-skjema og skuff fyller/wrapper bredden.
- Planvelger → «📋 Planoversikt (N)»: gruppert i I dag/Kommende/Tidligere med
  relative datoer, søk på navn/dato/person, markerer aktiv plan.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jon Vanvik 2026-06-15 15:09:57 +02:00
parent 3f69cd4248
commit 4f24592dd0
2 changed files with 127 additions and 24 deletions

View file

@ -795,6 +795,10 @@ function renderPlan() {
$('plan-shared').disabled = !own;
$('plan-shared').closest('.plan-share').style.display = own ? '' : 'none';
$('plan-move').style.display = own ? '' : 'none';
const nPlans = derivePlanList().length;
$('plan-picker-btn').textContent = `📋 Planoversikt${nPlans ? ` (${nPlans})` : ''}`;
// Hold panelet oppdatert hvis det er åpent
if ($('plan-picker-panel').classList.contains('open')) renderPlanPicker($('plan-picker-search').value);
populatePlanUserSelect();
// Lesemodus-banner når man ser en annens plan
@ -865,27 +869,50 @@ function derivePlanList() {
});
}
function planDateLabel(date) {
const today = todayISO();
if (date === today) return 'I dag';
if (date === todayISO(1)) return 'I morgen';
if (date === todayISO(-1)) return 'I går';
const diff = Math.round((new Date(date) - new Date(today)) / 86400000);
if (diff > 1 && diff <= 7) return `om ${diff} dager`;
if (diff < -1 && diff >= -7) return `${Math.abs(diff)} dager siden`;
return date;
}
function planPickRow(p) {
const me = p.user === state.user;
const cur = p.user === state.plan.viewUser && p.date === state.plan.date;
return `<div class="plan-pick-row${cur ? ' current' : ''}" onclick="pickPlan('${escapeHtml(p.user)}','${p.date}')">
<span class="pp-date">${planDateLabel(p.date)}</span>
<span class="pp-name ${p.name ? '' : 'unnamed'}">${p.name ? escapeHtml(p.name) : '(uten navn)'}</span>
<span class="pp-who ${me ? 'me' : ''}">${me ? 'meg' : escapeHtml(p.user)}</span>
<span class="pp-count" title="oppgaver">${p.count}</span>
</div>`;
}
function renderPlanPicker(filter = '') {
const q = filter.trim().toLowerCase();
const list = derivePlanList().filter(p => {
if (!q) return true;
return [p.name, p.date, p.user === state.user ? 'meg' : p.user].join(' ').toLowerCase().includes(q);
return [p.name, p.date, planDateLabel(p.date), p.user === state.user ? 'meg' : p.user].join(' ').toLowerCase().includes(q);
});
const el = $('plan-picker-list');
if (!list.length) {
el.innerHTML = `<div class="plan-pick-empty">${q ? 'Ingen planer matcher søket.' : 'Ingen planer ennå.'}</div>`;
el.innerHTML = `<div class="plan-pick-empty">${q ? 'Ingen planer matcher søket.' : 'Ingen planer ennå — lag en ved å legge oppgaver i dagens plan.'}</div>`;
return;
}
el.innerHTML = list.map(p => {
const me = p.user === state.user;
const d = p.date.slice(8, 10) + '.' + p.date.slice(5, 7) + '.' + p.date.slice(0, 4);
return `<div class="plan-pick-row" onclick="pickPlan('${escapeHtml(p.user)}','${p.date}')">
<span class="pp-date">${d}</span>
<span class="pp-name ${p.name ? '' : 'unnamed'}">${p.name ? escapeHtml(p.name) : '(uten navn)'}</span>
<span class="pp-who ${me ? 'me' : ''}">${me ? 'meg' : escapeHtml(p.user)}</span>
<span class="pp-count">${p.count}</span>
</div>`;
}).join('');
const today = todayISO();
const groups = { today: [], upcoming: [], past: [] };
for (const p of list) {
if (p.date === today) groups.today.push(p);
else if (p.date > today) groups.upcoming.push(p);
else groups.past.push(p);
}
groups.upcoming.sort((a, b) => a.date.localeCompare(b.date)); // nærmeste først
groups.past.sort((a, b) => b.date.localeCompare(a.date)); // nyeste fortid først
const section = (title, arr) => arr.length ? `<div class="pp-group">${title}</div>` + arr.map(planPickRow).join('') : '';
el.innerHTML = section('I dag', groups.today) + section('Kommende', groups.upcoming) + section('Tidligere', groups.past);
}
function togglePlanPicker(open) {