- Added ProductsIndex.vue for displaying and managing products. - Created index.html for the product management interface. - Developed productService.ts for API interactions related to products. - Established productStore.ts using Pinia for state management of products. - Defined product types in product.d.ts for TypeScript support. - Integrated toast notifications and confirmation dialogs for user feedback. - Implemented pagination and search functionality in the product table. - Added form for creating and editing products with validation.
364 lines
28 KiB
HTML
364 lines
28 KiB
HTML
<!DOCTYPE html>
|
|
<html class="light" lang="en">
|
|
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
|
<title>WMS - Add New Product</title>
|
|
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap"
|
|
rel="stylesheet" />
|
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
|
|
<script>
|
|
tailwind.config = {
|
|
darkMode: "class",
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
"primary": "#137fec",
|
|
"background-light": "#f6f7f8",
|
|
"background-dark": "#101922",
|
|
},
|
|
fontFamily: {
|
|
"display": ["Inter", "sans-serif"]
|
|
},
|
|
borderRadius: {
|
|
"DEFAULT": "0.25rem",
|
|
"lg": "0.5rem",
|
|
"xl": "0.75rem",
|
|
"full": "9999px"
|
|
},
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
</head>
|
|
|
|
<body class="bg-background-light dark:bg-background-dark font-display text-gray-800 dark:text-gray-200">
|
|
<div class="flex h-screen w-full">
|
|
<aside
|
|
class="flex w-64 flex-col border-r border-gray-200 dark:border-gray-800 bg-white dark:bg-background-dark">
|
|
<div class="flex h-full flex-col justify-between p-4">
|
|
<div class="flex flex-col gap-4">
|
|
<div class="flex items-center gap-3 p-2">
|
|
<div class="bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10"
|
|
data-alt="Admin user avatar"
|
|
style='background-image: url("https://lh3.googleusercontent.com/aida-public/AB6AXuCztlHhjKvu2qkn2Xi2zFHagNsNToKwcTg3vQr0KtTqBCo13dK1yyz9HzB2uLCiciLyDfnrf7pREvdblPqCcUiN0HqlSbkFwY1dpQLMbJ4hmpVgHVWaLaUCMXju06qyGQSdg2ChGVcbTQIrk-RNI2-hDOFnfrI1PD89RNSsByXGRsdkYWSyEYFOFk7bT4l7aIaasB6cdVxDfNwJdvVx15wb7-qOHZHFTPMbrkkzmjGec-f7iVqTi5U1ykNDclBSezBM97TfXajTwRJE");'>
|
|
</div>
|
|
<div class="flex flex-col">
|
|
<h1 class="text-gray-900 dark:text-white text-base font-medium leading-normal">Admin User
|
|
</h1>
|
|
<p class="text-gray-500 dark:text-gray-400 text-sm font-normal leading-normal">Warehouse
|
|
Manager</p>
|
|
</div>
|
|
</div>
|
|
<nav class="flex flex-col gap-2">
|
|
<a class="flex items-center gap-3 px-3 py-2 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
href="#">
|
|
<span class="material-symbols-outlined text-gray-800 dark:text-gray-200">dashboard</span>
|
|
<p class="text-sm font-medium leading-normal">Dashboard</p>
|
|
</a>
|
|
<a class="flex items-center gap-3 px-3 py-2 rounded-lg bg-primary/10 text-primary dark:bg-primary/20"
|
|
href="#">
|
|
<span class="material-symbols-outlined">warehouse</span>
|
|
<p class="text-sm font-medium leading-normal">Inventory</p>
|
|
</a>
|
|
<a class="flex items-center gap-3 px-3 py-2 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
href="#">
|
|
<span class="material-symbols-outlined text-gray-800 dark:text-gray-200">receipt_long</span>
|
|
<p class="text-sm font-medium leading-normal">Orders</p>
|
|
</a>
|
|
<a class="flex items-center gap-3 px-3 py-2 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
href="#">
|
|
<span
|
|
class="material-symbols-outlined text-gray-800 dark:text-gray-200">local_shipping</span>
|
|
<p class="text-sm font-medium leading-normal">Suppliers</p>
|
|
</a>
|
|
<a class="flex items-center gap-3 px-3 py-2 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
href="#">
|
|
<span class="material-symbols-outlined text-gray-800 dark:text-gray-200">pie_chart</span>
|
|
<p class="text-sm font-medium leading-normal">Reports</p>
|
|
</a>
|
|
</nav>
|
|
</div>
|
|
<div class="flex flex-col gap-2">
|
|
<nav class="flex flex-col gap-1">
|
|
<a class="flex items-center gap-3 px-3 py-2 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
href="#">
|
|
<span class="material-symbols-outlined text-gray-800 dark:text-gray-200">settings</span>
|
|
<p class="text-sm font-medium leading-normal">Settings</p>
|
|
</a>
|
|
<a class="flex items-center gap-3 px-3 py-2 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
href="#">
|
|
<span class="material-symbols-outlined text-gray-800 dark:text-gray-200">help</span>
|
|
<p class="text-sm font-medium leading-normal">Help</p>
|
|
</a>
|
|
</nav>
|
|
<button
|
|
class="flex min-w-[84px] cursor-pointer items-center justify-center overflow-hidden rounded-lg h-10 px-4 bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200 text-sm font-bold leading-normal tracking-[0.015em] hover:bg-gray-300 dark:hover:bg-gray-700">
|
|
<span class="truncate">Logout</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
<main class="flex-1 flex flex-col h-screen overflow-y-auto">
|
|
<header
|
|
class="flex sticky top-0 items-center justify-between whitespace-nowrap border-b border-solid border-gray-200 dark:border-gray-800 px-10 py-3 bg-white/80 dark:bg-background-dark/80 backdrop-blur-sm z-10">
|
|
<div class="flex items-center gap-4 text-gray-900 dark:text-white">
|
|
<div class="size-6 text-primary">
|
|
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path
|
|
d="M21.435 7.182a.75.75 0 0 0-.87-.11L12 10.435 3.435 7.072a.75.75 0 0 0-.87.11.75.75 0 0 0-.11.87l2.122 7.878a.75.75 0 0 0 .869.59l6-1.635a.75.75 0 0 0 .108 0l6 1.635a.75.75 0 0 0 .87-.59l2.12-7.878a.75.75 0 0 0-.11-.87zM12 12.18l-5.693-1.55L12 4.288l5.693 6.342L12 12.18z">
|
|
</path>
|
|
</svg>
|
|
</div>
|
|
<h2 class="text-lg font-bold leading-tight tracking-[-0.015em]">WMS Dashboard</h2>
|
|
</div>
|
|
<div class="flex flex-1 justify-end items-center gap-4">
|
|
<label class="relative flex-grow max-w-sm">
|
|
<span
|
|
class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-gray-500">search</span>
|
|
<input
|
|
class="form-input w-full rounded-lg border-none bg-gray-100 dark:bg-gray-800 h-10 pl-10 pr-4 text-sm text-gray-900 dark:text-white placeholder:text-gray-500"
|
|
placeholder="Search items, orders..." value="" />
|
|
</label>
|
|
<div class="flex gap-2">
|
|
<button
|
|
class="flex items-center justify-center rounded-lg h-10 w-10 bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700">
|
|
<span class="material-symbols-outlined text-xl">notifications</span>
|
|
</button>
|
|
<button
|
|
class="flex items-center justify-center rounded-lg h-10 w-10 bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700">
|
|
<span class="material-symbols-outlined text-xl">help_outline</span>
|
|
</button>
|
|
</div>
|
|
<div class="bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10"
|
|
data-alt="Admin user avatar"
|
|
style='background-image: url("https://lh3.googleusercontent.com/aida-public/AB6AXuBNpxncwdjcD3fLZbRbit_NZyuFBZhcpV-Bvdlu6NiZL3kb65hsFRsDkTNHtC0zJxG3HGV1TInl_DCfafj3axNGSwW4-UNj1sZWhiHCYE2aK9hm-FYjrNGiEh0UqKya1EAYMTM5Z4k8qKOWPEPdIaZz9X98tPC5FIn5lbRRusCTuQmgRL-QxK9SdIMA3TflImwA1vyh3zq44j8EkkNTQWf94-e82GDHs5MwHIkK0S-Gg4d950IyRTpoABSa9qXA5yPzoaT9jCGjCodL");'>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<div class="flex-1 p-6 lg:p-10">
|
|
<div class="mx-auto max-w-7xl">
|
|
<div class="flex flex-wrap gap-2 mb-6">
|
|
<a class="text-gray-500 dark:text-gray-400 text-sm font-medium leading-normal"
|
|
href="#">Dashboard</a>
|
|
<span class="text-gray-500 dark:text-gray-400 text-sm font-medium leading-normal">/</span>
|
|
<a class="text-gray-500 dark:text-gray-400 text-sm font-medium leading-normal"
|
|
href="#">Inventory</a>
|
|
<span class="text-gray-500 dark:text-gray-400 text-sm font-medium leading-normal">/</span>
|
|
<span class="text-gray-800 dark:text-gray-200 text-sm font-medium leading-normal">Add New
|
|
Product</span>
|
|
</div>
|
|
<div class="flex flex-wrap justify-between items-center gap-4 mb-8">
|
|
<div class="flex min-w-72 flex-col gap-2">
|
|
<h1 class="text-gray-900 dark:text-white text-3xl font-bold tracking-tight">Add New Product
|
|
</h1>
|
|
<p class="text-gray-500 dark:text-gray-400 text-base font-normal leading-normal">Fill in the
|
|
details below to add a new product to the catalog.</p>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
<div class="lg:col-span-2 flex flex-col gap-8">
|
|
<div
|
|
class="bg-white dark:bg-gray-900/50 p-6 rounded-xl border border-gray-200 dark:border-gray-800">
|
|
<h2 class="text-lg font-bold text-gray-900 dark:text-white mb-6">Product Information
|
|
</h2>
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
|
<div class="sm:col-span-2">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="product-name">Product Name *</label>
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="product-name" placeholder="e.g., Premium Wireless Mouse" type="text" />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="sku">SKU (Stock Keeping Unit) *</label>
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="sku" placeholder="e.g., WRLS-MSE-BLK-01" type="text" />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="supplier-id">Supplier ID</label>
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="supplier-id" placeholder="e.g., SUP-ACME-45" type="text" />
|
|
</div>
|
|
<div class="sm:col-span-2">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="description">Product Description</label>
|
|
<textarea
|
|
class="form-textarea w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="description"
|
|
placeholder="Enter a detailed description of the product..."
|
|
rows="4"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-900/50 p-6 rounded-xl border border-gray-200 dark:border-gray-800">
|
|
<h2 class="text-lg font-bold text-gray-900 dark:text-white mb-6">Product Attributes</h2>
|
|
<div class="space-y-6" id="attributes-container">
|
|
<div class="p-4 border border-gray-200 dark:border-gray-700 rounded-lg">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
for="attribute-name-1">Attribute Name</label>
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span class="material-symbols-outlined text-xl">delete</span>
|
|
</button>
|
|
</div>
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary mb-4"
|
|
id="attribute-name-1" placeholder="e.g., resolucion" type="text"
|
|
value="resolucion" />
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="attribute-values-1">Attribute Values</label>
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="attribute-values-1" placeholder="e.g., 1080" type="text"
|
|
value="1080" />
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span
|
|
class="material-symbols-outlined text-xl">remove_circle_outline</span>
|
|
</button>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
placeholder="e.g., 4K" type="text" value="4K" />
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span
|
|
class="material-symbols-outlined text-xl">remove_circle_outline</span>
|
|
</button>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-4">
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
placeholder="e.g., 2K" type="text" value="2K" />
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span
|
|
class="material-symbols-outlined text-xl">remove_circle_outline</span>
|
|
</button>
|
|
</div>
|
|
<button
|
|
class="flex items-center gap-2 text-sm font-medium text-primary hover:text-primary/90">
|
|
<span class="material-symbols-outlined">add_circle_outline</span>
|
|
<span>Add Value</span>
|
|
</button>
|
|
</div>
|
|
<div class="p-4 border border-gray-200 dark:border-gray-700 rounded-lg">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
for="attribute-name-2">Attribute Name</label>
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span class="material-symbols-outlined text-xl">delete</span>
|
|
</button>
|
|
</div>
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary mb-4"
|
|
id="attribute-name-2" placeholder="e.g., medida" type="text"
|
|
value="medida" />
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="attribute-values-2">Attribute Values</label>
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="attribute-values-2" placeholder="e.g., 24" type="text" value="24" />
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span
|
|
class="material-symbols-outlined text-xl">remove_circle_outline</span>
|
|
</button>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-4">
|
|
<input
|
|
class="form-input w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
placeholder="e.g., 36" type="text" value="36" />
|
|
<button class="text-gray-400 hover:text-red-500 dark:hover:text-red-400">
|
|
<span
|
|
class="material-symbols-outlined text-xl">remove_circle_outline</span>
|
|
</button>
|
|
</div>
|
|
<button
|
|
class="flex items-center gap-2 text-sm font-medium text-primary hover:text-primary/90">
|
|
<span class="material-symbols-outlined">add_circle_outline</span>
|
|
<span>Add Value</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<button
|
|
class="flex min-w-[84px] cursor-pointer items-center justify-center overflow-hidden rounded-lg h-10 px-4 bg-primary/10 dark:bg-primary/20 text-primary text-sm font-bold leading-normal tracking-[0.015em] hover:bg-primary/20 dark:hover:bg-primary/30 w-full mt-4">
|
|
<span class="material-symbols-outlined mr-2">add</span>
|
|
<span class="truncate">Add Another Attribute</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="lg:col-span-1 flex flex-col gap-8">
|
|
<div
|
|
class="bg-white dark:bg-gray-900/50 p-6 rounded-xl border border-gray-200 dark:border-gray-800">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Product Image</h3>
|
|
<div
|
|
class="flex flex-col items-center justify-center p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center cursor-pointer hover:border-primary dark:hover:border-primary transition-colors">
|
|
<div class="mb-2 text-gray-400 dark:text-gray-500">
|
|
<span class="material-symbols-outlined text-5xl">upload_file</span>
|
|
</div>
|
|
<p class="text-sm text-gray-500 dark:text-gray-400"><span
|
|
class="font-semibold text-primary">Click to upload</span> or drag and drop
|
|
</p>
|
|
<p class="text-xs text-gray-400 dark:text-gray-500 mt-1">SVG, PNG, JPG or GIF (max.
|
|
800x400px)</p>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-900/50 p-6 rounded-xl border border-gray-200 dark:border-gray-800">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-6">Organization</h3>
|
|
<div class="space-y-6">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="category">Category</label>
|
|
<select
|
|
class="form-select w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="category">
|
|
<option>Select a category</option>
|
|
<option>Electronics</option>
|
|
<option>Apparel</option>
|
|
<option>Home Goods</option>
|
|
<option>Office Supplies</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
for="subcategory">Subcategory</label>
|
|
<select
|
|
class="form-select w-full rounded-lg border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-primary focus:border-primary"
|
|
id="subcategory">
|
|
<option>Select a subcategory</option>
|
|
<option>Mice & Keyboards</option>
|
|
<option>Monitors</option>
|
|
<option>Cables & Adapters</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-800 flex justify-end items-center gap-4">
|
|
<button
|
|
class="flex min-w-[84px] cursor-pointer items-center justify-center overflow-hidden rounded-lg h-10 px-4 bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200 text-sm font-bold leading-normal hover:bg-gray-300 dark:hover:bg-gray-700">
|
|
<span class="truncate">Cancel</span>
|
|
</button>
|
|
<button
|
|
class="flex min-w-[84px] cursor-pointer items-center justify-center overflow-hidden rounded-lg h-10 px-4 bg-primary text-white text-sm font-bold leading-normal tracking-[0.015em] hover:bg-primary/90">
|
|
<span class="truncate">Save Product</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</body>
|
|
|
|
</html> |