b913a2bf90
Refs gitea:Adriano/AI-OS#310 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
3.3 KiB
3.3 KiB
Task 9: Toggle "Mostra tag" — endpoint cookie e cablaggio
Files:
- Create:
src/pages/api/admin/showtags.ts - Modify:
src/components/Header.astro(script del pulsante)
Interfaces:
-
Consumes:
locals.userdal middleware (rotta sotto/api/admin, quindi login garantito). -
Produces:
POST /api/admin/showtagscon body{ on: boolean }; imposta/rimuove il cookieshowtags;403se 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"