From 2686b695068416b463b8d066195152231e7e5314 Mon Sep 17 00:00:00 2001 From: Tiago Yamamoto Date: Sun, 22 Feb 2026 12:32:55 -0600 Subject: [PATCH] feat(jobs/new): add user account registration and fix companyId in job payload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add password + confirm-password fields to billing step (Step 3) so the recruiter creates their account credentials during the job posting flow - Validate password length (≥8) and confirmation match before proceeding - Extract company `id` from POST /auth/register/company response and send it as `companyId` in the job creation payload (was missing — caused 400) - Pass `contact` (full name) to company registration endpoint - Remove hardcoded "Temp@123456" password; use the user-provided one - Remove hardcoded "+55" phone prefix; send raw digits with "+" prefix - Add translations (pt-BR, en, es) for password fields and error messages Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/app/jobs/new/page.tsx | 71 ++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/jobs/new/page.tsx b/frontend/src/app/jobs/new/page.tsx index 5c5435e..f80d83c 100644 --- a/frontend/src/app/jobs/new/page.tsx +++ b/frontend/src/app/jobs/new/page.tsx @@ -179,6 +179,12 @@ const contentByLocale = { phonePlaceholder: "(00) 0000-0000", mobile: "Celular", mobilePlaceholder: "(00) 00000-0000", + accountTitle: "Dados de acesso à conta", + accountHint: "Você usará este e-mail e senha para acessar o painel da empresa.", + password: "Senha *", + passwordPlaceholder: "Mínimo 8 caracteres", + confirmPassword: "Confirmar senha *", + confirmPasswordPlaceholder: "Repita a senha", termsAccept: "Li e aceito as", termsLink: "Condições Legais", termsAnd: "e a", @@ -218,6 +224,8 @@ const contentByLocale = { paymentRequired: "Selecione um método de pagamento.", registerError: "Erro ao registrar empresa", unexpectedError: "Erro inesperado ao publicar vaga", + passwordRequired: "Informe uma senha com ao menos 8 caracteres.", + passwordMismatch: "As senhas não coincidem.", }, success: "Vaga cadastrada com sucesso!", }, @@ -335,6 +343,12 @@ const contentByLocale = { phonePlaceholder: "(00) 0000-0000", mobile: "Mobile", mobilePlaceholder: "(00) 00000-0000", + accountTitle: "Account access details", + accountHint: "You will use this email and password to access the company dashboard.", + password: "Password *", + passwordPlaceholder: "Minimum 8 characters", + confirmPassword: "Confirm password *", + confirmPasswordPlaceholder: "Repeat password", termsAccept: "I have read and accept the", termsLink: "Legal Terms", termsAnd: "and the", @@ -374,6 +388,8 @@ const contentByLocale = { paymentRequired: "Please select a payment method.", registerError: "Error registering company", unexpectedError: "Unexpected error publishing job", + passwordRequired: "Please enter a password with at least 8 characters.", + passwordMismatch: "Passwords do not match.", }, success: "Job posted successfully!", }, @@ -491,6 +507,12 @@ const contentByLocale = { phonePlaceholder: "(00) 0000-0000", mobile: "Celular", mobilePlaceholder: "(00) 00000-0000", + accountTitle: "Datos de acceso a la cuenta", + accountHint: "Usará este correo y contraseña para acceder al panel de la empresa.", + password: "Contraseña *", + passwordPlaceholder: "Mínimo 8 caracteres", + confirmPassword: "Confirmar contraseña *", + confirmPasswordPlaceholder: "Repita la contraseña", termsAccept: "He leído y acepto las", termsLink: "Condiciones Legales", termsAnd: "y la", @@ -530,6 +552,8 @@ const contentByLocale = { paymentRequired: "Seleccione un método de pago.", registerError: "Error al registrar empresa", unexpectedError: "Error inesperado al publicar vacante", + passwordRequired: "Ingrese una contraseña con al menos 8 caracteres.", + passwordMismatch: "Las contraseñas no coinciden.", }, success: "¡Vacante publicada con éxito!", }, @@ -593,6 +617,8 @@ export default function PostJobPage() { contactEmail: "", contactPhone: "", contactMobile: "", + password: "", + confirmPassword: "", acceptTerms: false, acceptMarketing: false, }); @@ -655,6 +681,14 @@ export default function PostJobPage() { toast.error(c.errors.billingEmailInvalid); return false; } + if (!billing.password || billing.password.length < 8) { + toast.error(c.errors.passwordRequired); + return false; + } + if (billing.password !== billing.confirmPassword) { + toast.error(c.errors.passwordMismatch); + return false; + } if (!billing.acceptTerms) { toast.error(c.errors.termsRequired); return false; @@ -688,8 +722,8 @@ export default function PostJobPage() { setLoading(true); try { const apiBase = process.env.NEXT_PUBLIC_API_URL || ""; - const password = "Temp@123456"; const billingPhone = cleanDigits(billing.contactMobile || billing.contactPhone || job.applicationPhone); + const contactFullName = [billing.contactName, billing.contactLastName].filter(Boolean).join(" "); const registerRes = await fetch(`${apiBase}/api/v1/auth/register/company`, { method: "POST", @@ -697,9 +731,10 @@ export default function PostJobPage() { body: JSON.stringify({ companyName: company.name, email: billing.contactEmail, + contact: contactFullName || null, document: cleanDigits(company.document) || null, - password, - phone: billingPhone ? `+55${billingPhone}` : null, + password: billing.password, + phone: billingPhone ? `+${billingPhone}` : null, website: company.website || null, employeeCount: company.employeeCount || null, foundedYear: company.foundedYear ? Number(company.foundedYear) : null, @@ -712,7 +747,7 @@ export default function PostJobPage() { throw new Error(err.message || c.errors.registerError); } - const { token } = await registerRes.json(); + const { id: companyId, token } = await registerRes.json(); const salaryMin = job.salaryMode === "fixed" ? Number(job.salaryFixed || 0) : Number(job.salaryMin || 0); const salaryMax = job.salaryMode === "fixed" ? Number(job.salaryFixed || 0) : Number(job.salaryMax || 0); @@ -724,6 +759,7 @@ export default function PostJobPage() { Authorization: `Bearer ${token}`, }, body: JSON.stringify({ + companyId, title: job.title, description: job.description, location: `${job.location}, ${job.country}`, @@ -1227,6 +1263,33 @@ export default function PostJobPage() { +
+
+

{c.billing.accountTitle}

+

{c.billing.accountHint}

+
+
+
+ + setBilling({ ...billing, password: e.target.value })} + /> +
+
+ + setBilling({ ...billing, confirmPassword: e.target.value })} + /> +
+
+
+