'use client'; import { useCallback, useEffect, useState } from 'react'; import Link from 'next/link'; import style from '@/styles/admin.module.scss'; type GuideRow = { id: number; title: string; description: string | null; youtube_id: string; }; export function GuideAdminClient() { const [items, setItems] = useState([]); const [error, setError] = useState(''); const [loading, setLoading] = useState(true); const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); const [youtubeId, setYoutubeId] = useState(''); const load = useCallback(async () => { setError(''); const res = await fetch('/api/admin/guide', { credentials: 'include' }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Failed to load'); setLoading(false); return; } setItems((data as { items: GuideRow[] }).items ?? []); setLoading(false); }, []); useEffect(() => { load(); }, [load]); function updateLocal(id: number, patch: Partial) { setItems((prev) => prev.map((r) => (r.id === id ? { ...r, ...patch } : r))); } async function save(row: GuideRow) { setError(''); const res = await fetch(`/api/admin/guide/${row.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ title: row.title, description: row.description ?? '', youtube_id: row.youtube_id, }), }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Save failed'); return; } await load(); } async function remove(id: number) { if (!window.confirm('Delete this entry?')) return; setError(''); const res = await fetch(`/api/admin/guide/${id}`, { method: 'DELETE', credentials: 'include' }); if (!res.ok) { const data = await res.json().catch(() => ({})); setError((data as { error?: string }).error ?? 'Delete failed'); return; } await load(); } async function add(e: React.FormEvent) { e.preventDefault(); setError(''); const res = await fetch('/api/admin/guide', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ title, description, youtube_id: youtubeId }), }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Create failed'); return; } setTitle(''); setDescription(''); setYoutubeId(''); await load(); } return (

← Dashboard

Guide

{error ?

{error}

: null} {loading ?

Loading…

: null} {!loading && items.map((row) => (