"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 { categoriaManoObraSchema, calcularFSR, type CategoriaManoObraInput, } from "@/lib/validations/apu"; import { toast } from "@/hooks/use-toast"; import { Loader2 } from "lucide-react"; import { CATEGORIA_MANO_OBRA_LABELS } from "@/types"; import { CategoriaManoObra } from "@prisma/client"; interface ManoObraFormProps { categoria?: { id: string; codigo: string; nombre: string; categoria: CategoriaManoObra; salarioDiario: number; factorIMSS: number; factorINFONAVIT: number; factorRetiro: number; factorVacaciones: number; factorPrimaVac: number; factorAguinaldo: number; factorSalarioReal: number; salarioReal: number; }; } export function ManoObraForm({ categoria }: ManoObraFormProps) { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const isEditing = !!categoria; const { register, handleSubmit, formState: { errors }, setValue, watch, } = useForm({ resolver: zodResolver(categoriaManoObraSchema), defaultValues: { codigo: categoria?.codigo || "", nombre: categoria?.nombre || "", categoria: categoria?.categoria || "PEON", salarioDiario: categoria?.salarioDiario || 0, factorIMSS: categoria?.factorIMSS || 0.2675, factorINFONAVIT: categoria?.factorINFONAVIT || 0.05, factorRetiro: categoria?.factorRetiro || 0.02, factorVacaciones: categoria?.factorVacaciones || 0.0411, factorPrimaVac: categoria?.factorPrimaVac || 0.0103, factorAguinaldo: categoria?.factorAguinaldo || 0.0411, }, }); const watchedValues = watch(); // Calculate FSR and salario real in real-time const calculatedValues = useMemo(() => { const fsr = calcularFSR({ factorIMSS: watchedValues.factorIMSS || 0, factorINFONAVIT: watchedValues.factorINFONAVIT || 0, factorRetiro: watchedValues.factorRetiro || 0, factorVacaciones: watchedValues.factorVacaciones || 0, factorPrimaVac: watchedValues.factorPrimaVac || 0, factorAguinaldo: watchedValues.factorAguinaldo || 0, }); const salarioReal = (watchedValues.salarioDiario || 0) * fsr; return { fsr, salarioReal }; }, [watchedValues]); const onSubmit = async (data: CategoriaManoObraInput) => { setIsLoading(true); try { const url = isEditing ? `/api/apu/mano-obra/${categoria.id}` : "/api/apu/mano-obra"; 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 ? "Categoria actualizada" : "Categoria creada", description: isEditing ? "Los cambios han sido guardados" : "La categoria de mano de obra ha sido creada exitosamente", }); router.push("/apu/mano-obra"); router.refresh(); } catch (error) { toast({ title: "Error", description: error instanceof Error ? error.message : "No se pudo guardar la categoria", variant: "destructive", }); } finally { setIsLoading(false); } }; return (
Informacion General Datos basicos de la categoria de mano de obra
{errors.codigo && (

{errors.codigo.message}

)}
{errors.nombre && (

{errors.nombre.message}

)}
{errors.salarioDiario && (

{errors.salarioDiario.message}

)}
Factor de Salario Real (FSR) Factores para calcular el salario real incluyendo prestaciones

Resumen de Calculo

Factor de Salario Real: {calculatedValues.fsr.toFixed(4)}
Salario Real Diario: ${calculatedValues.salarioReal.toFixed(2)}
); }