Update src/app/admin/page.tsx
This commit is contained in:
@@ -1,92 +1,613 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingInline from "@/components/navbar/NavbarLayoutFloatingInline";
|
||||
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
|
||||
import { Users, FileText, Star, BarChart3, Settings, LogOut } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Package,
|
||||
Image,
|
||||
Tag,
|
||||
FolderOpen,
|
||||
DollarSign,
|
||||
Box,
|
||||
ShoppingCart,
|
||||
Users,
|
||||
FileText,
|
||||
Image as ImageIcon,
|
||||
Star,
|
||||
Menu,
|
||||
X,
|
||||
Plus,
|
||||
Edit,
|
||||
Trash2,
|
||||
Search,
|
||||
ChevronRight,
|
||||
} from "lucide-react";
|
||||
|
||||
export default function AdminPage() {
|
||||
const [activeTab, setActiveTab] = useState("dashboard");
|
||||
type AdminTab =
|
||||
| "products"
|
||||
| "images"
|
||||
| "brands"
|
||||
| "categories"
|
||||
| "prices"
|
||||
| "stock"
|
||||
| "orders"
|
||||
| "customers"
|
||||
| "content"
|
||||
| "banners"
|
||||
| "reviews";
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
name: string;
|
||||
brand: string;
|
||||
price: number;
|
||||
stock: number;
|
||||
category: string;
|
||||
}
|
||||
|
||||
interface Order {
|
||||
id: string;
|
||||
customer: string;
|
||||
total: number;
|
||||
status: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
interface Customer {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
orders: number;
|
||||
spent: number;
|
||||
}
|
||||
|
||||
interface Review {
|
||||
id: string;
|
||||
product: string;
|
||||
author: string;
|
||||
rating: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export default function AdminDashboard() {
|
||||
const [activeTab, setActiveTab] = useState<AdminTab>("products");
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
|
||||
const navItems = [
|
||||
{ name: "Dashboard", id: "dashboard" },
|
||||
{ name: "Home", id: "home" },
|
||||
{ name: "Shop", id: "shop" },
|
||||
{ name: "Brands", id: "brands" },
|
||||
{ name: "New Arrivals", id: "new-arrivals" },
|
||||
{ name: "Best Sellers", id: "best-sellers" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "Contact", id: "contact" },
|
||||
{ name: "Admin", id: "admin" },
|
||||
];
|
||||
|
||||
const footerColumns = [
|
||||
{
|
||||
title: "Shop", items: [
|
||||
{ label: "All Products", href: "/shop" },
|
||||
{ label: "New Arrivals", href: "/shop" },
|
||||
{ label: "Best Sellers", href: "/shop" },
|
||||
{ label: "Brands", href: "/shop" },
|
||||
title: "Admin", items: [
|
||||
{ label: "Dashboard", href: "/admin" },
|
||||
{ label: "Analytics", href: "/admin" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// Sample data
|
||||
const products: Product[] = [
|
||||
{
|
||||
id: "1", name: "Air Max 90 Classic", brand: "Nike", price: 129.99,
|
||||
stock: 45,
|
||||
category: "Sneakers"},
|
||||
{
|
||||
id: "2", name: "Box Logo Hoodie", brand: "Supreme", price: 345.0,
|
||||
stock: 12,
|
||||
category: "Hoodies"},
|
||||
{
|
||||
id: "3", name: "Detroit Jacket", brand: "Carhartt WIP", price: 159.99,
|
||||
stock: 28,
|
||||
category: "Jackets"},
|
||||
];
|
||||
|
||||
const orders: Order[] = [
|
||||
{
|
||||
id: "ORD-001", customer: "John Doe", total: 299.99,
|
||||
status: "Shipped", date: "2025-01-15"},
|
||||
{
|
||||
id: "ORD-002", customer: "Jane Smith", total: 549.98,
|
||||
status: "Processing", date: "2025-01-16"},
|
||||
{
|
||||
id: "ORD-003", customer: "Bob Johnson", total: 189.99,
|
||||
status: "Delivered", date: "2025-01-14"},
|
||||
];
|
||||
|
||||
const customers: Customer[] = [
|
||||
{
|
||||
id: "C-001", name: "John Doe", email: "john@example.com", orders: 5,
|
||||
spent: 1299.95,
|
||||
},
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "/" },
|
||||
{ label: "Contact", href: "/" },
|
||||
{ label: "Blog", href: "/" },
|
||||
{ label: "Careers", href: "#" },
|
||||
],
|
||||
id: "C-002", name: "Jane Smith", email: "jane@example.com", orders: 3,
|
||||
spent: 849.99,
|
||||
},
|
||||
{
|
||||
title: "Support", items: [
|
||||
{ label: "Shipping & Returns", href: "/" },
|
||||
{ label: "FAQ", href: "/" },
|
||||
{ label: "Size Guide", href: "#" },
|
||||
{ label: "Track Order", href: "#" },
|
||||
],
|
||||
id: "C-003", name: "Bob Johnson", email: "bob@example.com", orders: 2,
|
||||
spent: 549.98,
|
||||
},
|
||||
];
|
||||
|
||||
const reviews: Review[] = [
|
||||
{
|
||||
title: "Legal", items: [
|
||||
{ label: "Privacy Policy", href: "#" },
|
||||
{ label: "Terms & Conditions", href: "#" },
|
||||
{ label: "Cookie Policy", href: "#" },
|
||||
{ label: "Accessibility", href: "#" },
|
||||
],
|
||||
},
|
||||
id: "R-001", product: "Air Max 90 Classic", author: "John D.", rating: 5,
|
||||
text: "Amazing quality and comfort. Highly recommend!"},
|
||||
{
|
||||
id: "R-002", product: "Box Logo Hoodie", author: "Jane S.", rating: 4,
|
||||
text: "Great piece, shipping was fast."},
|
||||
{
|
||||
id: "R-003", product: "Detroit Jacket", author: "Bob J.", rating: 5,
|
||||
text: "Perfect fit and authentic. Very satisfied."},
|
||||
];
|
||||
|
||||
const adminTabs = [
|
||||
{ id: "dashboard", label: "Analytics Dashboard", icon: BarChart3 },
|
||||
{ id: "customers", label: "Customer Management", icon: Users },
|
||||
{ id: "content", label: "Content & Banners", icon: FileText },
|
||||
{ id: "reviews", label: "Review Management", icon: Star },
|
||||
const menuItems = [
|
||||
{ id: "products" as AdminTab, label: "Products", icon: Package },
|
||||
{ id: "images" as AdminTab, label: "Images", icon: ImageIcon },
|
||||
{ id: "brands" as AdminTab, label: "Brands", icon: Tag },
|
||||
{ id: "categories" as AdminTab, label: "Categories", icon: FolderOpen },
|
||||
{ id: "prices" as AdminTab, label: "Prices", icon: DollarSign },
|
||||
{ id: "stock" as AdminTab, label: "Stock", icon: Box },
|
||||
{ id: "orders" as AdminTab, label: "Orders", icon: ShoppingCart },
|
||||
{ id: "customers" as AdminTab, label: "Customers", icon: Users },
|
||||
{ id: "content" as AdminTab, label: "Content", icon: FileText },
|
||||
{ id: "banners" as AdminTab, label: "Banners", icon: ImageIcon },
|
||||
{ id: "reviews" as AdminTab, label: "Reviews", icon: Star },
|
||||
];
|
||||
|
||||
const sampleMetrics = [
|
||||
{ label: "Total Revenue", value: "$45,230", change: "+12.5%" },
|
||||
{ label: "Total Orders", value: "1,248", change: "+8.2%" },
|
||||
{ label: "Active Customers", value: "523", change: "+5.3%" },
|
||||
{ label: "Conversion Rate", value: "3.2%", change: "+0.8%" },
|
||||
];
|
||||
const renderContent = () => {
|
||||
switch (activeTab) {
|
||||
case "products":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Products Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Add Product
|
||||
</button>
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b">
|
||||
<th className="p-3 text-left font-semibold">Name</th>
|
||||
<th className="p-3 text-left font-semibold">Brand</th>
|
||||
<th className="p-3 text-left font-semibold">Price</th>
|
||||
<th className="p-3 text-left font-semibold">Stock</th>
|
||||
<th className="p-3 text-left font-semibold">Category</th>
|
||||
<th className="p-3 text-left font-semibold">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{products.map((product) => (
|
||||
<tr key={product.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3">{product.name}</td>
|
||||
<td className="p-3">{product.brand}</td>
|
||||
<td className="p-3">${product.price.toFixed(2)}</td>
|
||||
<td className="p-3">{product.stock} units</td>
|
||||
<td className="p-3">{product.category}</td>
|
||||
<td className="p-3 flex gap-2">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
<button className="p-2 hover:bg-red-100 rounded-lg text-red-600">
|
||||
<Trash2 size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const sampleCustomers = [
|
||||
{ id: 1, name: "John Smith", email: "john@example.com", orders: 12, status: "Active" },
|
||||
{ id: 2, name: "Sarah Johnson", email: "sarah@example.com", orders: 8, status: "Active" },
|
||||
{ id: 3, name: "Mike Davis", email: "mike@example.com", orders: 5, status: "Inactive" },
|
||||
{ id: 4, name: "Emma Wilson", email: "emma@example.com", orders: 15, status: "Active" },
|
||||
];
|
||||
case "orders":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Orders Management</h2>
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b">
|
||||
<th className="p-3 text-left font-semibold">Order ID</th>
|
||||
<th className="p-3 text-left font-semibold">Customer</th>
|
||||
<th className="p-3 text-left font-semibold">Total</th>
|
||||
<th className="p-3 text-left font-semibold">Status</th>
|
||||
<th className="p-3 text-left font-semibold">Date</th>
|
||||
<th className="p-3 text-left font-semibold">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{orders.map((order) => (
|
||||
<tr key={order.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3 font-mono text-sm">{order.id}</td>
|
||||
<td className="p-3">{order.customer}</td>
|
||||
<td className="p-3">${order.total.toFixed(2)}</td>
|
||||
<td className="p-3">
|
||||
<span
|
||||
className={`px-3 py-1 rounded-full text-sm font-semibold ${
|
||||
order.status === "Delivered"
|
||||
? "bg-green-100 text-green-800"
|
||||
: order.status === "Shipped"
|
||||
? "bg-blue-100 text-blue-800"
|
||||
: "bg-yellow-100 text-yellow-800"
|
||||
}`}
|
||||
>
|
||||
{order.status}
|
||||
</span>
|
||||
</td>
|
||||
<td className="p-3">{order.date}</td>
|
||||
<td className="p-3 flex gap-2">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const sampleContent = [
|
||||
{ id: 1, title: "Summer Collection Banner", type: "Banner", status: "Published", date: "2025-01-15" },
|
||||
{ id: 2, title: "New Year Sale", type: "Banner", status: "Scheduled", date: "2025-02-01" },
|
||||
{ id: 3, title: "Blog Post: Style Guide", type: "Content", status: "Draft", date: "2025-01-10" },
|
||||
];
|
||||
case "customers":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Customers Management</h2>
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b">
|
||||
<th className="p-3 text-left font-semibold">Name</th>
|
||||
<th className="p-3 text-left font-semibold">Email</th>
|
||||
<th className="p-3 text-left font-semibold">Orders</th>
|
||||
<th className="p-3 text-left font-semibold">Total Spent</th>
|
||||
<th className="p-3 text-left font-semibold">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{customers.map((customer) => (
|
||||
<tr key={customer.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3">{customer.name}</td>
|
||||
<td className="p-3">{customer.email}</td>
|
||||
<td className="p-3">{customer.orders}</td>
|
||||
<td className="p-3">${customer.spent.toFixed(2)}</td>
|
||||
<td className="p-3 flex gap-2">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const sampleReviews = [
|
||||
{ id: 1, product: "Nike Air Max 90", rating: 5, author: "Alex Chen", status: "Approved", date: "2025-01-18" },
|
||||
{ id: 2, product: "Supreme Box Logo Hoodie", rating: 4, author: "Taylor Brown", status: "Pending", date: "2025-01-17" },
|
||||
{ id: 3, product: "Adidas Ultra Boost 22", rating: 5, author: "Jordan Lee", status: "Approved", date: "2025-01-16" },
|
||||
];
|
||||
case "reviews":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Reviews Management</h2>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{reviews.map((review) => (
|
||||
<div
|
||||
key={review.id}
|
||||
className="border rounded-lg p-4 hover:bg-gray-50 flex justify-between items-start"
|
||||
>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<h3 className="font-semibold">{review.product}</h3>
|
||||
<div className="flex gap-1">
|
||||
{[...Array(review.rating)].map((_, i) => (
|
||||
<Star key={i} size={16} className="fill-yellow-400 text-yellow-400" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 mb-2">By {review.author}</p>
|
||||
<p className="text-gray-700">{review.text}</p>
|
||||
</div>
|
||||
<div className="flex gap-2 ml-4">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
<button className="p-2 hover:bg-red-100 rounded-lg text-red-600">
|
||||
<Trash2 size={18} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "images":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Images Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Upload Image
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
|
||||
<div key={i} className="border rounded-lg overflow-hidden hover:shadow-lg">
|
||||
<div className="bg-gray-200 h-40 flex items-center justify-center">
|
||||
<ImageIcon size={40} className="text-gray-400" />
|
||||
</div>
|
||||
<div className="p-3 space-y-2">
|
||||
<p className="text-sm font-semibold">Image {i}</p>
|
||||
<div className="flex gap-2">
|
||||
<button className="flex-1 p-2 hover:bg-blue-100 rounded text-blue-600 text-sm">
|
||||
<Edit size={16} className="inline" /> Edit
|
||||
</button>
|
||||
<button className="flex-1 p-2 hover:bg-red-100 rounded text-red-600 text-sm">
|
||||
<Trash2 size={16} className="inline" /> Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "brands":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Brands Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Add Brand
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{["Nike", "Adidas", "Supreme", "Carhartt WIP", "The North Face", "Stüssy"].map(
|
||||
(brand, i) => (
|
||||
<div key={i} className="border rounded-lg p-4 hover:bg-gray-50">
|
||||
<h3 className="font-semibold mb-3">{brand}</h3>
|
||||
<div className="flex gap-2">
|
||||
<button className="flex-1 p-2 hover:bg-blue-100 rounded-lg text-blue-600 text-sm">
|
||||
<Edit size={16} className="inline" />
|
||||
</button>
|
||||
<button className="flex-1 p-2 hover:bg-red-100 rounded-lg text-red-600 text-sm">
|
||||
<Trash2 size={16} className="inline" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "categories":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Categories Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Add Category
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{["Sneakers", "Hoodies", "Jackets", "T-Shirts", "Pants", "Accessories"].map(
|
||||
(category, i) => (
|
||||
<div key={i} className="border rounded-lg p-4 flex justify-between items-center hover:bg-gray-50">
|
||||
<span className="font-semibold">{category}</span>
|
||||
<div className="flex gap-2">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
<button className="p-2 hover:bg-red-100 rounded-lg text-red-600">
|
||||
<Trash2 size={18} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "prices":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Prices Management</h2>
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b">
|
||||
<th className="p-3 text-left font-semibold">Product</th>
|
||||
<th className="p-3 text-left font-semibold">Current Price</th>
|
||||
<th className="p-3 text-left font-semibold">Cost</th>
|
||||
<th className="p-3 text-left font-semibold">Margin</th>
|
||||
<th className="p-3 text-left font-semibold">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{products.map((product) => (
|
||||
<tr key={product.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3">{product.name}</td>
|
||||
<td className="p-3">${product.price.toFixed(2)}</td>
|
||||
<td className="p-3">${(product.price * 0.6).toFixed(2)}</td>
|
||||
<td className="p-3">40%</td>
|
||||
<td className="p-3">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "stock":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Stock Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Add Stock
|
||||
</button>
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-100 border-b">
|
||||
<th className="p-3 text-left font-semibold">Product</th>
|
||||
<th className="p-3 text-left font-semibold">Current Stock</th>
|
||||
<th className="p-3 text-left font-semibold">Reorder Level</th>
|
||||
<th className="p-3 text-left font-semibold">Status</th>
|
||||
<th className="p-3 text-left font-semibold">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{products.map((product) => (
|
||||
<tr key={product.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3">{product.name}</td>
|
||||
<td className="p-3">{product.stock} units</td>
|
||||
<td className="p-3">10 units</td>
|
||||
<td className="p-3">
|
||||
<span className="px-3 py-1 rounded-full text-sm font-semibold bg-green-100 text-green-800">
|
||||
In Stock
|
||||
</span>
|
||||
</td>
|
||||
<td className="p-3">
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "content":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Content Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Add Content
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{[
|
||||
{ id: 1, title: "Home Page Hero", type: "Hero Section", status: "Published" },
|
||||
{ id: 2, title: "About Us", type: "Text Page", status: "Draft" },
|
||||
{ id: 3, title: "FAQs", type: "FAQ Section", status: "Published" },
|
||||
].map((content) => (
|
||||
<div key={content.id} className="border rounded-lg p-4 flex justify-between items-center hover:bg-gray-50">
|
||||
<div>
|
||||
<h3 className="font-semibold">{content.title}</h3>
|
||||
<p className="text-sm text-gray-600">{content.type}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span
|
||||
className={`px-3 py-1 rounded-full text-sm font-semibold ${
|
||||
content.status === "Published"
|
||||
? "bg-green-100 text-green-800"
|
||||
: "bg-gray-100 text-gray-800"
|
||||
}`}
|
||||
>
|
||||
{content.status}
|
||||
</span>
|
||||
<button className="p-2 hover:bg-blue-100 rounded-lg text-blue-600">
|
||||
<Edit size={18} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "banners":
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Banners Management</h2>
|
||||
<button className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700">
|
||||
<Plus size={20} />
|
||||
Add Banner
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<div key={i} className="border rounded-lg overflow-hidden hover:shadow-lg">
|
||||
<div className="bg-gradient-to-r from-blue-400 to-purple-500 h-32 flex items-center justify-center text-white font-bold text-lg">
|
||||
Banner {i}
|
||||
</div>
|
||||
<div className="p-3 space-y-2">
|
||||
<p className="text-sm font-semibold">Banner Title {i}</p>
|
||||
<div className="flex gap-2">
|
||||
<button className="flex-1 p-2 hover:bg-blue-100 rounded text-blue-600 text-sm">
|
||||
<Edit size={16} className="inline" /> Edit
|
||||
</button>
|
||||
<button className="flex-1 p-2 hover:bg-red-100 rounded text-red-600 text-sm">
|
||||
<Trash2 size={16} className="inline" /> Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-2xl font-bold">Dashboard Overview</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<div className="border rounded-lg p-4">
|
||||
<p className="text-gray-600 text-sm">Total Products</p>
|
||||
<p className="text-3xl font-bold mt-2">1,247</p>
|
||||
</div>
|
||||
<div className="border rounded-lg p-4">
|
||||
<p className="text-gray-600 text-sm">Total Orders</p>
|
||||
<p className="text-3xl font-bold mt-2">356</p>
|
||||
</div>
|
||||
<div className="border rounded-lg p-4">
|
||||
<p className="text-gray-600 text-sm">Total Customers</p>
|
||||
<p className="text-3xl font-bold mt-2">892</p>
|
||||
</div>
|
||||
<div className="border rounded-lg p-4">
|
||||
<p className="text-gray-600 text-sm">Revenue</p>
|
||||
<p className="text-3xl font-bold mt-2">$45,230</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
@@ -104,9 +625,9 @@ export default function AdminPage() {
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingInline
|
||||
navItems={navItems}
|
||||
brandName="garraagarmzz Admin"
|
||||
brandName="Admin Dashboard"
|
||||
button={{
|
||||
text: "Dashboard", href: "#"}}
|
||||
text: "Back to Store", href: "/"}}
|
||||
animateOnLoad={true}
|
||||
className="bg-opacity-95"
|
||||
navItemClassName="text-sm font-medium"
|
||||
@@ -115,181 +636,56 @@ export default function AdminPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen bg-gradient-to-br from-background to-background-accent py-16 px-4">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Admin Header */}
|
||||
<div className="mb-12">
|
||||
<h1 className="text-4xl font-bold mb-4">Admin Dashboard</h1>
|
||||
<p className="text-foreground/70">Manage customers, content, reviews, and analytics</p>
|
||||
<div className="flex h-screen overflow-hidden bg-gray-50 mt-20">
|
||||
{/* Sidebar */}
|
||||
<div
|
||||
className={`${
|
||||
sidebarOpen ? "w-64" : "w-20"
|
||||
} bg-white border-r border-gray-200 transition-all duration-300 overflow-y-auto`}
|
||||
>
|
||||
<div className="p-4 flex justify-between items-center">
|
||||
<h1 className={`font-bold text-lg ${!sidebarOpen && "hidden"}`}>Admin Panel</h1>
|
||||
<button
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
className="p-2 hover:bg-gray-100 rounded-lg"
|
||||
>
|
||||
{sidebarOpen ? <X size={20} /> : <Menu size={20} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<div className="flex flex-wrap gap-4 mb-8 border-b border-foreground/10 pb-4">
|
||||
{adminTabs.map((tab) => {
|
||||
const Icon = tab.icon;
|
||||
<nav className="mt-8">
|
||||
{menuItems.map((item) => {
|
||||
const IconComponent = item.icon;
|
||||
return (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
className={`flex items-center gap-2 px-6 py-3 rounded-lg transition-all ${
|
||||
activeTab === tab.id
|
||||
? "bg-primary-cta text-white"
|
||||
: "bg-card text-foreground hover:bg-card/80"
|
||||
key={item.id}
|
||||
onClick={() => setActiveTab(item.id)}
|
||||
className={`w-full flex items-center gap-3 px-4 py-3 transition-colors ${
|
||||
activeTab === item.id
|
||||
? "bg-blue-50 text-blue-600 border-r-4 border-blue-600"
|
||||
: "text-gray-700 hover:bg-gray-50"
|
||||
}`}
|
||||
>
|
||||
<Icon size={18} />
|
||||
{tab.label}
|
||||
<IconComponent size={20} />
|
||||
{sidebarOpen && <span>{item.label}</span>}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Analytics Dashboard Tab */}
|
||||
{activeTab === "dashboard" && (
|
||||
<div id="analytics-dashboard" data-section="analytics-dashboard">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
{sampleMetrics.map((metric, idx) => (
|
||||
<div key={idx} className="bg-card border border-foreground/10 rounded-lg p-6">
|
||||
<p className="text-foreground/70 text-sm mb-2">{metric.label}</p>
|
||||
<p className="text-3xl font-bold mb-2">{metric.value}</p>
|
||||
<p className="text-accent text-sm">{metric.change}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Analytics Charts Placeholder */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<div className="bg-card border border-foreground/10 rounded-lg p-8 h-80 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<BarChart3 size={48} className="mx-auto mb-4 text-primary-cta/50" />
|
||||
<p className="text-foreground/70">Revenue Chart</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-card border border-foreground/10 rounded-lg p-8 h-80 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<BarChart3 size={48} className="mx-auto mb-4 text-primary-cta/50" />
|
||||
<p className="text-foreground/70">Orders Chart</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Customer Management Tab */}
|
||||
{activeTab === "customers" && (
|
||||
<div id="customer-management" data-section="customer-management">
|
||||
<div className="bg-card border border-foreground/10 rounded-lg overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead className="bg-foreground/5 border-b border-foreground/10">
|
||||
<tr>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Name</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Email</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Orders</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Status</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{sampleCustomers.map((customer) => (
|
||||
<tr key={customer.id} className="border-b border-foreground/5 hover:bg-foreground/2">
|
||||
<td className="px-6 py-4">{customer.name}</td>
|
||||
<td className="px-6 py-4 text-foreground/70">{customer.email}</td>
|
||||
<td className="px-6 py-4">{customer.orders}</td>
|
||||
<td className="px-6 py-4">
|
||||
<span className={`px-3 py-1 rounded-full text-xs font-medium ${
|
||||
customer.status === "Active" ? "bg-green-500/20 text-green-600" : "bg-gray-500/20 text-gray-600"
|
||||
}`}>
|
||||
{customer.status}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-6 py-4 text-sm text-primary-cta cursor-pointer hover:underline">Edit</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Content & Banner Management Tab */}
|
||||
{activeTab === "content" && (
|
||||
<div id="content-management" data-section="content-management">
|
||||
<div className="mb-6 flex justify-between items-center">
|
||||
<h2 className="text-xl font-semibold">Content & Banners</h2>
|
||||
<button className="bg-primary-cta text-white px-6 py-2 rounded-lg hover:opacity-90 transition-opacity">
|
||||
+ Add New
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{sampleContent.map((item) => (
|
||||
<div key={item.id} className="bg-card border border-foreground/10 rounded-lg p-6 flex justify-between items-center">
|
||||
<div>
|
||||
<h3 className="font-semibold mb-2">{item.title}</h3>
|
||||
<p className="text-foreground/70 text-sm">{item.type} • {item.date}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className={`px-3 py-1 rounded-full text-xs font-medium ${
|
||||
item.status === "Published" ? "bg-blue-500/20 text-blue-600" :
|
||||
item.status === "Scheduled" ? "bg-yellow-500/20 text-yellow-600" :
|
||||
"bg-gray-500/20 text-gray-600"
|
||||
}`}>
|
||||
{item.status}
|
||||
</span>
|
||||
<button className="text-primary-cta hover:underline text-sm">Edit</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Review Management Tab */}
|
||||
{activeTab === "reviews" && (
|
||||
<div id="review-management" data-section="review-management">
|
||||
<div className="space-y-4">
|
||||
{sampleReviews.map((review) => (
|
||||
<div key={review.id} className="bg-card border border-foreground/10 rounded-lg p-6">
|
||||
<div className="flex justify-between items-start mb-4">
|
||||
<div>
|
||||
<h3 className="font-semibold mb-1">{review.product}</h3>
|
||||
<p className="text-foreground/70 text-sm">By {review.author}</p>
|
||||
</div>
|
||||
<span className={`px-3 py-1 rounded-full text-xs font-medium ${
|
||||
review.status === "Approved" ? "bg-green-500/20 text-green-600" : "bg-yellow-500/20 text-yellow-600"
|
||||
}`}>
|
||||
{review.status}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex gap-1">
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<Star key={i} size={16} className={i < review.rating ? "fill-yellow-400 text-yellow-400" : "text-foreground/20"} />
|
||||
))}
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
{review.status === "Pending" && (
|
||||
<>
|
||||
<button className="text-green-600 hover:underline text-sm">Approve</button>
|
||||
<button className="text-red-600 hover:underline text-sm">Reject</button>
|
||||
</>
|
||||
)}
|
||||
<button className="text-primary-cta hover:underline text-sm">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{/* Main Content */}
|
||||
<div className="flex-1 overflow-auto">
|
||||
<div className="p-8">{renderContent()}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<div id="footer" data-section="footer" className="mt-12">
|
||||
<FooterBaseCard
|
||||
logoText="garraagarmzz"
|
||||
copyrightText="© 2025 garraagarmzz. All rights reserved. Curated Fashion From The Best Brands."
|
||||
logoText="garraagarmzz Admin"
|
||||
copyrightText="© 2025 garraagarmzz Admin Dashboard. All rights reserved."
|
||||
columns={footerColumns}
|
||||
ariaLabel="Site footer with navigation and company information"
|
||||
ariaLabel="Admin footer"
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
|
||||
Reference in New Issue
Block a user