'use client' import * as React from 'react' import Link from 'next/link' import { useRouter } from 'next/navigation' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group' import { Separator } from '@/components/ui/separator' import { ArrowLeft, ArrowRight, Save, Send, MapPin, Building2, Briefcase, FileText, DollarSign, CheckCircle2, AlertCircle, } from 'lucide-react' import { cn } from '@/lib/utils' import { countries, cities, departments, positions, currentUser, getCitiesByCountry } from '@/lib/mock-data' import { toast } from 'sonner' type FormStep = 'ubicacion' | 'vacante' | 'justificacion' | 'compensacion' | 'revision' const STEPS: { key: FormStep; label: string; icon: React.ElementType }[] = [ { key: 'ubicacion', label: 'Ubicación', icon: MapPin }, { key: 'vacante', label: 'Vacante', icon: Briefcase }, { key: 'justificacion', label: 'Justificación', icon: FileText }, { key: 'compensacion', label: 'Compensación', icon: DollarSign }, { key: 'revision', label: 'Revisión', icon: CheckCircle2 }, ] interface FormData { countryId: string cityId: string departmentId: string positionId: string quantity: number modalidad: 'presencial' | 'remoto' | 'hibrido' tipoContratacion: 'nuevo' | 'reemplazo' | 'temporal' justification: string urgency: 'normal' | 'alta' | 'critica' salaryPackage: string budget: string currency: string } function StepIndicator({ currentStep }: { currentStep: FormStep }) { const currentIndex = STEPS.findIndex(s => s.key === currentStep) return (
{STEPS.map((step, index) => { const Icon = step.icon const isCompleted = index < currentIndex const isCurrent = step.key === currentStep return (
{isCompleted ? ( ) : ( )}
{index < STEPS.length - 1 && (
)} ) })}
) } export function NewRequisitionPage() { const router = useRouter() const [currentStep, setCurrentStep] = React.useState('ubicacion') const [errors, setErrors] = React.useState>>({}) const [formData, setFormData] = React.useState({ countryId: '', cityId: '', departmentId: '', positionId: '', quantity: 1, modalidad: 'presencial', tipoContratacion: 'nuevo', justification: '', urgency: 'normal', salaryPackage: '', budget: '', currency: 'USD', }) const availableCities = formData.countryId ? getCitiesByCountry(formData.countryId) : [] const updateFormData = (field: keyof FormData, value: string | number) => { setFormData(prev => ({ ...prev, [field]: value })) if (errors[field]) { setErrors(prev => ({ ...prev, [field]: undefined })) } // Reset city when country changes if (field === 'countryId') { setFormData(prev => ({ ...prev, cityId: '' })) } } const validateStep = (step: FormStep): boolean => { const newErrors: Partial> = {} if (step === 'ubicacion') { if (!formData.countryId) newErrors.countryId = 'Selecciona un país' if (!formData.cityId) newErrors.cityId = 'Selecciona una ciudad' if (!formData.departmentId) newErrors.departmentId = 'Selecciona un departamento' } if (step === 'vacante') { if (!formData.positionId) newErrors.positionId = 'Selecciona una posición' if (formData.quantity < 1) newErrors.quantity = 'La cantidad debe ser al menos 1' } if (step === 'justificacion') { if (!formData.justification.trim()) newErrors.justification = 'La justificación es obligatoria' if (formData.justification.length < 20) newErrors.justification = 'Proporciona una justificación más detallada (mín. 20 caracteres)' } setErrors(newErrors) return Object.keys(newErrors).length === 0 } const goToNextStep = () => { if (!validateStep(currentStep)) return const currentIndex = STEPS.findIndex(s => s.key === currentStep) if (currentIndex < STEPS.length - 1) { setCurrentStep(STEPS[currentIndex + 1].key) } } const goToPreviousStep = () => { const currentIndex = STEPS.findIndex(s => s.key === currentStep) if (currentIndex > 0) { setCurrentStep(STEPS[currentIndex - 1].key) } } const handleSaveDraft = () => { toast.success('Borrador guardado', { description: 'La requisición se ha guardado como borrador.', }) } const handleSubmit = () => { toast.success('Requisición enviada', { description: 'La requisición ha sido enviada para aprobación de RR.HH.', }) router.push('/requisiciones') } const selectedCountry = countries.find(c => c.id === formData.countryId) const selectedCity = cities.find(c => c.id === formData.cityId) const selectedDepartment = departments.find(d => d.id === formData.departmentId) const selectedPosition = positions.find(p => p.id === formData.positionId) return (
{/* Header */}

Nueva Requisición

Completa el formulario para solicitar una nueva vacante

{/* Step Indicator */} {/* Form Card */} {/* Step 1: Ubicación */} {currentStep === 'ubicacion' && (

Ubicación

Define el país, ciudad y departamento de la vacante

{errors.countryId && (

{errors.countryId}

)}
{errors.cityId && (

{errors.cityId}

)}
{errors.departmentId && (

{errors.departmentId}

)}
{/* Requester Info */}

Solicitante

{currentUser.name}

{currentUser.email}

)} {/* Step 2: Vacante */} {currentStep === 'vacante' && (

Información de la Vacante

Define la posición, cantidad y tipo de contratación

{errors.positionId && (

{errors.positionId}

)}
updateFormData('quantity', parseInt(e.target.value) || 1)} className={cn(errors.quantity && 'border-destructive')} /> {errors.quantity && (

{errors.quantity}

)}
updateFormData('modalidad', v)} className="flex gap-4" >
updateFormData('tipoContratacion', v)} className="flex gap-4" >
)} {/* Step 3: Justificación */} {currentStep === 'justificacion' && (

Justificación

Explica el motivo de la requisición y su nivel de urgencia