diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 2aa659a..7bab3aa 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -1,1185 +1,1088 @@
'use client';
-import { useState, useEffect } from 'react';
+import { useState, useEffect, useRef, useCallback } from 'react';
-// Types
-type Image = {
- id: number;
- data: string;
- filename: string;
- category: string;
- room_id: number | null;
- location_target: string;
+type Image = { id: number; filename: string; data: string; category: string; room_id: number | null; location_target: string; uploaded_at: string };
+type Slide = { id: number; title: string; subtitle: string; image_url: string | null; image_id: number | null; active: boolean; sort_order: number };
+type Room = { id: number; name: string; description: string; price: string; photos: string[]; featured_photo: string | null; active: boolean; sort_order: number };
+type CalendarEvent = { id: number; date: string; title: string; type: string; color: string; description: string | null; active: boolean };
+type SocialEvent = { id: number; name: string; description: string; price: string | null; date: string | null; photos: string[]; featured_photo: string | null; active: boolean; sort_order: number };
+type MenuItem = { id: number; category: string; name: string; description: string; price: string; is_daily_special: boolean; active: boolean; sort_order: number };
+type Place = { id: number; name: string; description: string; photos: string[]; featured_photo: string | null; distance_km: string; visit_time: string; suggestion: string; active: boolean; sort_order: number };
+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 };
+
+const C = {
+ gold: '#D4A853', goldLight: 'rgba(212,168,83,0.12)', navy: '#010D1E',
+ warm: '#7A5A3A', bg: '#F7F4EF', card: '#FFFFFF', border: 'rgba(1,13,30,0.08)',
+ text: '#444444', textLight: '#888888', danger: '#D32F2F', success: '#388E3C',
+ shadow: '0 1px 4px rgba(1,13,30,0.06)', shadowHover: '0 6px 20px rgba(1,13,30,0.12)',
};
-type FooterInfo = {
- facebook_url: string;
- instagram_url: string;
- whatsapp_url: string;
- address: string;
- phone: string;
- email: string;
-};
+const NAV = [
+ { id: 'brand', label: 'Brand', icon: 'π¨' },
+ { id: 'gallery', label: 'Images', icon: 'πΌοΈ' },
+ { id: 'slides', label: 'Slideshow', icon: 'ποΈ' },
+ { id: 'calendar', label: 'Calendar', icon: 'π
' },
+ { id: 'social', label: 'Social Events', icon: 'πͺ' },
+ { id: 'rooms', label: 'Rooms', icon: 'π¨' },
+ { id: 'menu', label: 'Menu', icon: 'π½οΈ' },
+ { id: 'places', label: 'Places', icon: 'πΊοΈ' },
+ { id: 'reviews', label: 'Reviews', icon: 'β' },
+ { id: 'users', label: 'Users', icon: 'π₯' },
+];
-type Slide = {
- id: number;
- title: string;
- subtitle: string;
- image_id: number | null;
- image_url: string;
- active: boolean;
- sort_order: number;
-};
-
-type CalendarEvent = {
- id: number;
- date: string;
- title: string;
- type: 'holiday' | 'season' | 'weather' | 'event';
- color: string;
- description: string;
- active: boolean;
-};
-
-type SocialEvent = {
- id: number;
- name: string;
- description: string;
- price: string;
- date: string;
- photos: string[];
- featured_photo: string | null;
- active: boolean;
- sort_order: number;
- reservation_count: number;
-};
-
-type SocialEventReservation = {
- id: number;
- event_id: number;
- username: string;
- event_name: string;
- guests: number;
- notes: string;
- status: 'pending' | 'confirmed' | 'cancelled';
- created_at: string;
-};
-
-type Room = {
- id: number;
- name: string;
- description: string;
- price: string;
- photos: string[];
- featured_photo: string | null;
- active: boolean;
- sort_order: number;
-};
-
-type RoomComment = {
- id: number;
- room_id: number;
- first_name: string;
- last_initial: string;
- text: string;
- created_at: string;
-};
-
-type MenuItem = {
- id: number;
- category: string;
- name: string;
- description: string;
- price: string;
- is_daily_special: boolean;
- active: boolean;
- sort_order: number;
-};
-
-type Place = {
- id: number;
- name: string;
- description: string;
- photos: string[];
- featured_photo: string | null;
- distance_km: string;
- visit_time: string;
- suggestion: string;
- active: boolean;
- sort_order: number;
-};
-
-type Review = {
- id: number;
- author_name: string;
- rating: number;
- text: string;
- approved: boolean;
-};
-
-// Constants
-const gold = '#E8A849';
-const navy = '#010D1E';
-const warm = '#7A5A3A';
-
-// Components
-function Text({ label, value, onChange, type = 'text' }: { label: string; value: string; onChange: (value: string) => void; type?: string }) {
+function I({ label, value, onChange, type = 'text', placeholder, style }: any) {
return (
-
+
+ {label && }
+ onChange(e.target.value)} placeholder={placeholder}
+ style={{ padding: '8px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: '14px', outline: 'none', background: '#FAFAFA', ...style }}
+ onFocus={e => { e.target.style.borderColor = C.gold; e.target.style.background = C.white; }}
+ onBlur={e => { e.target.style.borderColor = C.border; e.target.style.background = '#FAFAFA'; }} />
+
);
}
-function Number({ label, value, onChange }: { label: string; value: number; onChange: (value: string) => void }) {
+function TA({ label, value, onChange, rows = 3 }: any) {
return (
-
+
+ {label && }
+
);
}
-function ImageSelect({ label, images, value, onChange }: { label: string; images: Image[]; value: string; onChange: (value: string) => void }) {
+function S({ label, value, onChange, options, style }: any) {
return (
-