Add src/app/admin/page.tsx
This commit is contained in:
373
src/app/admin/page.tsx
Normal file
373
src/app/admin/page.tsx
Normal file
@@ -0,0 +1,373 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import { useState } from "react";
|
||||
import { LayoutDashboard, Menu, ShoppingCart, BarChart3, LogOut } from "lucide-react";
|
||||
|
||||
interface MenuItem {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
price: string;
|
||||
category: string;
|
||||
available: boolean;
|
||||
}
|
||||
|
||||
interface Order {
|
||||
id: string;
|
||||
customerName: string;
|
||||
items: string;
|
||||
status: string;
|
||||
totalAmount: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
const initialMenuItems: MenuItem[] = [
|
||||
{
|
||||
id: "1", name: "Biryani Special", description: "Fragrant rice with tender meat", price: "450", category: "Main Course", available: true
|
||||
},
|
||||
{
|
||||
id: "2", name: "Seekh Kebab", description: "Spiced minced meat kebab", price: "350", category: "Appetizers", available: true
|
||||
},
|
||||
{
|
||||
id: "3", name: "Chicken Karahi", description: "Spicy chicken with peppers and tomatoes", price: "400", category: "Main Course", available: false
|
||||
}
|
||||
];
|
||||
|
||||
const initialOrders: Order[] = [
|
||||
{
|
||||
id: "ORD001", customerName: "Ahmed Khan", items: "Biryani x2, Seekh Kebab x3", status: "Completed", totalAmount: "1250", timestamp: "2025-01-15 14:30"
|
||||
},
|
||||
{
|
||||
id: "ORD002", customerName: "Fatima Hassan", items: "Chicken Karahi x1, Naan x2", status: "In Progress", totalAmount: "550", timestamp: "2025-01-15 14:45"
|
||||
},
|
||||
{
|
||||
id: "ORD003", customerName: "Muhammad Ali", items: "Biryani x1", status: "Pending", totalAmount: "450", timestamp: "2025-01-15 15:00"
|
||||
}
|
||||
];
|
||||
|
||||
export default function AdminPanel() {
|
||||
const [activeTab, setActiveTab] = useState<"dashboard" | "menu" | "orders">("dashboard");
|
||||
const [menuItems, setMenuItems] = useState<MenuItem[]>(initialMenuItems);
|
||||
const [orders, setOrders] = useState<Order[]>(initialOrders);
|
||||
const [selectedMenuItem, setSelectedMenuItem] = useState<MenuItem | null>(null);
|
||||
const [editForm, setEditForm] = useState<Partial<MenuItem>>({});
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
|
||||
const toggleItemAvailability = (id: string) => {
|
||||
setMenuItems(menuItems.map(item =>
|
||||
item.id === id ? { ...item, available: !item.available } : item
|
||||
));
|
||||
};
|
||||
|
||||
const handleEditItem = (item: MenuItem) => {
|
||||
setSelectedMenuItem(item);
|
||||
setEditForm(item);
|
||||
setShowForm(true);
|
||||
};
|
||||
|
||||
const handleSaveItem = () => {
|
||||
if (selectedMenuItem) {
|
||||
setMenuItems(menuItems.map(item =>
|
||||
item.id === selectedMenuItem.id ? { ...item, ...editForm } : item
|
||||
));
|
||||
}
|
||||
setShowForm(false);
|
||||
setSelectedMenuItem(null);
|
||||
setEditForm({});
|
||||
};
|
||||
|
||||
const handleAddItem = () => {
|
||||
const newItem: MenuItem = {
|
||||
id: String(menuItems.length + 1),
|
||||
name: editForm.name || "", description: editForm.description || "", price: editForm.price || "", category: editForm.category || "", available: true
|
||||
};
|
||||
setMenuItems([...menuItems, newItem]);
|
||||
setShowForm(false);
|
||||
setEditForm({});
|
||||
};
|
||||
|
||||
const updateOrderStatus = (id: string, newStatus: string) => {
|
||||
setOrders(orders.map(order =>
|
||||
order.id === id ? { ...order, status: newStatus } : order
|
||||
));
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="compact"
|
||||
sizing="largeSmallSizeMediumTitles"
|
||||
background="fluid"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<div className="min-h-screen bg-background text-foreground">
|
||||
{/* Header */}
|
||||
<div className="border-b border-accent bg-card p-4">
|
||||
<div className="max-w-7xl mx-auto flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<LayoutDashboard className="w-8 h-8 text-primary-cta" />
|
||||
<h1 className="text-2xl font-bold">Baidar G Restaurant Admin</h1>
|
||||
</div>
|
||||
<button className="flex items-center gap-2 text-sm bg-secondary-cta px-4 py-2 rounded-lg hover:opacity-80 transition">
|
||||
<LogOut className="w-4 h-4" />
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation Tabs */}
|
||||
<div className="border-b border-accent bg-card">
|
||||
<div className="max-w-7xl mx-auto flex items-center gap-8 px-4">
|
||||
<button
|
||||
onClick={() => setActiveTab("dashboard")}
|
||||
className={`py-4 font-medium transition flex items-center gap-2 ${
|
||||
activeTab === "dashboard"
|
||||
? "text-primary-cta border-b-2 border-primary-cta"
|
||||
: "text-foreground/60 hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
<BarChart3 className="w-4 h-4" />
|
||||
Dashboard
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("menu")}
|
||||
className={`py-4 font-medium transition flex items-center gap-2 ${
|
||||
activeTab === "menu"
|
||||
? "text-primary-cta border-b-2 border-primary-cta"
|
||||
: "text-foreground/60 hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
<Menu className="w-4 h-4" />
|
||||
Menu Management
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("orders")}
|
||||
className={`py-4 font-medium transition flex items-center gap-2 ${
|
||||
activeTab === "orders"
|
||||
? "text-primary-cta border-b-2 border-primary-cta"
|
||||
: "text-foreground/60 hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
<ShoppingCart className="w-4 h-4" />
|
||||
Order Management
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="max-w-7xl mx-auto p-6">
|
||||
{/* Dashboard Tab */}
|
||||
{activeTab === "dashboard" && (
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-2xl font-bold">Dashboard Overview</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="bg-card rounded-lg p-6 border border-accent">
|
||||
<p className="text-foreground/60 text-sm">Total Orders Today</p>
|
||||
<p className="text-4xl font-bold text-primary-cta mt-2">{orders.length}</p>
|
||||
<p className="text-sm text-foreground/50 mt-2">Active and completed</p>
|
||||
</div>
|
||||
<div className="bg-card rounded-lg p-6 border border-accent">
|
||||
<p className="text-foreground/60 text-sm">Menu Items</p>
|
||||
<p className="text-4xl font-bold text-primary-cta mt-2">{menuItems.length}</p>
|
||||
<p className="text-sm text-foreground/50 mt-2">{menuItems.filter(i => i.available).length} available</p>
|
||||
</div>
|
||||
<div className="bg-card rounded-lg p-6 border border-accent">
|
||||
<p className="text-foreground/60 text-sm">Total Revenue</p>
|
||||
<p className="text-4xl font-bold text-primary-cta mt-2">PKR {orders.reduce((sum, o) => sum + parseInt(o.totalAmount), 0).toLocaleString()}</p>
|
||||
<p className="text-sm text-foreground/50 mt-2">Today's earnings</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-8">
|
||||
<h3 className="text-lg font-bold mb-4">Recent Orders</h3>
|
||||
<div className="space-y-2 max-h-80 overflow-y-auto">
|
||||
{orders.map(order => (
|
||||
<div key={order.id} className="flex items-center justify-between bg-card rounded-lg p-4 border border-accent hover:border-primary-cta transition">
|
||||
<div className="flex-1">
|
||||
<p className="font-semibold">{order.customerName}</p>
|
||||
<p className="text-sm text-foreground/60">{order.items}</p>
|
||||
<p className="text-xs text-foreground/50 mt-1">{order.timestamp}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className={`px-3 py-1 rounded text-xs font-medium ${
|
||||
order.status === "Completed" ? "bg-green-500/20 text-green-600" :
|
||||
order.status === "In Progress" ? "bg-blue-500/20 text-blue-600" :
|
||||
"bg-yellow-500/20 text-yellow-600"
|
||||
}`}>
|
||||
{order.status}
|
||||
</span>
|
||||
<p className="font-semibold">PKR {order.totalAmount}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Menu Management Tab */}
|
||||
{activeTab === "menu" && (
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="text-2xl font-bold">Menu Management</h2>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSelectedMenuItem(null);
|
||||
setEditForm({});
|
||||
setShowForm(true);
|
||||
}}
|
||||
className="bg-primary-cta text-white px-4 py-2 rounded-lg hover:opacity-90 transition"
|
||||
>
|
||||
Add New Item
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Add/Edit Form */}
|
||||
{showForm && (
|
||||
<div className="bg-card rounded-lg p-6 border border-accent space-y-4">
|
||||
<h3 className="text-lg font-bold">{selectedMenuItem ? "Edit Item" : "Add New Item"}</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Item Name"
|
||||
value={editForm.name || ""}
|
||||
onChange={(e) => setEditForm({ ...editForm, name: e.target.value })}
|
||||
className="bg-background border border-accent rounded px-3 py-2 text-foreground placeholder:text-foreground/50"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Price"
|
||||
value={editForm.price || ""}
|
||||
onChange={(e) => setEditForm({ ...editForm, price: e.target.value })}
|
||||
className="bg-background border border-accent rounded px-3 py-2 text-foreground placeholder:text-foreground/50"
|
||||
/>
|
||||
<select
|
||||
value={editForm.category || ""}
|
||||
onChange={(e) => setEditForm({ ...editForm, category: e.target.value })}
|
||||
className="bg-background border border-accent rounded px-3 py-2 text-foreground"
|
||||
>
|
||||
<option value="">Select Category</option>
|
||||
<option value="Main Course">Main Course</option>
|
||||
<option value="Appetizers">Appetizers</option>
|
||||
<option value="Desserts">Desserts</option>
|
||||
<option value="Beverages">Beverages</option>
|
||||
</select>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Description"
|
||||
value={editForm.description || ""}
|
||||
onChange={(e) => setEditForm({ ...editForm, description: e.target.value })}
|
||||
className="bg-background border border-accent rounded px-3 py-2 text-foreground placeholder:text-foreground/50 md:col-span-2"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={selectedMenuItem ? handleSaveItem : handleAddItem}
|
||||
className="bg-primary-cta text-white px-4 py-2 rounded-lg hover:opacity-90 transition"
|
||||
>
|
||||
{selectedMenuItem ? "Save Changes" : "Add Item"}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setShowForm(false);
|
||||
setSelectedMenuItem(null);
|
||||
setEditForm({});
|
||||
}}
|
||||
className="bg-secondary-cta text-foreground px-4 py-2 rounded-lg hover:opacity-90 transition"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Menu Items List */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{menuItems.map(item => (
|
||||
<div key={item.id} className="bg-card rounded-lg p-4 border border-accent hover:border-primary-cta transition">
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<div>
|
||||
<h4 className="font-semibold text-lg">{item.name}</h4>
|
||||
<p className="text-sm text-foreground/60">{item.category}</p>
|
||||
</div>
|
||||
<span className={`px-2 py-1 rounded text-xs font-medium ${
|
||||
item.available ? "bg-green-500/20 text-green-600" : "bg-red-500/20 text-red-600"
|
||||
}`}>
|
||||
{item.available ? "Available" : "Unavailable"}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-foreground/70 mb-4">{item.description}</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-xl font-bold text-primary-cta">PKR {item.price}</p>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => toggleItemAvailability(item.id)}
|
||||
className="bg-secondary-cta px-3 py-1 rounded text-sm hover:opacity-90 transition"
|
||||
>
|
||||
{item.available ? "Mark Unavailable" : "Mark Available"}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleEditItem(item)}
|
||||
className="bg-primary-cta text-white px-3 py-1 rounded text-sm hover:opacity-90 transition"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Order Management Tab */}
|
||||
{activeTab === "orders" && (
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-2xl font-bold">Order Management</h2>
|
||||
<div className="space-y-3">
|
||||
{orders.map(order => (
|
||||
<div key={order.id} className="bg-card rounded-lg p-4 border border-accent hover:border-primary-cta transition">
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<div>
|
||||
<h4 className="font-semibold text-lg">{order.id}</h4>
|
||||
<p className="text-sm text-foreground/60">{order.customerName}</p>
|
||||
</div>
|
||||
<span className={`px-3 py-1 rounded text-xs font-medium ${
|
||||
order.status === "Completed" ? "bg-green-500/20 text-green-600" :
|
||||
order.status === "In Progress" ? "bg-blue-500/20 text-blue-600" :
|
||||
"bg-yellow-500/20 text-yellow-600"
|
||||
}`}>
|
||||
{order.status}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-foreground/70 mb-3">{order.items}</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-xs text-foreground/50">{order.timestamp}</p>
|
||||
<p className="text-lg font-bold text-primary-cta mt-1">PKR {order.totalAmount}</p>
|
||||
</div>
|
||||
<select
|
||||
value={order.status}
|
||||
onChange={(e) => updateOrderStatus(order.id, e.target.value)}
|
||||
className="bg-background border border-accent rounded px-3 py-2 text-foreground text-sm"
|
||||
>
|
||||
<option value="Pending">Pending</option>
|
||||
<option value="In Progress">In Progress</option>
|
||||
<option value="Completed">Completed</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user