113 lines
5.4 KiB
TypeScript
113 lines
5.4 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from 'react';
|
|
import AppLayout from '@/components/AppLayout/AppLayout';
|
|
import {
|
|
Plus,
|
|
Search,
|
|
Image as ImageIcon,
|
|
Edit2,
|
|
Trash2,
|
|
ChevronRight,
|
|
Filter,
|
|
Grid,
|
|
List,
|
|
LayoutDashboard,
|
|
Utensils,
|
|
Monitor
|
|
} from 'lucide-react';
|
|
import styles from './menu.module.css';
|
|
|
|
const sidebarItems = [
|
|
{ icon: <LayoutDashboard size={20} />, label: 'Floor Plan' },
|
|
{ icon: <Utensils size={20} />, label: 'Orders' },
|
|
{ icon: <Monitor size={20} />, label: 'KDS (Kitchen)' },
|
|
{ icon: <Plus size={20} />, label: 'Menu Management', active: true },
|
|
];
|
|
|
|
const mockMenu = [
|
|
{ id: 1, name: 'Classic Burger', category: 'Main Course', price: 12.99, image: '🍔', status: 'Available' },
|
|
{ id: 2, name: 'Margherita Pizza', category: 'Main Course', price: 14.50, image: '🍕', status: 'Available' },
|
|
{ id: 3, name: 'Caesar Salad', category: 'Appetizers', price: 8.00, image: '🥗', status: 'Available' },
|
|
{ id: 4, name: 'French Fries', category: 'Sides', price: 4.50, image: '🍟', status: 'Available' },
|
|
{ id: 5, name: 'Chocolate Cake', category: 'Desserts', price: 6.50, image: '🍰', status: 'Limited' },
|
|
{ id: 6, name: 'Fresh Orange Juice', category: 'Beverages', price: 3.50, image: '🥤', status: 'Available' },
|
|
];
|
|
|
|
export default function MenuManagementPage() {
|
|
const [view, setView] = useState<'grid' | 'list'>('grid');
|
|
const [search, setSearch] = useState('');
|
|
|
|
return (
|
|
<AppLayout title="Restaurant Menu" sidebarItems={sidebarItems}>
|
|
<div className={styles.menuContainer}>
|
|
{/* Top Header */}
|
|
<div className={styles.header}>
|
|
<div className={styles.searchWrapper}>
|
|
<Search size={18} className={styles.searchIcon} />
|
|
<input
|
|
type="text"
|
|
placeholder="Search items..."
|
|
value={search}
|
|
onChange={(e) => setSearch(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div className={styles.actions}>
|
|
<div className={styles.viewToggle}>
|
|
<button onClick={() => setView('grid')} className={view === 'grid' ? styles.activeView : ''}><Grid size={18} /></button>
|
|
<button onClick={() => setView('list')} className={view === 'list' ? styles.activeView : ''}><List size={18} /></button>
|
|
</div>
|
|
<button className={styles.filterBtn}><Filter size={18} /> Category</button>
|
|
<button className={styles.addBtn}><Plus size={18} /> New Item</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
{view === 'grid' ? (
|
|
<div className={styles.menuGrid}>
|
|
{mockMenu.map(item => (
|
|
<div key={item.id} className={styles.menuCard}>
|
|
<div className={styles.imagePlaceholder}>{item.image}</div>
|
|
<div className={styles.cardInfo}>
|
|
<div className={styles.cardHeader}>
|
|
<span className={styles.category}>{item.category}</span>
|
|
<span className={`${styles.statusBadge} ${styles[item.status.toLowerCase()]}`}>{item.status}</span>
|
|
</div>
|
|
<h3 className={styles.name}>{item.name}</h3>
|
|
<div className={styles.cardFooter}>
|
|
<span className={styles.price}>$ {item.price.toFixed(2)}</span>
|
|
<div className={styles.cardActions}>
|
|
<button className={styles.editBtn}><Edit2 size={16} /></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className={styles.menuList}>
|
|
{mockMenu.map(item => (
|
|
<div key={item.id} className={styles.menuListItem}>
|
|
<div className={styles.itemMain}>
|
|
<div className={styles.listIcon}>{item.image}</div>
|
|
<div className={styles.itemDetail}>
|
|
<strong>{item.name}</strong>
|
|
<span>{item.category}</span>
|
|
</div>
|
|
</div>
|
|
<span className={styles.listPrice}>$ {item.price.toFixed(2)}</span>
|
|
<span className={`${styles.statusBadge} ${styles[item.status.toLowerCase()]}`}>{item.status}</span>
|
|
<div className={styles.listActions}>
|
|
<button><Edit2 size={16} /></button>
|
|
<button><Trash2 size={16} /></button>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</AppLayout>
|
|
);
|
|
}
|