219 lines
8.9 KiB
TypeScript
219 lines
8.9 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState } from 'react';
|
|
import Sidebar from '@/components/Sidebar';
|
|
import ProductTable, { Product } from '@/components/ProductTable';
|
|
|
|
const sampleProducts: Product[] = [
|
|
{
|
|
id: 'PRD-001',
|
|
name: 'Organic Butter',
|
|
category: 'Dairy',
|
|
subcategory: 'Butter & Spreads',
|
|
quantity: 25,
|
|
unit: 'kg',
|
|
unitPrice: 4.50,
|
|
vat: 9,
|
|
supplier: 'DairyFresh Co.',
|
|
lastUpdated: '2026-02-10',
|
|
},
|
|
{
|
|
id: 'PRD-002',
|
|
name: 'All-Purpose Flour',
|
|
category: 'Dry Goods',
|
|
subcategory: 'Flours',
|
|
quantity: 150,
|
|
unit: 'kg',
|
|
unitPrice: 0.85,
|
|
vat: 9,
|
|
supplier: 'GrainMasters',
|
|
lastUpdated: '2026-02-09',
|
|
},
|
|
{
|
|
id: 'PRD-003',
|
|
name: 'Atlantic Salmon Fillet',
|
|
category: 'Seafood',
|
|
subcategory: 'Fresh Fish',
|
|
quantity: 12,
|
|
unit: 'kg',
|
|
unitPrice: 18.90,
|
|
vat: 9,
|
|
supplier: 'OceanHarvest',
|
|
lastUpdated: '2026-02-11',
|
|
},
|
|
{
|
|
id: 'PRD-004',
|
|
name: 'Madagascar Vanilla Extract',
|
|
category: 'Dry Goods',
|
|
subcategory: 'Spices & Extracts',
|
|
quantity: 8,
|
|
unit: 'L',
|
|
unitPrice: 45.00,
|
|
vat: 21,
|
|
supplier: 'SpiceWorld Ltd',
|
|
lastUpdated: '2026-02-08',
|
|
},
|
|
{
|
|
id: 'PRD-005',
|
|
name: 'Fresh Avocados',
|
|
category: 'Produce',
|
|
subcategory: 'Fruits',
|
|
quantity: 40,
|
|
unit: 'pcs',
|
|
unitPrice: 1.20,
|
|
vat: 9,
|
|
supplier: 'FreshFarm Direct',
|
|
lastUpdated: '2026-02-11',
|
|
},
|
|
];
|
|
|
|
export default function ProductsPage() {
|
|
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
|
|
|
return (
|
|
<div className="flex min-h-screen bg-gray-50">
|
|
<Sidebar isOpen={isSidebarOpen} onClose={() => setIsSidebarOpen(false)} />
|
|
|
|
<main className="flex-1 lg:ml-64">
|
|
{/* Mobile Header */}
|
|
<div className="lg:hidden sticky top-0 z-30 bg-white border-b border-gray-200 px-4 py-3">
|
|
<div className="flex items-center justify-between">
|
|
<button
|
|
onClick={() => setIsSidebarOpen(true)}
|
|
className="text-gray-500 hover:text-gray-700"
|
|
>
|
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
|
</svg>
|
|
</button>
|
|
<h1 className="text-lg font-bold text-gray-900">KitchenOS</h1>
|
|
<div className="w-6" /> {/* Spacer for centering */}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="p-4 sm:p-6 lg:p-8">
|
|
{/* Header */}
|
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6 lg:mb-8">
|
|
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900">Product Management</h1>
|
|
<div className="flex gap-2 sm:gap-3">
|
|
<button className="flex-1 sm:flex-none px-4 sm:px-5 py-2.5 rounded-lg border border-gray-300 bg-white text-gray-700 font-medium hover:bg-gray-50 transition-colors text-sm sm:text-base">
|
|
Import
|
|
</button>
|
|
<button className="flex-1 sm:flex-none px-4 sm:px-5 py-2.5 rounded-lg bg-blue-600 text-white font-medium hover:bg-blue-700 transition-colors text-sm sm:text-base whitespace-nowrap">
|
|
+ Create Product
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Filters and Search */}
|
|
<div className="bg-white rounded-lg border border-gray-200 p-4 sm:p-6 mb-4 sm:mb-6">
|
|
<div className="flex flex-col sm:flex-row sm:flex-wrap items-stretch sm:items-center gap-3 sm:gap-4 mb-4">
|
|
{/* Search */}
|
|
<div className="w-full sm:flex-1 sm:min-w-[250px]">
|
|
<div className="relative">
|
|
<input
|
|
type="text"
|
|
placeholder="Search by name, ID, or supplier…"
|
|
className="w-full px-4 py-2.5 pl-10 rounded-lg border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none text-sm sm:text-base"
|
|
/>
|
|
<svg
|
|
className="absolute left-3 top-3 w-5 h-5 text-gray-400"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Filters Row */}
|
|
<div className="grid grid-cols-2 sm:flex gap-2 sm:gap-3">
|
|
{/* Category Filter */}
|
|
<select className="px-3 sm:px-4 py-2.5 rounded-lg border border-gray-300 bg-white text-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none text-sm sm:text-base">
|
|
<option>Categories</option>
|
|
<option>Dairy</option>
|
|
<option>Dry Goods</option>
|
|
<option>Seafood</option>
|
|
<option>Produce</option>
|
|
</select>
|
|
|
|
{/* Subcategory Filter */}
|
|
<select className="px-3 sm:px-4 py-2.5 rounded-lg border border-gray-300 bg-white text-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none text-sm sm:text-base">
|
|
<option>Subcategories</option>
|
|
<option>Butter & Spreads</option>
|
|
<option>Flours</option>
|
|
<option>Fresh Fish</option>
|
|
<option>Spices & Extracts</option>
|
|
<option>Fruits</option>
|
|
</select>
|
|
|
|
{/* Bulk Actions */}
|
|
<button className="col-span-2 sm:col-span-1 px-3 sm:px-4 py-2.5 rounded-lg border border-gray-300 bg-white text-gray-700 font-medium hover:bg-gray-50 transition-colors text-sm sm:text-base">
|
|
Bulk Actions
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Active Filters */}
|
|
<div className="flex flex-col sm:flex-row sm:items-center gap-2">
|
|
<span className="text-sm text-gray-600">Active filters:</span>
|
|
<div className="flex flex-wrap gap-2">
|
|
<span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full bg-blue-50 text-blue-700 text-xs sm:text-sm font-medium">
|
|
Category: Dry Goods
|
|
<button className="hover:text-blue-900">
|
|
<svg className="w-3 h-3 sm:w-4 sm:h-4" fill="currentColor" viewBox="0 0 20 20">
|
|
<path
|
|
fillRule="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"
|
|
clipRule="evenodd"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</span>
|
|
</div>
|
|
<button className="text-xs sm:text-sm text-blue-600 hover:text-blue-800 font-medium sm:ml-2 self-start">
|
|
Clear all
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Product Table */}
|
|
<ProductTable products={sampleProducts} />
|
|
|
|
{/* Pagination */}
|
|
<div className="mt-4 sm:mt-6 flex flex-col sm:flex-row items-center justify-between gap-4">
|
|
<p className="text-xs sm:text-sm text-gray-600 text-center sm:text-left">
|
|
Showing <span className="font-medium">1</span> to{' '}
|
|
<span className="font-medium">5</span> of{' '}
|
|
<span className="font-medium">5</span> results
|
|
</p>
|
|
<div className="flex items-center gap-1 sm:gap-2">
|
|
<button className="px-2 sm:px-3 py-2 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-xs sm:text-sm" disabled>
|
|
Previous
|
|
</button>
|
|
<button className="px-2 sm:px-3 py-2 rounded-lg bg-blue-600 text-white font-medium text-xs sm:text-sm min-w-[32px] sm:min-w-[36px]">
|
|
1
|
|
</button>
|
|
<button className="px-2 sm:px-3 py-2 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 transition-colors text-xs sm:text-sm min-w-[32px] sm:min-w-[36px]">
|
|
2
|
|
</button>
|
|
<button className="hidden sm:block px-3 py-2 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 transition-colors text-sm">
|
|
3
|
|
</button>
|
|
<button className="px-2 sm:px-3 py-2 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 transition-colors text-xs sm:text-sm">
|
|
Next
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|