Refactor commerce module
This commit is contained in:
170
src/pages/dashboard/commerce/Inventory.tsx
Normal file
170
src/pages/dashboard/commerce/Inventory.tsx
Normal file
@@ -0,0 +1,170 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Package, Plus, Edit, Trash2, AlertTriangle } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
|
||||
const Inventory = () => {
|
||||
const [inventory, setInventory] = useState<any[]>([]);
|
||||
const { toast } = useToast();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
category: '',
|
||||
quantity: 0,
|
||||
unit: 'kg',
|
||||
minStock: 0,
|
||||
supplier: ''
|
||||
});
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
toast({ title: 'Éxito', description: 'Producto agregado al inventario' });
|
||||
setFormData({
|
||||
name: '',
|
||||
category: '',
|
||||
quantity: 0,
|
||||
unit: 'kg',
|
||||
minStock: 0,
|
||||
supplier: ''
|
||||
});
|
||||
} catch (error: any) {
|
||||
toast({ title: 'Error', description: error?.message || 'No se pudo agregar el producto', variant: 'destructive' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<Package className="w-8 h-8 text-orange-600" />
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900">Gestión de Inventario</h1>
|
||||
<p className="text-gray-600">Controla el stock de productos</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end mb-4">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Nuevo Producto
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Agregar Producto</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid gap-4">
|
||||
<div>
|
||||
<Label>Nombre del Producto</Label>
|
||||
<Input
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
placeholder="Ej: Tomates"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Categoría</Label>
|
||||
<Input
|
||||
value={formData.category}
|
||||
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
|
||||
placeholder="Ej: Vegetales"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label>Cantidad</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={formData.quantity}
|
||||
onChange={(e) => setFormData({ ...formData, quantity: parseFloat(e.target.value) })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Unidad</Label>
|
||||
<Input
|
||||
value={formData.unit}
|
||||
onChange={(e) => setFormData({ ...formData, unit: e.target.value })}
|
||||
placeholder="kg, lb, unidades"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Stock Mínimo</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={formData.minStock}
|
||||
onChange={(e) => setFormData({ ...formData, minStock: parseFloat(e.target.value) })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Proveedor</Label>
|
||||
<Input
|
||||
value={formData.supplier}
|
||||
onChange={(e) => setFormData({ ...formData, supplier: e.target.value })}
|
||||
placeholder="Nombre del proveedor"
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={handleSubmit}>Agregar Producto</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{inventory.length === 0 ? (
|
||||
<div className="col-span-full text-center py-12 text-muted-foreground">
|
||||
No hay productos en el inventario. Agrega el primer producto.
|
||||
</div>
|
||||
) : (
|
||||
inventory.map((item) => (
|
||||
<Card key={item.id}>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<div>
|
||||
<CardTitle className="text-base">{item.name}</CardTitle>
|
||||
<p className="text-sm text-muted-foreground">{item.category}</p>
|
||||
</div>
|
||||
<div className="flex gap-1">
|
||||
<Button variant="outline" size="sm">
|
||||
<Edit className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button variant="outline" size="sm">
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-muted-foreground">Stock actual:</span>
|
||||
<span className="font-bold">{item.quantity} {item.unit}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-muted-foreground">Stock mínimo:</span>
|
||||
<span>{item.minStock} {item.unit}</span>
|
||||
</div>
|
||||
{item.quantity <= item.minStock && (
|
||||
<Badge variant="destructive" className="w-full justify-center">
|
||||
<AlertTriangle className="w-3 h-3 mr-1" />
|
||||
Stock Bajo
|
||||
</Badge>
|
||||
)}
|
||||
<p className="text-xs text-muted-foreground">Proveedor: {item.supplier}</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Inventory;
|
||||
Reference in New Issue
Block a user