Files
Adriano b913a2bf90 registri dei piani in git (AI-OS#309)
Refs gitea:Adriano/AI-OS#310

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 10:36:26 +02:00

3.3 KiB

Files:

  • Create: src/pages/api/admin/showtags.ts
  • Modify: src/components/Header.astro (script del pulsante)

Interfaces:

  • Consumes: locals.user dal middleware (rotta sotto /api/admin, quindi login garantito).

  • Produces: POST /api/admin/showtags con body { on: boolean }; imposta/rimuove il cookie showtags; 403 se il ruolo non è superuser/admin.

  • Step 1: Crea l'endpoint

Crea src/pages/api/admin/showtags.ts:

import type { APIRoute } from 'astro';
export const prerender = false;

const json = (status: number, body: object) =>
  new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' } });

export const POST: APIRoute = async ({ request, cookies, locals }) => {
  const role = locals.user!.role;
  if (role !== 'superuser' && role !== 'admin') return json(403, { error: 'Permessi insufficienti' });
  let data: { on?: unknown };
  try { data = await request.json(); } catch { return json(400, { error: 'Dati non validi.' }); }
  if (data.on) {
    cookies.set('showtags', '1', { httpOnly: true, sameSite: 'lax', path: '/', secure: import.meta.env.PROD });
  } else {
    cookies.delete('showtags', { path: '/' });
  }
  return json(200, { on: Boolean(data.on) });
};
  • Step 2: Cabla il pulsante nell'header

In src/components/Header.astro, dentro il blocco <script> esistente (dopo il codice del burger), aggiungi:

  const tagsBtn = document.getElementById('toggle-tags');
  if (tagsBtn) {
    // Lo stato attuale è riflesso server-side; il testo lo deriviamo dal cookie.
    const on = document.cookie.split('; ').some((c) => c === 'showtags=1');
    tagsBtn.textContent = on ? 'Nascondi tag' : 'Mostra tag';
    tagsBtn.addEventListener('click', async () => {
      const res = await fetch('/api/admin/showtags', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ on: !on }),
      });
      if (res.ok) location.reload();
      else alert('Operazione non riuscita.');
    });
  }

Nota: il cookie showtags è httpOnly, quindi document.cookie non lo espone. Per riflettere lo stato senza reload, l'header riceve già showTags come prop: passa lo stato al pulsante via attributo. Correzione da applicare in questo step — nel markup del Task 8 il pulsante diventa:

<button type="button" class="umenu__tags" id="toggle-tags" data-on={Astro.props.showTags ? '1' : '0'}>{Astro.props.showTags ? 'Nascondi tag' : 'Mostra tag'}</button>

e lo script usa data-on:

  const tagsBtn = document.getElementById('toggle-tags');
  if (tagsBtn) {
    const on = tagsBtn.dataset.on === '1';
    tagsBtn.addEventListener('click', async () => {
      const res = await fetch('/api/admin/showtags', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ on: !on }),
      });
      if (res.ok) location.reload();
      else alert('Operazione non riuscita.');
    });
  }
  • Step 3: Verifica build

Run: npm run build Expected: build OK.

  • Step 4: Commit
git add src/pages/api/admin/showtags.ts src/components/Header.astro
git commit -m "feat(showtags): endpoint cookie + toggle nel menu utente"