176 lines
5.3 KiB
TypeScript
176 lines
5.3 KiB
TypeScript
import { Button } from '@repo/shadcn/button';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from '@repo/shadcn/components/ui/dialog';
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from '@repo/shadcn/components/ui/table';
|
|
import { Input } from '@repo/shadcn/input';
|
|
import { Label } from '@repo/shadcn/label';
|
|
import { Trash2 } from 'lucide-react';
|
|
import { useState } from 'react';
|
|
import { useFieldArray, useFormContext } from 'react-hook-form';
|
|
import { TrainingSchema } from '../schemas/training';
|
|
|
|
interface EquipmentItem {
|
|
machine: string;
|
|
quantity: string | number;
|
|
}
|
|
|
|
export function EquipmentList() {
|
|
const { control, register } = useFormContext<TrainingSchema>();
|
|
const { fields, append, remove } = useFieldArray({
|
|
control,
|
|
name: 'equipmentList',
|
|
});
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [newItem, setNewItem] = useState<EquipmentItem>({
|
|
machine: '',
|
|
quantity: '',
|
|
});
|
|
|
|
const handleAdd = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
if (newItem.machine.trim()) {
|
|
append({
|
|
machine: newItem.machine,
|
|
quantity: newItem.quantity ? Number(newItem.quantity) : 0,
|
|
});
|
|
setNewItem({ machine: '', quantity: '' });
|
|
setIsOpen(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<div className="flex justify-between items-center">
|
|
<h3 className="text-lg font-medium">Datos del Equipamiento</h3>
|
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
<DialogTrigger asChild>
|
|
<Button variant="outline" type="button">
|
|
Agregar Maquinaria
|
|
</Button>
|
|
</DialogTrigger>
|
|
<DialogContent onPointerDownOutside={(e) => e.preventDefault()}>
|
|
<DialogHeader>
|
|
<DialogTitle>Agregar Maquinaria/Equipo</DialogTitle>
|
|
</DialogHeader>
|
|
<DialogDescription className="sr-only">
|
|
Datos de equipamiento
|
|
</DialogDescription>
|
|
<div className="space-y-4 py-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="modal-machine">Maquinaria</Label>
|
|
<Input
|
|
id="modal-machine"
|
|
value={newItem.machine}
|
|
onChange={(e) =>
|
|
setNewItem({ ...newItem, machine: e.target.value })
|
|
}
|
|
placeholder="Nombre de la maquinaria"
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="modal-quantity">Cantidad</Label>
|
|
<Input
|
|
id="modal-quantity"
|
|
type="number"
|
|
value={newItem.quantity}
|
|
onChange={(e) =>
|
|
setNewItem({ ...newItem, quantity: e.target.value })
|
|
}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div className="flex justify-end gap-4">
|
|
<Button
|
|
variant="outline"
|
|
type="button"
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
setIsOpen(false);
|
|
}}
|
|
>
|
|
Cancelar
|
|
</Button>
|
|
|
|
<Button type="button" onClick={handleAdd}>
|
|
Guardar
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
|
|
<div className="border rounded-md">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Maquinaria</TableHead>
|
|
<TableHead>Cantidad</TableHead>
|
|
<TableHead className="w-[50px]"></TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{fields.map((field, index) => (
|
|
<TableRow key={field.id}>
|
|
<TableCell>
|
|
<input
|
|
type="hidden"
|
|
{...register(`equipmentList.${index}.machine`)}
|
|
defaultValue={field.machine}
|
|
/>
|
|
{field.machine}
|
|
</TableCell>
|
|
<TableCell>
|
|
<input
|
|
type="hidden"
|
|
{...register(`equipmentList.${index}.quantity`)}
|
|
defaultValue={field.quantity}
|
|
/>
|
|
{field.quantity}
|
|
</TableCell>
|
|
<TableCell>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
type="button"
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
remove(index);
|
|
}}
|
|
>
|
|
<Trash2 className="h-4 w-4 text-destructive" />
|
|
</Button>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
{fields.length === 0 && (
|
|
<TableRow>
|
|
<TableCell
|
|
colSpan={3}
|
|
className="text-center text-muted-foreground"
|
|
>
|
|
No hay equipamiento registrado
|
|
</TableCell>
|
|
</TableRow>
|
|
)}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|