"use client"; import { useState, useMemo } from "react"; import { useRouter } from "next/navigation"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { equipoMaquinariaSchema, calcularCostoHorario, type EquipoMaquinariaInput, } from "@/lib/validations/apu"; import { toast } from "@/hooks/use-toast"; import { Loader2 } from "lucide-react"; import { TIPO_EQUIPO_LABELS } from "@/types"; import { TipoEquipo } from "@prisma/client"; interface EquipoFormProps { equipo?: { id: string; codigo: string; nombre: string; tipo: TipoEquipo; valorAdquisicion: number; vidaUtilHoras: number; valorRescate: number; consumoCombustible: number | null; precioCombustible: number | null; factorMantenimiento: number; costoOperador: number | null; costoHorario: number; }; } export function EquipoForm({ equipo }: EquipoFormProps) { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const isEditing = !!equipo; const { register, handleSubmit, formState: { errors }, setValue, watch, } = useForm({ resolver: zodResolver(equipoMaquinariaSchema), defaultValues: { codigo: equipo?.codigo || "", nombre: equipo?.nombre || "", tipo: equipo?.tipo || "MAQUINARIA_LIGERA", valorAdquisicion: equipo?.valorAdquisicion || 0, vidaUtilHoras: equipo?.vidaUtilHoras || 0, valorRescate: equipo?.valorRescate || 0, consumoCombustible: equipo?.consumoCombustible || undefined, precioCombustible: equipo?.precioCombustible || undefined, factorMantenimiento: equipo?.factorMantenimiento || 0.6, costoOperador: equipo?.costoOperador || undefined, }, }); const watchedValues = watch(); // Calculate costo horario in real-time const calculatedCostoHorario = useMemo(() => { if (!watchedValues.valorAdquisicion || !watchedValues.vidaUtilHoras) { return 0; } return calcularCostoHorario({ valorAdquisicion: watchedValues.valorAdquisicion || 0, vidaUtilHoras: watchedValues.vidaUtilHoras || 1, valorRescate: watchedValues.valorRescate || 0, consumoCombustible: watchedValues.consumoCombustible, precioCombustible: watchedValues.precioCombustible, factorMantenimiento: watchedValues.factorMantenimiento || 0.6, costoOperador: watchedValues.costoOperador, }); }, [watchedValues]); // Calculate breakdown const costoBreakdown = useMemo(() => { const va = watchedValues.valorAdquisicion || 0; const vh = watchedValues.vidaUtilHoras || 1; const vr = watchedValues.valorRescate || 0; const fm = watchedValues.factorMantenimiento || 0.6; const cc = watchedValues.consumoCombustible || 0; const pc = watchedValues.precioCombustible || 0; const co = watchedValues.costoOperador || 0; const depreciacion = (va - vr) / vh; const mantenimiento = depreciacion * fm; const combustible = cc * pc; return { depreciacion, mantenimiento, combustible, operador: co, }; }, [watchedValues]); const onSubmit = async (data: EquipoMaquinariaInput) => { setIsLoading(true); try { const url = isEditing ? `/api/apu/equipos/${equipo.id}` : "/api/apu/equipos"; const method = isEditing ? "PUT" : "POST"; const response = await fetch(url, { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || "Error al guardar"); } toast({ title: isEditing ? "Equipo actualizado" : "Equipo creado", description: isEditing ? "Los cambios han sido guardados" : "El equipo ha sido creado exitosamente", }); router.push("/apu/equipos"); router.refresh(); } catch (error) { toast({ title: "Error", description: error instanceof Error ? error.message : "No se pudo guardar el equipo", variant: "destructive", }); } finally { setIsLoading(false); } }; return (
Informacion General Datos basicos del equipo o maquinaria
{errors.codigo && (

{errors.codigo.message}

)}
{errors.nombre && (

{errors.nombre.message}

)}
Datos Economicos Valores para calcular el costo horario del equipo
{errors.valorAdquisicion && (

{errors.valorAdquisicion.message}

)}
{errors.vidaUtilHoras && (

{errors.vidaUtilHoras.message}

)}

Tipicamente entre 0.40 y 0.80 (60% por defecto)

Resumen de Costo Horario
Depreciacion: ${costoBreakdown.depreciacion.toFixed(2)}/hr
Mantenimiento: ${costoBreakdown.mantenimiento.toFixed(2)}/hr
Combustible: ${costoBreakdown.combustible.toFixed(2)}/hr
Operador: ${costoBreakdown.operador.toFixed(2)}/hr
Costo Horario Total: ${calculatedCostoHorario.toFixed(2)}/hr
); }