diff --git a/frontend/src/app/register/job/page.tsx b/frontend/src/app/register/job/page.tsx new file mode 100644 index 0000000..3126473 --- /dev/null +++ b/frontend/src/app/register/job/page.tsx @@ -0,0 +1,472 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { useRouter } from "next/navigation"; +import Link from "next/link"; +import Image from "next/image"; +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 { + Briefcase, + Building2, + ArrowLeft, + MapPin, + DollarSign, + Clock, + Loader2, +} from "lucide-react"; +import { motion } from "framer-motion"; +import { useTranslation } from "@/lib/i18n"; +import { LanguageSwitcher } from "@/components/language-switcher"; +import { jobsApi, adminCompaniesApi, type CreateJobPayload, type AdminCompany } from "@/lib/api"; +import { toast } from "sonner"; + +export default function PublicPostJobPage() { + const router = useRouter(); + const { t } = useTranslation(); + const [loading, setLoading] = useState(false); + const [companies, setCompanies] = useState([]); + const [loadingCompanies, setLoadingCompanies] = useState(true); + const [currentStep, setCurrentStep] = useState(1); + + const [formData, setFormData] = useState({ + title: "", + description: "", + location: "", + salaryMin: "", + salaryMax: "", + salaryType: "monthly", + currency: "BRL", + employmentType: "", + workingHours: "", + companyId: "", + }); + + useEffect(() => { + const loadCompanies = async () => { + try { + setLoadingCompanies(true); + const data = await adminCompaniesApi.list(undefined, 1, 100); + setCompanies(data.data ?? []); + } catch (error) { + console.error("Failed to load companies:", error); + } finally { + setLoadingCompanies(false); + } + }; + loadCompanies(); + }, []); + + const updateField = (field: string, value: string) => { + setFormData((prev) => ({ ...prev, [field]: value })); + }; + + const canSubmit = () => { + return ( + formData.title.length >= 5 && + formData.description.length >= 20 && + formData.companyId !== "" + ); + }; + + const onSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!canSubmit()) { + toast.error("Please fill in all required fields"); + return; + } + + setLoading(true); + try { + const payload: CreateJobPayload = { + companyId: formData.companyId, + title: formData.title, + description: formData.description, + location: formData.location || undefined, + employmentType: formData.employmentType as CreateJobPayload["employmentType"] || undefined, + salaryMin: formData.salaryMin ? parseFloat(formData.salaryMin) : undefined, + salaryMax: formData.salaryMax ? parseFloat(formData.salaryMax) : undefined, + salaryType: formData.salaryType as CreateJobPayload["salaryType"] || undefined, + currency: formData.currency as CreateJobPayload["currency"] || undefined, + workingHours: formData.workingHours || undefined, + status: "draft", + }; + + await jobsApi.create(payload); + toast.success("Job posted successfully! It will be reviewed soon."); + router.push("/jobs"); + } catch (error: any) { + console.error("Failed to post job:", error); + toast.error(error.message || "Failed to post job. Please try again."); + } finally { + setLoading(false); + } + }; + + const nextStep = () => { + if (currentStep < 2) setCurrentStep(currentStep + 1); + }; + + const prevStep = () => { + if (currentStep > 1) setCurrentStep(currentStep - 1); + }; + + const stepVariants = { + hidden: { opacity: 0, x: 20 }, + visible: { opacity: 1, x: 0 }, + exit: { opacity: 0, x: -20 }, + }; + + return ( +
+ {/* Left Panel - Information */} +
+ +
+ GoHorse Jobs +
+ +

Post a Job

+ +

+ Reach thousands of qualified candidates looking for their next opportunity. +

+ +
+
+
+ Free job posting +
+
+
+ Access to verified candidates +
+
+
+ Easy application management +
+
+
+ Professional dashboard +
+
+
+
+ + {/* Right Panel - Form */} +
+
+ +
+ +
+ {/* Header */} +
+ + + Back to jobs + + +

+ Post a new job +

+

+ Fill in the details below to create your job listing +

+
+ + {/* Progress Indicator */} +
+
+ + Step {currentStep} of 2 + + + {currentStep === 1 && "Job Details"} + {currentStep === 2 && "Salary & Company"} + +
+
+
+
+
+ +
+ {/* Step 1: Job Details */} + {currentStep === 1 && ( + +
+ + updateField("title", e.target.value)} + /> + {formData.title.length > 0 && formData.title.length < 5 && ( + + Title must be at least 5 characters + + )} +
+ +
+ +