fix: admin menu fetch and add item — use /api/admin/menu endpoint, parse response.data correctly
This commit is contained in:
+22
-5
@@ -646,13 +646,30 @@ function MenuSection({ items, setItems, images, onToast }: any) {
|
||||
const [overIdx, setOverIdx] = useState<number | null>(null);
|
||||
|
||||
const save = async (item: MenuItem) => {
|
||||
if (!item.category || !item.name || !item.price) {
|
||||
onToast('Category, name, and price are required', 'error');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await fetch(`/api/menu/${item.id}`, {
|
||||
const url = item.id ? `/api/menu/${item.id}` : '/api/menu/';
|
||||
const res = await fetch(url, {
|
||||
method: item.id ? 'PUT' : 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(item),
|
||||
});
|
||||
if (res.ok) { setEditing(null); setItems((i: any) => i.map((x: any) => x.id === item.id ? item : x)); onToast('Menu item saved!', 'success'); }
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
setEditing(null);
|
||||
if (item.id) {
|
||||
setItems((i: any) => i.map((x: any) => x.id === item.id ? data.data : x));
|
||||
} else {
|
||||
setItems((i: any) => [...i, data.data]);
|
||||
}
|
||||
onToast('Menu item saved!', 'success');
|
||||
} else {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
onToast(err.error || 'Failed to save menu item', 'error');
|
||||
}
|
||||
} catch { onToast('Error', 'error'); }
|
||||
};
|
||||
|
||||
@@ -726,7 +743,7 @@ function MenuSection({ items, setItems, images, onToast }: any) {
|
||||
<div
|
||||
key={item.id}
|
||||
draggable
|
||||
onDragStart={() => handleDragStart(idx)}
|
||||
onDragStart={(e: any) => { e.dataTransfer!.effectAllowed = 'move'; handleDragStart(idx); }}
|
||||
onDragOver={(e) => handleDragOver(e, idx)}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDragEnter={() => setOverIdx(idx)}
|
||||
@@ -1130,7 +1147,7 @@ export default function AdminPage() {
|
||||
fetch('/api/rooms'),
|
||||
fetch('/api/calendar_events'),
|
||||
fetch('/api/social_events/public'),
|
||||
fetch('/api/menu'),
|
||||
fetch('/api/admin/menu'),
|
||||
fetch('/api/places'),
|
||||
fetch('/api/reviews'),
|
||||
fetch('/api/admin/images').catch(() => null),
|
||||
@@ -1139,7 +1156,7 @@ export default function AdminPage() {
|
||||
if (roomsRes.ok) { const d = await roomsRes.json(); setRooms(Array.isArray(d) ? d : []); }
|
||||
if (calRes.ok) { const d = await calRes.json(); setEvents(Array.isArray(d) ? d : []); }
|
||||
if (socialRes.ok) { const d = await socialRes.json(); setSocialEvents(Array.isArray(d) ? d : []); }
|
||||
if (menuRes.ok) { const d = await menuRes.json(); setMenuItems(Array.isArray(d) ? d : []); }
|
||||
if (menuRes.ok) { const d = await menuRes.json(); setMenuItems(Array.isArray(d) ? d : (d.data || [])); }
|
||||
if (placesRes.ok) { const d = await placesRes.json(); setPlaces(Array.isArray(d) ? d : []); }
|
||||
if (reviewsRes.ok) { const d = await reviewsRes.json(); setReviews(Array.isArray(d) ? d : []); }
|
||||
if (imagesRes?.ok) { const d = await imagesRes.json(); setImages(Array.isArray(d) ? d : []); }
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { requireRole } from '@/lib/auth';
|
||||
import { db } from '@/lib/db';
|
||||
|
||||
// GET /api/admin/menu — returns ALL menu items (including inactive)
|
||||
export async function GET() {
|
||||
try {
|
||||
await requireRole('admin');
|
||||
const { rows } = await db.query(
|
||||
'SELECT * FROM menu_items ORDER BY sort_order, id'
|
||||
);
|
||||
return NextResponse.json({ data: rows });
|
||||
} catch (error: any) {
|
||||
console.error('GET /api/admin/menu error:', error);
|
||||
return NextResponse.json({ error: error.message || 'Failed to fetch menu' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user