diff --git a/apps/admin/src/App.tsx b/apps/admin/src/App.tsx index d87c1e0..9236ed2 100644 --- a/apps/admin/src/App.tsx +++ b/apps/admin/src/App.tsx @@ -13,6 +13,11 @@ import ProtectedRoute from './components/ProtectedRoute' import OrdersPage from './pages/OrdersPage' import OrderDetailPage from './pages/OrderDetailPage' import SystemSettingsPage from './pages/SystemSettingsPage' +import StoreSettingsPage from './pages/StoreSettingsPage' +import PaymentSettingsPage from './pages/PaymentSettingsPage' +import ThemeSettingsPage from './pages/ThemeSettingsPage' +import ContentSettingsPage from './pages/ContentSettingsPage' +import SystemMaintenancePage from './pages/SystemMaintenancePage' import MenuManagerPage from './pages/MenuManagerPage' import NewsletterSubscribersPage from './pages/NewsletterSubscribersPage' import ArticlesPage from './pages/ArticlesPage' @@ -61,7 +66,11 @@ function App() { } /> } /> } /> - } /> + } /> + } /> + } /> + } /> + } /> } /> } /> } /> diff --git a/apps/admin/src/components/Sidebar.tsx b/apps/admin/src/components/Sidebar.tsx index f549d7e..1bd83a5 100644 --- a/apps/admin/src/components/Sidebar.tsx +++ b/apps/admin/src/components/Sidebar.tsx @@ -1,4 +1,5 @@ -import { NavLink, useNavigate } from 'react-router-dom' +import { useState } from 'react' +import { NavLink, useNavigate, useLocation } from 'react-router-dom' import { LayoutDashboard, Package, @@ -18,10 +19,16 @@ import { Globe2, Users, Image as ImageIcon, - MessageSquare + MessageSquare, + Store, + CreditCard, + Palette, + FileText, + Wrench, + ChevronDown, } from 'lucide-react' -const MENU_ITEMS = [ +const MAIN_MENU = [ { icon: LayoutDashboard, label: 'Dashboard', to: '/' }, { icon: Tags, label: 'Categories', to: '/categories' }, { icon: Package, label: 'Products', to: '/products' }, @@ -49,11 +56,21 @@ const MENU_ITEMS = [ { icon: Layers, label: 'Menu Manager', to: '/menu-manager' }, { icon: Users, label: 'Subscribers', to: '/subscribers' }, { icon: MessageSquare, label: 'Contact Messages', to: '/contacts' }, - { icon: Settings, label: 'Settings', to: '/settings' }, +] + +const SETTINGS_MENU = [ + { icon: Store, label: 'Store Settings', to: '/settings' }, + { icon: CreditCard, label: 'Payment & Shipping',to: '/settings/payments' }, + { icon: Palette, label: 'Theme & Design', to: '/settings/theme' }, + { icon: FileText, label: 'Content', to: '/settings/content' }, + { icon: Wrench, label: 'System', to: '/settings/system' }, ] export default function Sidebar() { const navigate = useNavigate() + const location = useLocation() + const isInSettings = location.pathname.startsWith('/settings') + const [settingsOpen, setSettingsOpen] = useState(isInSettings) const handleLogout = () => { localStorage.removeItem('homaroma_admin_token') @@ -72,12 +89,12 @@ export default function Sidebar() { {/* Navigation — scrollable */} {/* User / Bottom */} diff --git a/apps/admin/src/pages/ContentSettingsPage.tsx b/apps/admin/src/pages/ContentSettingsPage.tsx new file mode 100644 index 0000000..19367f8 --- /dev/null +++ b/apps/admin/src/pages/ContentSettingsPage.tsx @@ -0,0 +1,127 @@ +import { useState, useEffect } from 'react' +import { API_BASE, type StoreSettings } from '@homaroma/types' +import { Save, Loader2 } from 'lucide-react' + +export default function ContentSettingsPage() { + const [loading, setLoading] = useState(true) + const [saving, setSaving] = useState(false) + + const [footerDescription, setFooterDescription] = useState('') + const [footerSupportHeading, setFooterSupportHeading] = useState('') + const [footerCopyrightText, setFooterCopyrightText] = useState('') + const [newsletterTitle, setNewsletterTitle] = useState('') + const [newsletterDescription, setNewsletterDescription] = useState('') + const [newsletterPlaceholder, setNewsletterPlaceholder] = useState('') + const [newsletterButtonText, setNewsletterButtonText] = useState('') + + useEffect(() => { + fetch(`${API_BASE}/settings`) + .then(r => r.json()) + .then((data: StoreSettings) => { + setFooterDescription(data.footerDescription || '') + setFooterSupportHeading(data.footerSupportHeading || '') + setFooterCopyrightText(data.footerCopyrightText || '') + setNewsletterTitle(data.newsletterTitle || '') + setNewsletterDescription(data.newsletterDescription || '') + setNewsletterPlaceholder(data.newsletterPlaceholder || '') + setNewsletterButtonText(data.newsletterButtonText || '') + }) + .catch(console.error) + .finally(() => setLoading(false)) + }, []) + + const handleSave = async (e: React.FormEvent) => { + e.preventDefault() + setSaving(true) + try { + const res = await fetch(`${API_BASE}/settings`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + footerDescription, footerSupportHeading, footerCopyrightText, + newsletterTitle, newsletterDescription, newsletterPlaceholder, newsletterButtonText, + }), + }) + if (res.ok) alert('Saved successfully!') + } catch { alert('Failed to save') } finally { setSaving(false) } + } + + if (loading) return
+ + return ( +
+
+

Content Settings

+

Newsletter copy and footer text displayed across the website.

+
+ +
+ {/* Footer Content */} +
+
+
📄
+

Footer Content

+
+ +
+
+ +