Restaurant Management Dashboard Template
Preview
Edit
Download
Run
Download Options
HTML File
Download as .html file
CSS File
Download as .css file
JavaScript File
Download as .js file
Combined HTML
All code in one HTML file
Project ZIP
All files in a ZIP archive
Cancel
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>RestaurantPro - Management Dashboard</title> </head> <body class="bg-gray-50 min-h-screen"> <!-- Navigation --> <nav class="bg-white shadow-lg border-b border-gray-200"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="flex justify-between h-16"> <div class="flex items-center"> <div class="flex-shrink-0 flex items-center"> <div class="w-8 h-8 bg-gradient-to-r from-orange-500 to-red-500 rounded-lg flex items-center justify-center"> <span class="text-white font-bold text-lg">R</span> </div> <span class="ml-2 text-xl font-bold text-gray-900">RestaurantPro</span> </div> <div class="hidden md:ml-10 md:flex md:space-x-8"> <button onclick="showSection('dashboard')" class="nav-btn text-orange-600 border-orange-500 px-3 py-2 text-sm font-medium border-b-2">Dashboard</button> <button onclick="showSection('orders')" class="nav-btn text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">Orders</button> <button onclick="showSection('menu')" class="nav-btn text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">Menu</button> <button onclick="showSection('staff')" class="nav-btn text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">Staff</button> <button onclick="showSection('analytics')" class="nav-btn text-gray-500 hover:text-gray-700 px-3 py-2 text-sm font-medium">Analytics</button> </div> </div> <div class="flex items-center space-x-4"> <div class="relative"> <button class="p-2 text-gray-400 hover:text-gray-500 relative"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-5 5-5-5h5v-12"></path> </svg> <span class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center pulse-dot">3</span> </button> </div> <div class="flex items-center space-x-2"> <div class="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center"> <span class="text-sm font-medium text-gray-700">JD</span> </div> <span class="text-sm font-medium text-gray-700">John Doe</span> </div> </div> </div> </div> </nav> <!-- Main Content --> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> <!-- Dashboard Section --> <div id="dashboard" class="section"> <!-- Stats Cards --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8"> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Today's Revenue</p> <p class="text-2xl font-bold text-gray-900">$2,847</p> <p class="text-sm text-green-600 mt-1">+12.5% from yesterday</p> </div> <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Active Orders</p> <p class="text-2xl font-bold text-gray-900">23</p> <p class="text-sm text-blue-600 mt-1">8 pending, 15 in progress</p> </div> <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Staff On Duty</p> <p class="text-2xl font-bold text-gray-900">12/15</p> <p class="text-sm text-yellow-600 mt-1">3 staff members off</p> </div> <div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Table Occupancy</p> <p class="text-2xl font-bold text-gray-900">18/25</p> <p class="text-sm text-purple-600 mt-1">72% occupied</p> </div> <div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path> </svg> </div> </div> </div> </div> <!-- Recent Activity & Quick Actions --> <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <!-- Recent Orders --> <div class="bg-white rounded-xl shadow-sm border border-gray-100"> <div class="p-6 border-b border-gray-100"> <h3 class="text-lg font-semibold text-gray-900">Recent Orders</h3> </div> <div class="p-6"> <div class="space-y-4"> <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg"> <div class="flex items-center space-x-3"> <div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center"> <span class="text-sm font-medium text-blue-600">#001</span> </div> <div> <p class="font-medium text-gray-900">Table 5</p> <p class="text-sm text-gray-500">2x Pasta, 1x Pizza</p> </div> </div> <div class="text-right"> <p class="font-medium text-gray-900">$45.50</p> <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">Preparing</span> </div> </div> <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg"> <div class="flex items-center space-x-3"> <div class="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center"> <span class="text-sm font-medium text-green-600">#002</span> </div> <div> <p class="font-medium text-gray-900">Table 12</p> <p class="text-sm text-gray-500">3x Burger, 2x Fries</p> </div> </div> <div class="text-right"> <p class="font-medium text-gray-900">$67.25</p> <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">Ready</span> </div> </div> <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg"> <div class="flex items-center space-x-3"> <div class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center"> <span class="text-sm font-medium text-red-600">#003</span> </div> <div> <p class="font-medium text-gray-900">Table 8</p> <p class="text-sm text-gray-500">1x Steak, 1x Salad</p> </div> </div> <div class="text-right"> <p class="font-medium text-gray-900">$89.00</p> <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">Pending</span> </div> </div> </div> </div> </div> <!-- Quick Actions --> <div class="bg-white rounded-xl shadow-sm border border-gray-100"> <div class="p-6 border-b border-gray-100"> <h3 class="text-lg font-semibold text-gray-900">Quick Actions</h3> </div> <div class="p-6"> <div class="grid grid-cols-2 gap-4"> <button onclick="showSection('orders')" class="p-4 bg-blue-50 hover:bg-blue-100 rounded-lg text-center transition-colors"> <div class="w-8 h-8 bg-blue-500 rounded-lg mx-auto mb-2 flex items-center justify-center"> <svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path> </svg> </div> <p class="text-sm font-medium text-gray-900">New Order</p> </button> <button onclick="showSection('menu')" class="p-4 bg-green-50 hover:bg-green-100 rounded-lg text-center transition-colors"> <div class="w-8 h-8 bg-green-500 rounded-lg mx-auto mb-2 flex items-center justify-center"> <svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"></path> </svg> </div> <p class="text-sm font-medium text-gray-900">Update Menu</p> </button> <button onclick="showSection('staff')" class="p-4 bg-purple-50 hover:bg-purple-100 rounded-lg text-center transition-colors"> <div class="w-8 h-8 bg-purple-500 rounded-lg mx-auto mb-2 flex items-center justify-center"> <svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-9a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z"></path> </svg> </div> <p class="text-sm font-medium text-gray-900">Manage Staff</p> </button> <button onclick="showSection('analytics')" class="p-4 bg-orange-50 hover:bg-orange-100 rounded-lg text-center transition-colors"> <div class="w-8 h-8 bg-orange-500 rounded-lg mx-auto mb-2 flex items-center justify-center"> <svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path> </svg> </div> <p class="text-sm font-medium text-gray-900">View Reports</p> </button> </div> </div> </div> </div> </div> <!-- Orders Section --> <div id="orders" class="section hidden"> <div class="flex justify-between items-center mb-6"> <h2 class="text-2xl font-bold text-gray-900">Order Management</h2> <button onclick="openNewOrderModal()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-medium transition-colors"> + New Order </button> </div> <!-- Order Filters --> <div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6"> <div class="flex flex-wrap gap-4"> <button onclick="filterOrders('all')" class="order-filter-btn bg-blue-100 text-blue-700 px-4 py-2 rounded-lg font-medium">All Orders</button> <button onclick="filterOrders('pending')" class="order-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Pending</button> <button onclick="filterOrders('preparing')" class="order-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Preparing</button> <button onclick="filterOrders('ready')" class="order-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Ready</button> <button onclick="filterOrders('completed')" class="order-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Completed</button> </div> </div> <!-- Orders List --> <div id="ordersList" class="space-y-4"> <!-- Orders will be populated by JavaScript --> </div> </div> <!-- Menu Section --> <div id="menu" class="section hidden"> <div class="flex justify-between items-center mb-6"> <h2 class="text-2xl font-bold text-gray-900">Menu Management</h2> <button onclick="openAddItemModal()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg font-medium transition-colors"> + Add Item </button> </div> <!-- Menu Categories --> <div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6"> <div class="flex flex-wrap gap-4"> <button onclick="filterMenu('all')" class="menu-filter-btn bg-green-100 text-green-700 px-4 py-2 rounded-lg font-medium">All Items</button> <button onclick="filterMenu('appetizers')" class="menu-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Appetizers</button> <button onclick="filterMenu('mains')" class="menu-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Main Courses</button> <button onclick="filterMenu('desserts')" class="menu-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Desserts</button> <button onclick="filterMenu('beverages')" class="menu-filter-btn bg-gray-100 text-gray-700 px-4 py-2 rounded-lg font-medium">Beverages</button> </div> </div> <!-- Menu Items Grid --> <div id="menuGrid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <!-- Menu items will be populated by JavaScript --> </div> </div> <!-- Staff Section --> <div id="staff" class="section hidden"> <div class="flex justify-between items-center mb-6"> <h2 class="text-2xl font-bold text-gray-900">Staff Management</h2> <button onclick="openAddStaffModal()" class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg font-medium transition-colors"> + Add Staff </button> </div> <!-- Staff Stats --> <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Total Staff</p> <p class="text-2xl font-bold text-gray-900">15</p> </div> <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">On Duty</p> <p class="text-2xl font-bold text-green-600">12</p> </div> <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Off Duty</p> <p class="text-2xl font-bold text-red-600">3</p> </div> <div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"></path> </svg> </div> </div> </div> </div> <!-- Staff List --> <div class="bg-white rounded-xl shadow-sm border border-gray-100"> <div class="p-6 border-b border-gray-100"> <h3 class="text-lg font-semibold text-gray-900">Staff Directory</h3> </div> <div class="overflow-x-auto"> <table class="min-w-full divide-y divide-gray-200"> <thead class="bg-gray-50"> <tr> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Employee</th> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Position</th> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Shift</th> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th> </tr> </thead> <tbody id="staffTable" class="bg-white divide-y divide-gray-200"> <!-- Staff rows will be populated by JavaScript --> </tbody> </table> </div> </div> </div> <!-- Analytics Section --> <div id="analytics" class="section hidden"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Analytics & Reports</h2> <!-- Analytics Cards --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8"> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Weekly Revenue</p> <p class="text-2xl font-bold text-gray-900">$18,247</p> <p class="text-sm text-green-600 mt-1">+8.2% from last week</p> </div> <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Orders This Week</p> <p class="text-2xl font-bold text-gray-900">342</p> <p class="text-sm text-blue-600 mt-1">+15.3% from last week</p> </div> <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Avg Order Value</p> <p class="text-2xl font-bold text-gray-900">$53.35</p> <p class="text-sm text-purple-600 mt-1">+2.1% from last week</p> </div> <div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"></path> </svg> </div> </div> </div> <div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100"> <div class="flex items-center justify-between"> <div> <p class="text-sm font-medium text-gray-600">Customer Satisfaction</p> <p class="text-2xl font-bold text-gray-900">4.8/5</p> <p class="text-sm text-yellow-600 mt-1">Based on 127 reviews</p> </div> <div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center"> <svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"></path> </svg> </div> </div> </div> </div> <!-- Charts --> <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <!-- Revenue Chart --> <div class="bg-white rounded-xl shadow-sm border border-gray-100"> <div class="p-6 border-b border-gray-100"> <h3 class="text-lg font-semibold text-gray-900">Daily Revenue</h3> </div> <div class="p-6"> <div class="flex items-end space-x-2 h-64"> <div class="flex-1 bg-blue-200 chart-bar" style="height: 60%"></div> <div class="flex-1 bg-blue-300 chart-bar" style="height: 80%"></div> <div class="flex-1 bg-blue-400 chart-bar" style="height: 45%"></div> <div class="flex-1 bg-blue-500 chart-bar" style="height: 90%"></div> <div class="flex-1 bg-blue-600 chart-bar" style="height: 75%"></div> <div class="flex-1 bg-blue-700 chart-bar" style="height: 100%"></div> <div class="flex-1 bg-blue-800 chart-bar" style="height: 85%"></div> </div> <div class="flex justify-between text-sm text-gray-500 mt-2"> <span>Mon</span> <span>Tue</span> <span>Wed</span> <span>Thu</span> <span>Fri</span> <span>Sat</span> <span>Sun</span> </div> </div> </div> <!-- Popular Items --> <div class="bg-white rounded-xl shadow-sm border border-gray-100"> <div class="p-6 border-b border-gray-100"> <h3 class="text-lg font-semibold text-gray-900">Popular Items</h3> </div> <div class="p-6"> <div class="space-y-4"> <div class="flex items-center justify-between"> <div class="flex items-center space-x-3"> <div class="w-8 h-8 bg-yellow-100 rounded-lg flex items-center justify-center"> <span class="text-sm font-bold text-yellow-600">1</span> </div> <span class="font-medium text-gray-900">Margherita Pizza</span> </div> <span class="text-sm text-gray-500">127 orders</span> </div> <div class="flex items-center justify-between"> <div class="flex items-center space-x-3"> <div class="w-8 h-8 bg-gray-100 rounded-lg flex items-center justify-center"> <span class="text-sm font-bold text-gray-600">2</span> </div> <span class="font-medium text-gray-900">Caesar Salad</span> </div> <span class="text-sm text-gray-500">98 orders</span> </div> <div class="flex items-center justify-between"> <div class="flex items-center space-x-3"> <div class="w-8 h-8 bg-orange-100 rounded-lg flex items-center justify-center"> <span class="text-sm font-bold text-orange-600">3</span> </div> <span class="font-medium text-gray-900">Grilled Salmon</span> </div> <span class="text-sm text-gray-500">87 orders</span> </div> <div class="flex items-center justify-between"> <div class="flex items-center space-x-3"> <div class="w-8 h-8 bg-gray-100 rounded-lg flex items-center justify-center"> <span class="text-sm font-bold text-gray-600">4</span> </div> <span class="font-medium text-gray-900">Beef Burger</span> </div> <span class="text-sm text-gray-500">76 orders</span> </div> <div class="flex items-center justify-between"> <div class="flex items-center space-x-3"> <div class="w-8 h-8 bg-gray-100 rounded-lg flex items-center justify-center"> <span class="text-sm font-bold text-gray-600">5</span> </div> <span class="font-medium text-gray-900">Chocolate Cake</span> </div> <span class="text-sm text-gray-500">65 orders</span> </div> </div> </div> </div> </div> </div> </div> <!-- Modals --> <!-- New Order Modal --> <div id="newOrderModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50"> <div class="flex items-center justify-center min-h-screen p-4"> <div class="bg-white rounded-xl shadow-xl max-w-md w-full"> <div class="p-6 border-b border-gray-100"> <div class="flex justify-between items-center"> <h3 class="text-lg font-semibold text-gray-900">New Order</h3> <button onclick="closeModal('newOrderModal')" class="text-gray-400 hover:text-gray-600"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> </div> <div class="p-6"> <form onsubmit="createOrder(event)"> <div class="space-y-4"> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Table Number</label> <select id="tableNumber" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"> <option value="">Select Table</option> <option value="1">Table 1</option> <option value="2">Table 2</option> <option value="3">Table 3</option> <option value="4">Table 4</option> <option value="5">Table 5</option> </select> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Items</label> <textarea id="orderItems" placeholder="Enter order items..." class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" rows="3"></textarea> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Total Amount</label> <input type="number" id="orderTotal" placeholder="0.00" step="0.01" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"> </div> </div> <div class="flex justify-end space-x-3 mt-6"> <button type="button" onclick="closeModal('newOrderModal')" class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg font-medium transition-colors">Cancel</button> <button type="submit" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium transition-colors">Create Order</button> </div> </form> </div> </div> </div> </div> <!-- Add Menu Item Modal --> <div id="addItemModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50"> <div class="flex items-center justify-center min-h-screen p-4"> <div class="bg-white rounded-xl shadow-xl max-w-md w-full"> <div class="p-6 border-b border-gray-100"> <div class="flex justify-between items-center"> <h3 class="text-lg font-semibold text-gray-900">Add Menu Item</h3> <button onclick="closeModal('addItemModal')" class="text-gray-400 hover:text-gray-600"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> </div> <div class="p-6"> <form onsubmit="addMenuItem(event)"> <div class="space-y-4"> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Item Name</label> <input type="text" id="itemName" placeholder="Enter item name..." class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Category</label> <select id="itemCategory" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500"> <option value="appetizers">Appetizers</option> <option value="mains">Main Courses</option> <option value="desserts">Desserts</option> <option value="beverages">Beverages</option> </select> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Price</label> <input type="number" id="itemPrice" placeholder="0.00" step="0.01" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Description</label> <textarea id="itemDescription" placeholder="Enter description..." class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" rows="3"></textarea> </div> </div> <div class="flex justify-end space-x-3 mt-6"> <button type="button" onclick="closeModal('addItemModal')" class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg font-medium transition-colors">Cancel</button> <button type="submit" class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg font-medium transition-colors">Add Item</button> </div> </form> </div> </div> </div> </div> <!-- Add Staff Modal --> <div id="addStaffModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50"> <div class="flex items-center justify-center min-h-screen p-4"> <div class="bg-white rounded-xl shadow-xl max-w-md w-full"> <div class="p-6 border-b border-gray-100"> <div class="flex justify-between items-center"> <h3 class="text-lg font-semibold text-gray-900">Add Staff Member</h3> <button onclick="closeModal('addStaffModal')" class="text-gray-400 hover:text-gray-600"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> </div> <div class="p-6"> <form onsubmit="addStaffMember(event)"> <div class="space-y-4"> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Full Name</label> <input type="text" id="staffName" placeholder="Enter full name..." class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Position</label> <select id="staffPosition" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"> <option value="waiter">Waiter</option> <option value="chef">Chef</option> <option value="bartender">Bartender</option> <option value="manager">Manager</option> <option value="host">Host</option> </select> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Shift</label> <select id="staffShift" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"> <option value="morning">Morning (6AM - 2PM)</option> <option value="afternoon">Afternoon (2PM - 10PM)</option> <option value="night">Night (10PM - 6AM)</option> </select> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-2">Phone</label> <input type="tel" id="staffPhone" placeholder="Enter phone number..." class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"> </div> </div> <div class="flex justify-end space-x-3 mt-6"> <button type="button" onclick="closeModal('addStaffModal')" class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg font-medium transition-colors">Cancel</button> <button type="submit" class="px-4 py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-lg font-medium transition-colors">Add Staff</button> </div> </form> </div> </div> </div> </div> <!-- Notification Container --> <div id="notifications" class="fixed top-4 right-4 z-50 space-y-2"></div> <script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'96be50a8b087ff6d',t:'MTc1NDY0ODc4Mi4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body> </html>
CSS
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); * { font-family: 'Inter', sans-serif; } .fade-in { animation: fadeIn 0.3s ease-in; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .pulse-dot { animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .slide-in { animation: slideIn 0.4s ease-out; } @keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } } .chart-bar { transition: height 0.5s ease-in-out; } .notification-enter { animation: notificationSlide 0.3s ease-out; } @keyframes notificationSlide { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
JavaScript
// Global data storage let orders = [ { id: 1, table: 5, items: '2x Pasta, 1x Pizza', total: 45.50, status: 'preparing', time: '10:30 AM' }, { id: 2, table: 12, items: '3x Burger, 2x Fries', total: 67.25, status: 'ready', time: '10:45 AM' }, { id: 3, table: 8, items: '1x Steak, 1x Salad', total: 89.00, status: 'pending', time: '11:00 AM' }, { id: 4, table: 3, items: '2x Pizza, 1x Coke', total: 32.75, status: 'completed', time: '9:15 AM' }, { id: 5, table: 15, items: '1x Fish, 2x Wine', total: 78.50, status: 'preparing', time: '11:15 AM' } ]; let menuItems = [ { id: 1, name: 'Margherita Pizza', category: 'mains', price: 18.99, description: 'Fresh tomatoes, mozzarella, basil', available: true }, { id: 2, name: 'Caesar Salad', category: 'appetizers', price: 12.99, description: 'Romaine lettuce, parmesan, croutons', available: true }, { id: 3, name: 'Grilled Salmon', category: 'mains', price: 24.99, description: 'Atlantic salmon with herbs', available: true }, { id: 4, name: 'Chocolate Cake', category: 'desserts', price: 8.99, description: 'Rich chocolate layer cake', available: true }, { id: 5, name: 'Craft Beer', category: 'beverages', price: 6.99, description: 'Local brewery selection', available: true }, { id: 6, name: 'Beef Burger', category: 'mains', price: 16.99, description: 'Angus beef with fries', available: true } ]; let staff = [ { id: 1, name: 'Alice Johnson', position: 'waiter', status: 'on-duty', shift: 'morning', phone: '(555) 123-4567' }, { id: 2, name: 'Bob Smith', position: 'chef', status: 'on-duty', shift: 'afternoon', phone: '(555) 234-5678' }, { id: 3, name: 'Carol Davis', position: 'bartender', status: 'off-duty', shift: 'night', phone: '(555) 345-6789' }, { id: 4, name: 'David Wilson', position: 'manager', status: 'on-duty', shift: 'morning', phone: '(555) 456-7890' }, { id: 5, name: 'Eva Brown', position: 'waiter', status: 'on-duty', shift: 'afternoon', phone: '(555) 567-8901' } ]; // Navigation functions function showSection(sectionName) { // Hide all sections document.querySelectorAll('.section').forEach(section => { section.classList.add('hidden'); }); // Show selected section document.getElementById(sectionName).classList.remove('hidden'); document.getElementById(sectionName).classList.add('fade-in'); // Update navigation document.querySelectorAll('.nav-btn').forEach(btn => { btn.classList.remove('text-orange-600', 'border-orange-500', 'border-b-2'); btn.classList.add('text-gray-500'); }); event.target.classList.remove('text-gray-500'); event.target.classList.add('text-orange-600', 'border-orange-500', 'border-b-2'); // Load section-specific data if (sectionName === 'orders') { renderOrders(); } else if (sectionName === 'menu') { renderMenu(); } else if (sectionName === 'staff') { renderStaff(); } } // Order management functions function renderOrders(filter = 'all') { const ordersList = document.getElementById('ordersList'); const filteredOrders = filter === 'all' ? orders : orders.filter(order => order.status === filter); ordersList.innerHTML = filteredOrders.map(order => ` <div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6"> <div class="flex items-center justify-between"> <div class="flex items-center space-x-4"> <div class="w-12 h-12 bg-${getStatusColor(order.status)}-100 rounded-full flex items-center justify-center"> <span class="font-medium text-${getStatusColor(order.status)}-600">#${String(order.id).padStart(3, '0')}</span> </div> <div> <h3 class="font-semibold text-gray-900">Table ${order.table}</h3> <p class="text-gray-600">${order.items}</p> <p class="text-sm text-gray-500">${order.time}</p> </div> </div> <div class="text-right"> <p class="text-xl font-bold text-gray-900">$${order.total.toFixed(2)}</p> <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-${getStatusColor(order.status)}-100 text-${getStatusColor(order.status)}-800"> ${order.status.charAt(0).toUpperCase() + order.status.slice(1)} </span> <div class="mt-2 space-x-2"> ${order.status !== 'completed' ? ` <button onclick="updateOrderStatus(${order.id}, '${getNextStatus(order.status)}')" class="px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded-lg transition-colors"> ${getNextStatus(order.status).charAt(0).toUpperCase() + getNextStatus(order.status).slice(1)} </button> ` : ''} <button onclick="deleteOrder(${order.id})" class="px-3 py-1 bg-red-600 hover:bg-red-700 text-white text-sm rounded-lg transition-colors"> Delete </button> </div> </div> </div> </div> `).join(''); } function getStatusColor(status) { const colors = { 'pending': 'red', 'preparing': 'yellow', 'ready': 'green', 'completed': 'gray' }; return colors[status] || 'gray'; } function getNextStatus(currentStatus) { const statusFlow = { 'pending': 'preparing', 'preparing': 'ready', 'ready': 'completed' }; return statusFlow[currentStatus] || currentStatus; } function updateOrderStatus(orderId, newStatus) { const orderIndex = orders.findIndex(order => order.id === orderId); if (orderIndex !== -1) { orders[orderIndex].status = newStatus; renderOrders(); showNotification(`Order #${String(orderId).padStart(3, '0')} updated to ${newStatus}`, 'success'); } } function deleteOrder(orderId) { orders = orders.filter(order => order.id !== orderId); renderOrders(); showNotification(`Order #${String(orderId).padStart(3, '0')} deleted`, 'success'); } function filterOrders(status) { // Update filter buttons document.querySelectorAll('.order-filter-btn').forEach(btn => { btn.classList.remove('bg-blue-100', 'text-blue-700'); btn.classList.add('bg-gray-100', 'text-gray-700'); }); event.target.classList.remove('bg-gray-100', 'text-gray-700'); event.target.classList.add('bg-blue-100', 'text-blue-700'); renderOrders(status); } function createOrder(event) { event.preventDefault(); const table = document.getElementById('tableNumber').value; const items = document.getElementById('orderItems').value; const total = parseFloat(document.getElementById('orderTotal').value); if (!table || !items || !total) { showNotification('Please fill in all fields', 'error'); return; } const newOrder = { id: orders.length + 1, table: parseInt(table), items: items, total: total, status: 'pending', time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }; orders.unshift(newOrder); closeModal('newOrderModal'); renderOrders(); showNotification('New order created successfully!', 'success'); // Reset form document.getElementById('tableNumber').value = ''; document.getElementById('orderItems').value = ''; document.getElementById('orderTotal').value = ''; } // Menu management functions function renderMenu(filter = 'all') { const menuGrid = document.getElementById('menuGrid'); const filteredItems = filter === 'all' ? menuItems : menuItems.filter(item => item.category === filter); menuGrid.innerHTML = filteredItems.map(item => ` <div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"> <div class="p-6"> <div class="flex justify-between items-start mb-4"> <h3 class="text-lg font-semibold text-gray-900">${item.name}</h3> <span class="text-xl font-bold text-green-600">$${item.price.toFixed(2)}</span> </div> <p class="text-gray-600 mb-4">${item.description}</p> <div class="flex justify-between items-center"> <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-${item.available ? 'green' : 'red'}-100 text-${item.available ? 'green' : 'red'}-800"> ${item.available ? 'Available' : 'Out of Stock'} </span> <div class="space-x-2"> <button onclick="toggleAvailability(${item.id})" class="px-3 py-1 bg-${item.available ? 'red' : 'green'}-600 hover:bg-${item.available ? 'red' : 'green'}-700 text-white text-sm rounded-lg transition-colors"> ${item.available ? 'Disable' : 'Enable'} </button> <button onclick="deleteMenuItem(${item.id})" class="px-3 py-1 bg-gray-600 hover:bg-gray-700 text-white text-sm rounded-lg transition-colors"> Delete </button> </div> </div> </div> </div> `).join(''); } function filterMenu(category) { // Update filter buttons document.querySelectorAll('.menu-filter-btn').forEach(btn => { btn.classList.remove('bg-green-100', 'text-green-700'); btn.classList.add('bg-gray-100', 'text-gray-700'); }); event.target.classList.remove('bg-gray-100', 'text-gray-700'); event.target.classList.add('bg-green-100', 'text-green-700'); renderMenu(category); } function toggleAvailability(itemId) { const itemIndex = menuItems.findIndex(item => item.id === itemId); if (itemIndex !== -1) { menuItems[itemIndex].available = !menuItems[itemIndex].available; renderMenu(); showNotification(`${menuItems[itemIndex].name} ${menuItems[itemIndex].available ? 'enabled' : 'disabled'}`, 'success'); } } function deleteMenuItem(itemId) { menuItems = menuItems.filter(item => item.id !== itemId); renderMenu(); showNotification('Menu item deleted successfully!', 'success'); } function addMenuItem(event) { event.preventDefault(); const name = document.getElementById('itemName').value; const category = document.getElementById('itemCategory').value; const price = parseFloat(document.getElementById('itemPrice').value); const description = document.getElementById('itemDescription').value; if (!name || !price || !description) { showNotification('Please fill in all fields', 'error'); return; } const newItem = { id: menuItems.length + 1, name: name, category: category, price: price, description: description, available: true }; menuItems.push(newItem); closeModal('addItemModal'); renderMenu(); showNotification('Menu item added successfully!', 'success'); // Reset form document.getElementById('itemName').value = ''; document.getElementById('itemPrice').value = ''; document.getElementById('itemDescription').value = ''; } // Staff management functions function renderStaff() { const staffTable = document.getElementById('staffTable'); staffTable.innerHTML = staff.map(member => ` <tr> <td class="px-6 py-4 whitespace-nowrap"> <div class="flex items-center"> <div class="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center"> <span class="text-sm font-medium text-gray-700">${member.name.split(' ').map(n => n[0]).join('')}</span> </div> <div class="ml-4"> <div class="text-sm font-medium text-gray-900">${member.name}</div> <div class="text-sm text-gray-500">${member.phone}</div> </div> </div> </td> <td class="px-6 py-4 whitespace-nowrap"> <span class="text-sm text-gray-900 capitalize">${member.position}</span> </td> <td class="px-6 py-4 whitespace-nowrap"> <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-${member.status === 'on-duty' ? 'green' : 'red'}-100 text-${member.status === 'on-duty' ? 'green' : 'red'}-800"> ${member.status === 'on-duty' ? 'On Duty' : 'Off Duty'} </span> </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 capitalize"> ${member.shift} </td> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2"> <button onclick="toggleStaffStatus(${member.id})" class="text-blue-600 hover:text-blue-900"> ${member.status === 'on-duty' ? 'Clock Out' : 'Clock In'} </button> <button onclick="deleteStaff(${member.id})" class="text-red-600 hover:text-red-900"> Remove </button> </td> </tr> `).join(''); } function toggleStaffStatus(staffId) { const staffIndex = staff.findIndex(member => member.id === staffId); if (staffIndex !== -1) { staff[staffIndex].status = staff[staffIndex].status === 'on-duty' ? 'off-duty' : 'on-duty'; renderStaff(); showNotification(`${staff[staffIndex].name} ${staff[staffIndex].status === 'on-duty' ? 'clocked in' : 'clocked out'}`, 'success'); } } function deleteStaff(staffId) { staff = staff.filter(member => member.id !== staffId); renderStaff(); showNotification('Staff member removed successfully!', 'success'); } function addStaffMember(event) { event.preventDefault(); const name = document.getElementById('staffName').value; const position = document.getElementById('staffPosition').value; const shift = document.getElementById('staffShift').value; const phone = document.getElementById('staffPhone').value; if (!name || !phone) { showNotification('Please fill in all required fields', 'error'); return; } const newStaff = { id: staff.length + 1, name: name, position: position, status: 'off-duty', shift: shift, phone: phone }; staff.push(newStaff); closeModal('addStaffModal'); renderStaff(); showNotification('Staff member added successfully!', 'success'); // Reset form document.getElementById('staffName').value = ''; document.getElementById('staffPhone').value = ''; } // Modal functions function openNewOrderModal() { document.getElementById('newOrderModal').classList.remove('hidden'); } function openAddItemModal() { document.getElementById('addItemModal').classList.remove('hidden'); } function openAddStaffModal() { document.getElementById('addStaffModal').classList.remove('hidden'); } function closeModal(modalId) { document.getElementById(modalId).classList.add('hidden'); } // Notification system function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification-enter bg-white border-l-4 border-${type === 'success' ? 'green' : type === 'error' ? 'red' : 'blue'}-500 p-4 shadow-lg rounded-lg max-w-sm`; notification.innerHTML = ` <div class="flex"> <div class="flex-shrink-0"> <svg class="w-5 h-5 text-${type === 'success' ? 'green' : type === 'error' ? 'red' : 'blue'}-500" fill="currentColor" viewBox="0 0 20 20"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path> </svg> </div> <div class="ml-3"> <p class="text-sm font-medium text-gray-900">${message}</p> </div> <div class="ml-auto pl-3"> <button onclick="this.parentElement.parentElement.parentElement.remove()" class="text-gray-400 hover:text-gray-600"> <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path> </svg> </button> </div> </div> `; document.getElementById('notifications').appendChild(notification); // Auto remove after 5 seconds setTimeout(() => { if (notification.parentElement) { notification.remove(); } }, 5000); } // Close modals when clicking outside document.addEventListener('click', function(event) { const modals = ['newOrderModal', 'addItemModal', 'addStaffModal']; modals.forEach(modalId => { const modal = document.getElementById(modalId); if (event.target === modal) { closeModal(modalId); } }); }); // Initialize the app document.addEventListener('DOMContentLoaded', function() { renderOrders(); renderMenu(); renderStaff(); // Show welcome notification setTimeout(() => { showNotification('Welcome to RestaurantPro! Your management dashboard is ready.', 'success'); }, 1000); });
Output Preview
Desktop
Mobile
Fullscreen