diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 0145430..96e6b35 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -12,6 +12,7 @@ type Place = { id: number; name: string; description: string; photos: string[]; type Review = { id: number; author_name: string; author_email: string | null; rating: number; text: string; approved: boolean }; type FooterConfig = { logo: string; favicon: string; tagline: string; facebook_url: string; instagram_url: string; whatsapp_url: string; address: string; phone: string; email: string }; type SocialRes = { id: number; event_id: number; username: string; event_name: string; guests: number; notes: string; status: string; created_at: string }; +type Amenity = { id: number; name: string; icon_svg: string; sort_order: number }; const C = { gold: '#D4A853', goldLight: 'rgba(212,168,83,0.12)', navy: '#010D1E', @@ -27,6 +28,7 @@ const NAV = [ { id: 'calendar', label: 'Calendar', icon: '📅' }, { id: 'social', label: 'Social Events', icon: '🎪' }, { id: 'rooms', label: 'Rooms', icon: '🏨' }, + { id: 'amenities', label: 'Amenities', icon: '✨' }, { id: 'trips', label: 'Trips', icon: '✈️' }, { id: 'messages', label: 'Messages', icon: '💬' }, { id: 'menu', label: 'Menu', icon: '🍽️' }, @@ -899,6 +901,134 @@ function RoomEditor({ room, setRoom, images, onSave, onCancel }: any) { ); } +/* ─── Amenities Section ─── */ +function AmenitiesSection({ onToast }: { onToast: (msg: string, type: string) => void }) { + const [amenities, setAmenities] = useState([]); + const [editing, setEditing] = useState(null); + const [confirmDel, setConfirmDel] = useState(null); + + useEffect(() => { + fetch('/api/amenities') + .then(r => r.json()) + .then(d => setAmenities(d.data || [])) + .catch(() => onToast('Failed to load amenities', 'error')); + }, []); + + const save = async (amenity: Amenity) => { + try { + const url = amenity.id ? `/api/amenities?id=${amenity.id}` : '/api/amenities'; + const res = await fetch(url, { + method: amenity.id ? 'PUT' : 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(amenity), + }); + if (res.ok) { + const data = await res.json(); + if (amenity.id) { + setAmenities(prev => prev.map(a => a.id === amenity.id ? data.data : a)); + } else { + setAmenities(prev => [...prev, data.data]); + } + setEditing(null); + onToast('Amenity saved!', 'success'); + } else { + const err = await res.json(); + onToast(err.error || 'Failed to save', 'error'); + } + } catch { onToast('Error', 'error'); } + }; + + const del = async (id: number) => { + await fetch(`/api/amenities?id=${id}`, { method: 'DELETE' }); + setAmenities(prev => prev.filter(a => a.id !== id)); + onToast('Amenity deleted', 'success'); + setConfirmDel(null); + }; + + return ( +
+ setEditing({ id: 0, name: '', icon_svg: '', sort_order: amenities.length })} size="sm">+ New Amenity} /> + {amenities.length === 0 ? : ( +
+ {amenities.sort((a, b) => a.sort_order - b.sort_order).map((a: Amenity) => ( +
+
+
{a.name}
+
+ setEditing(a)}>Edit + setConfirmDel(a.id)}>Del +
+
+ ))} +
+ )} + {editing && setEditing(null)} />} + {confirmDel !== null && setConfirmDel(null)} onConfirm={() => del(confirmDel)} />} +
+ ); +} + +function AmenityEditor({ amenity, setAmenity, onSave, onCancel }: any) { + const defaultIcons = [ + { name: 'Wi-Fi', svg: '' }, + { name: 'TV', svg: '' }, + { name: 'Shower', svg: '' }, + { name: 'Bathtub', svg: '' }, + { name: 'Fireplace', svg: '' }, + { name: 'Minibar', svg: '' }, + { name: 'Coffee', svg: '' }, + { name: 'Safe', svg: '' }, + { name: 'Heating', svg: '' }, + { name: 'Balcony', svg: '' }, + { name: 'King Bed', svg: '' }, + { name: 'Mountain View', svg: '' }, + { name: 'Parking', svg: '' }, + { name: 'Restaurant', svg: '' }, + ]; + + return ( +
+
+

{amenity.id ? 'Edit Amenity' : 'New Amenity'}

+
+ setAmenity({ ...amenity, name: v })} placeholder="e.g., Wi-Fi, TV, Shower" /> +
+ +