Merge pull request #13 from rede5/codex/adicionar-ingles-ao-idioma-padrao
Localize candidate registration flow
This commit is contained in:
commit
493ef81b24
4 changed files with 416 additions and 91 deletions
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
|
|
@ -41,37 +41,43 @@ import { motion } from "framer-motion";
|
|||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
import { useTranslation } from "@/lib/i18n";
|
||||
|
||||
const candidateSchema = z.object({
|
||||
fullName: z.string().min(2, "Nome deve ter pelo menos 2 caracteres"),
|
||||
email: z.string().email("Email inválido"),
|
||||
password: z.string().min(6, "Senha deve ter pelo menos 6 caracteres"),
|
||||
confirmPassword: z.string(),
|
||||
phone: z.string().min(10, "Telefone deve ter pelo menos 10 dígitos"),
|
||||
birthDate: z.string().min(1, "Data de nascimento é obrigatória"),
|
||||
address: z.string().min(5, "Endereço deve ter pelo menos 5 caracteres"),
|
||||
city: z.string().min(2, "Cidade é obrigatória"),
|
||||
state: z.string().min(2, "Estado é obrigatório"),
|
||||
zipCode: z.string().min(8, "CEP deve ter 8 dígitos"),
|
||||
education: z.string().min(1, "Nível de escolaridade é obrigatório"),
|
||||
experience: z.string().min(1, "Experiência profissional é obrigatória"),
|
||||
skills: z.string().optional(),
|
||||
objective: z.string().optional(),
|
||||
acceptTerms: z.boolean().refine(val => val === true, "Você deve aceitar os termos"),
|
||||
acceptNewsletter: z.boolean().optional(),
|
||||
}).refine(data => data.password === data.confirmPassword, {
|
||||
message: "Senhas não coincidem",
|
||||
path: ["confirmPassword"],
|
||||
});
|
||||
const createCandidateSchema = (t: (key: string, params?: Record<string, string | number>) => string) =>
|
||||
z.object({
|
||||
fullName: z.string().min(2, t("register.candidate.validation.fullName")),
|
||||
email: z.string().email(t("register.candidate.validation.email")),
|
||||
password: z.string().min(6, t("register.candidate.validation.password")),
|
||||
confirmPassword: z.string(),
|
||||
phone: z.string().min(10, t("register.candidate.validation.phone")),
|
||||
birthDate: z.string().min(1, t("register.candidate.validation.birthDate")),
|
||||
address: z.string().min(5, t("register.candidate.validation.address")),
|
||||
city: z.string().min(2, t("register.candidate.validation.city")),
|
||||
state: z.string().min(2, t("register.candidate.validation.state")),
|
||||
zipCode: z.string().min(8, t("register.candidate.validation.zipCode")),
|
||||
education: z.string().min(1, t("register.candidate.validation.education")),
|
||||
experience: z.string().min(1, t("register.candidate.validation.experience")),
|
||||
skills: z.string().optional(),
|
||||
objective: z.string().optional(),
|
||||
acceptTerms: z
|
||||
.boolean()
|
||||
.refine(val => val === true, t("register.candidate.validation.acceptTerms")),
|
||||
acceptNewsletter: z.boolean().optional(),
|
||||
}).refine(data => data.password === data.confirmPassword, {
|
||||
message: t("register.candidate.validation.passwordMismatch"),
|
||||
path: ["confirmPassword"],
|
||||
});
|
||||
|
||||
type CandidateFormData = z.infer<typeof candidateSchema>;
|
||||
type CandidateFormData = z.infer<ReturnType<typeof createCandidateSchema>>;
|
||||
|
||||
export default function CandidateRegisterPage() {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||
const [currentStep, setCurrentStep] = useState(1);
|
||||
const candidateSchema = useMemo(() => createCandidateSchema(t), [t]);
|
||||
|
||||
const {
|
||||
register,
|
||||
|
|
@ -94,7 +100,7 @@ export default function CandidateRegisterPage() {
|
|||
console.log("Dados do candidato:", data);
|
||||
|
||||
// Redirecionar para login após cadastro
|
||||
router.push("/login?message=Cadastro realizado com sucesso! Faça login para continuar.");
|
||||
router.push(`/login?message=${encodeURIComponent(t("register.candidate.success"))}`);
|
||||
} catch (error) {
|
||||
console.error("Erro no cadastro:", error);
|
||||
} finally {
|
||||
|
|
@ -130,30 +136,29 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<h1 className="text-4xl font-bold mb-4">
|
||||
Cadastre-se como Candidato
|
||||
{t("register.candidate.hero.title")}
|
||||
</h1>
|
||||
|
||||
<p className="text-lg opacity-90 leading-relaxed mb-6">
|
||||
Crie sua conta e tenha acesso às melhores oportunidades de emprego.
|
||||
Encontre a vaga dos seus sonhos hoje mesmo!
|
||||
{t("register.candidate.hero.subtitle")}
|
||||
</p>
|
||||
|
||||
<div className="space-y-4 text-left">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-2 h-2 bg-white rounded-full"></div>
|
||||
<span>Acesso a milhares de vagas</span>
|
||||
<span>{t("register.candidate.hero.bullets.jobs")}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-2 h-2 bg-white rounded-full"></div>
|
||||
<span>Candidaturas rápidas e fáceis</span>
|
||||
<span>{t("register.candidate.hero.bullets.fastApplications")}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-2 h-2 bg-white rounded-full"></div>
|
||||
<span>Perfil profissional completo</span>
|
||||
<span>{t("register.candidate.hero.bullets.profile")}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-2 h-2 bg-white rounded-full"></div>
|
||||
<span>Notificações de novas oportunidades</span>
|
||||
<span>{t("register.candidate.hero.bullets.notifications")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
|
@ -169,25 +174,27 @@ export default function CandidateRegisterPage() {
|
|||
className="inline-flex items-center gap-2 text-muted-foreground hover:text-foreground mb-4 transition-colors"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
Voltar ao Login
|
||||
{t("register.candidate.actions.backToLogin")}
|
||||
</Link>
|
||||
|
||||
<h2 className="text-2xl font-bold text-foreground mb-2">
|
||||
Criar Conta - Candidato
|
||||
{t("register.candidate.title")}
|
||||
</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Preencha seus dados para criar sua conta
|
||||
{t("register.candidate.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Progress Indicator */}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-sm font-medium">Etapa {currentStep} de 3</span>
|
||||
<span className="text-sm font-medium">
|
||||
{t("register.candidate.progress.step", { current: currentStep, total: 3 })}
|
||||
</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{currentStep === 1 && "Dados Pessoais"}
|
||||
{currentStep === 2 && "Endereço e Contato"}
|
||||
{currentStep === 3 && "Perfil Profissional"}
|
||||
{currentStep === 1 && t("register.candidate.steps.personal")}
|
||||
{currentStep === 2 && t("register.candidate.steps.address")}
|
||||
{currentStep === 3 && t("register.candidate.steps.professional")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="w-full bg-muted rounded-full h-2">
|
||||
|
|
@ -210,13 +217,13 @@ export default function CandidateRegisterPage() {
|
|||
className="space-y-4"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="fullName">Nome Completo</Label>
|
||||
<Label htmlFor="fullName">{t("register.candidate.fields.fullName")}</Label>
|
||||
<div className="relative">
|
||||
<User className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="fullName"
|
||||
type="text"
|
||||
placeholder="Seu nome completo"
|
||||
placeholder={t("register.candidate.placeholders.fullName")}
|
||||
className="pl-10"
|
||||
{...register("fullName")}
|
||||
/>
|
||||
|
|
@ -227,13 +234,13 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Label htmlFor="email">{t("register.candidate.fields.email")}</Label>
|
||||
<div className="relative">
|
||||
<Mail className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="seu@email.com"
|
||||
placeholder={t("register.candidate.placeholders.email")}
|
||||
className="pl-10"
|
||||
{...register("email")}
|
||||
/>
|
||||
|
|
@ -244,13 +251,13 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="password">Senha</Label>
|
||||
<Label htmlFor="password">{t("register.candidate.fields.password")}</Label>
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
placeholder="Sua senha"
|
||||
placeholder={t("register.candidate.placeholders.password")}
|
||||
className="pl-10 pr-10"
|
||||
{...register("password")}
|
||||
/>
|
||||
|
|
@ -274,13 +281,13 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="confirmPassword">Confirmar Senha</Label>
|
||||
<Label htmlFor="confirmPassword">{t("register.candidate.fields.confirmPassword")}</Label>
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="confirmPassword"
|
||||
type={showConfirmPassword ? "text" : "password"}
|
||||
placeholder="Confirme sua senha"
|
||||
placeholder={t("register.candidate.placeholders.confirmPassword")}
|
||||
className="pl-10 pr-10"
|
||||
{...register("confirmPassword")}
|
||||
/>
|
||||
|
|
@ -304,7 +311,7 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="birthDate">Data de Nascimento</Label>
|
||||
<Label htmlFor="birthDate">{t("register.candidate.fields.birthDate")}</Label>
|
||||
<div className="relative">
|
||||
<Calendar className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
|
|
@ -320,7 +327,7 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<Button type="button" onClick={nextStep} className="w-full">
|
||||
Próxima Etapa
|
||||
{t("register.candidate.actions.next")}
|
||||
</Button>
|
||||
</motion.div>
|
||||
)}
|
||||
|
|
@ -336,13 +343,13 @@ export default function CandidateRegisterPage() {
|
|||
className="space-y-4"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="phone">Telefone</Label>
|
||||
<Label htmlFor="phone">{t("register.candidate.fields.phone")}</Label>
|
||||
<div className="relative">
|
||||
<Phone className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="phone"
|
||||
type="tel"
|
||||
placeholder="(11) 99999-9999"
|
||||
placeholder={t("register.candidate.placeholders.phone")}
|
||||
className="pl-10"
|
||||
{...register("phone")}
|
||||
/>
|
||||
|
|
@ -353,13 +360,13 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="address">Endereço</Label>
|
||||
<Label htmlFor="address">{t("register.candidate.fields.address")}</Label>
|
||||
<div className="relative">
|
||||
<MapPin className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="address"
|
||||
type="text"
|
||||
placeholder="Rua, número, complemento"
|
||||
placeholder={t("register.candidate.placeholders.address")}
|
||||
className="pl-10"
|
||||
{...register("address")}
|
||||
/>
|
||||
|
|
@ -371,11 +378,11 @@ export default function CandidateRegisterPage() {
|
|||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="city">Cidade</Label>
|
||||
<Label htmlFor="city">{t("register.candidate.fields.city")}</Label>
|
||||
<Input
|
||||
id="city"
|
||||
type="text"
|
||||
placeholder="Sua cidade"
|
||||
placeholder={t("register.candidate.placeholders.city")}
|
||||
{...register("city")}
|
||||
/>
|
||||
{errors.city && (
|
||||
|
|
@ -384,10 +391,10 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="state">Estado</Label>
|
||||
<Label htmlFor="state">{t("register.candidate.fields.state")}</Label>
|
||||
<Select onValueChange={(value) => setValue("state", value)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Estado" />
|
||||
<SelectValue placeholder={t("register.candidate.placeholders.state")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="AC">Acre</SelectItem>
|
||||
|
|
@ -426,11 +433,11 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="zipCode">CEP</Label>
|
||||
<Label htmlFor="zipCode">{t("register.candidate.fields.zipCode")}</Label>
|
||||
<Input
|
||||
id="zipCode"
|
||||
type="text"
|
||||
placeholder="00000-000"
|
||||
placeholder={t("register.candidate.placeholders.zipCode")}
|
||||
{...register("zipCode")}
|
||||
/>
|
||||
{errors.zipCode && (
|
||||
|
|
@ -440,10 +447,10 @@ export default function CandidateRegisterPage() {
|
|||
|
||||
<div className="flex gap-4">
|
||||
<Button type="button" variant="outline" onClick={prevStep} className="flex-1">
|
||||
Voltar
|
||||
{t("register.candidate.actions.back")}
|
||||
</Button>
|
||||
<Button type="button" onClick={nextStep} className="flex-1">
|
||||
Próxima Etapa
|
||||
{t("register.candidate.actions.next")}
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
|
@ -460,19 +467,19 @@ export default function CandidateRegisterPage() {
|
|||
className="space-y-4"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="education">Nível de Escolaridade</Label>
|
||||
<Label htmlFor="education">{t("register.candidate.fields.education")}</Label>
|
||||
<Select onValueChange={(value) => setValue("education", value)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Selecione sua escolaridade" />
|
||||
<SelectValue placeholder={t("register.candidate.placeholders.education")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="fundamental">Ensino Fundamental</SelectItem>
|
||||
<SelectItem value="medio">Ensino Médio</SelectItem>
|
||||
<SelectItem value="tecnico">Técnico</SelectItem>
|
||||
<SelectItem value="superior">Ensino Superior</SelectItem>
|
||||
<SelectItem value="pos">Pós-graduação</SelectItem>
|
||||
<SelectItem value="mestrado">Mestrado</SelectItem>
|
||||
<SelectItem value="doutorado">Doutorado</SelectItem>
|
||||
<SelectItem value="fundamental">{t("register.candidate.education.fundamental")}</SelectItem>
|
||||
<SelectItem value="medio">{t("register.candidate.education.highSchool")}</SelectItem>
|
||||
<SelectItem value="tecnico">{t("register.candidate.education.technical")}</SelectItem>
|
||||
<SelectItem value="superior">{t("register.candidate.education.college")}</SelectItem>
|
||||
<SelectItem value="pos">{t("register.candidate.education.postgrad")}</SelectItem>
|
||||
<SelectItem value="mestrado">{t("register.candidate.education.masters")}</SelectItem>
|
||||
<SelectItem value="doutorado">{t("register.candidate.education.phd")}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.education && (
|
||||
|
|
@ -481,18 +488,18 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="experience">Experiência Profissional</Label>
|
||||
<Label htmlFor="experience">{t("register.candidate.fields.experience")}</Label>
|
||||
<Select onValueChange={(value) => setValue("experience", value)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Selecione sua experiência" />
|
||||
<SelectValue placeholder={t("register.candidate.placeholders.experience")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="sem-experiencia">Sem experiência</SelectItem>
|
||||
<SelectItem value="ate-1-ano">Até 1 ano</SelectItem>
|
||||
<SelectItem value="1-2-anos">1 a 2 anos</SelectItem>
|
||||
<SelectItem value="2-5-anos">2 a 5 anos</SelectItem>
|
||||
<SelectItem value="5-10-anos">5 a 10 anos</SelectItem>
|
||||
<SelectItem value="mais-10-anos">Mais de 10 anos</SelectItem>
|
||||
<SelectItem value="sem-experiencia">{t("register.candidate.experience.none")}</SelectItem>
|
||||
<SelectItem value="ate-1-ano">{t("register.candidate.experience.upToOne")}</SelectItem>
|
||||
<SelectItem value="1-2-anos">{t("register.candidate.experience.oneToTwo")}</SelectItem>
|
||||
<SelectItem value="2-5-anos">{t("register.candidate.experience.twoToFive")}</SelectItem>
|
||||
<SelectItem value="5-10-anos">{t("register.candidate.experience.fiveToTen")}</SelectItem>
|
||||
<SelectItem value="mais-10-anos">{t("register.candidate.experience.moreThanTen")}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.experience && (
|
||||
|
|
@ -501,20 +508,20 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="skills">Habilidades e Competências (opcional)</Label>
|
||||
<Label htmlFor="skills">{t("register.candidate.fields.skills")}</Label>
|
||||
<Textarea
|
||||
id="skills"
|
||||
placeholder="Ex: JavaScript, React, Photoshop, Inglês fluente..."
|
||||
placeholder={t("register.candidate.placeholders.skills")}
|
||||
className="min-h-[80px]"
|
||||
{...register("skills")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="objective">Objetivo Profissional (opcional)</Label>
|
||||
<Label htmlFor="objective">{t("register.candidate.fields.objective")}</Label>
|
||||
<Textarea
|
||||
id="objective"
|
||||
placeholder="Descreva seus objetivos e o que busca em uma oportunidade..."
|
||||
placeholder={t("register.candidate.placeholders.objective")}
|
||||
className="min-h-[80px]"
|
||||
{...register("objective")}
|
||||
/>
|
||||
|
|
@ -532,13 +539,13 @@ export default function CandidateRegisterPage() {
|
|||
htmlFor="acceptTerms"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Aceito os{" "}
|
||||
{t("register.candidate.acceptTerms.prefix")}{" "}
|
||||
<Link href="/termos" className="text-primary hover:underline">
|
||||
Termos de Uso
|
||||
{t("register.candidate.acceptTerms.terms")}
|
||||
</Link>{" "}
|
||||
e{" "}
|
||||
{t("register.candidate.acceptTerms.and")}{" "}
|
||||
<Link href="/privacidade" className="text-primary hover:underline">
|
||||
Política de Privacidade
|
||||
{t("register.candidate.acceptTerms.privacy")}
|
||||
</Link>
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -558,7 +565,7 @@ export default function CandidateRegisterPage() {
|
|||
htmlFor="acceptNewsletter"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Quero receber notificações sobre novas vagas por email
|
||||
{t("register.candidate.acceptNewsletter")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -566,10 +573,10 @@ export default function CandidateRegisterPage() {
|
|||
|
||||
<div className="flex gap-4">
|
||||
<Button type="button" variant="outline" onClick={prevStep} className="flex-1">
|
||||
Voltar
|
||||
{t("register.candidate.actions.back")}
|
||||
</Button>
|
||||
<Button type="submit" disabled={loading} className="flex-1">
|
||||
{loading ? "Criando conta..." : "Criar Conta"}
|
||||
{loading ? t("register.candidate.actions.creating") : t("register.candidate.actions.submit")}
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
|
@ -578,9 +585,9 @@ export default function CandidateRegisterPage() {
|
|||
|
||||
<div className="mt-6 text-center">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Já tem uma conta?{" "}
|
||||
{t("register.candidate.footer.prompt")}{" "}
|
||||
<Link href="/login" className="text-primary hover:underline font-medium">
|
||||
Faça login
|
||||
{t("register.candidate.footer.login")}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -588,4 +595,4 @@ export default function CandidateRegisterPage() {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,5 +105,111 @@
|
|||
"backLogin": "← Back to login"
|
||||
}
|
||||
},
|
||||
"register": {
|
||||
"candidate": {
|
||||
"title": "Create Account - Candidate",
|
||||
"subtitle": "Fill in your details to create your account",
|
||||
"success": "Registration completed! Please sign in to continue.",
|
||||
"hero": {
|
||||
"title": "Sign up as a Candidate",
|
||||
"subtitle": "Create your account and get access to the best job opportunities. Find your dream job today!",
|
||||
"bullets": {
|
||||
"jobs": "Access to thousands of jobs",
|
||||
"fastApplications": "Fast and easy applications",
|
||||
"profile": "Complete professional profile",
|
||||
"notifications": "New opportunity notifications"
|
||||
}
|
||||
},
|
||||
"progress": {
|
||||
"step": "Step {current} of {total}"
|
||||
},
|
||||
"steps": {
|
||||
"personal": "Personal Details",
|
||||
"address": "Address & Contact",
|
||||
"professional": "Professional Profile"
|
||||
},
|
||||
"fields": {
|
||||
"fullName": "Full Name",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"confirmPassword": "Confirm Password",
|
||||
"birthDate": "Date of Birth",
|
||||
"phone": "Phone",
|
||||
"address": "Address",
|
||||
"city": "City",
|
||||
"state": "State",
|
||||
"zipCode": "ZIP Code",
|
||||
"education": "Education Level",
|
||||
"experience": "Professional Experience",
|
||||
"skills": "Skills & Competencies (optional)",
|
||||
"objective": "Career Objective (optional)"
|
||||
},
|
||||
"placeholders": {
|
||||
"fullName": "Your full name",
|
||||
"email": "you@email.com",
|
||||
"password": "Your password",
|
||||
"confirmPassword": "Confirm your password",
|
||||
"phone": "(11) 99999-9999",
|
||||
"address": "Street, number, complement",
|
||||
"city": "Your city",
|
||||
"state": "State",
|
||||
"zipCode": "00000-000",
|
||||
"education": "Select your education level",
|
||||
"experience": "Select your experience",
|
||||
"skills": "e.g. JavaScript, React, Photoshop, Fluent English...",
|
||||
"objective": "Describe your goals and what you're looking for..."
|
||||
},
|
||||
"education": {
|
||||
"fundamental": "Primary School",
|
||||
"highSchool": "High School",
|
||||
"technical": "Technical",
|
||||
"college": "College",
|
||||
"postgrad": "Postgraduate",
|
||||
"masters": "Master's",
|
||||
"phd": "PhD"
|
||||
},
|
||||
"experience": {
|
||||
"none": "No experience",
|
||||
"upToOne": "Up to 1 year",
|
||||
"oneToTwo": "1 to 2 years",
|
||||
"twoToFive": "2 to 5 years",
|
||||
"fiveToTen": "5 to 10 years",
|
||||
"moreThanTen": "More than 10 years"
|
||||
},
|
||||
"acceptTerms": {
|
||||
"prefix": "I accept the",
|
||||
"terms": "Terms of Use",
|
||||
"and": "and",
|
||||
"privacy": "Privacy Policy"
|
||||
},
|
||||
"acceptNewsletter": "I want to receive notifications about new jobs by email",
|
||||
"actions": {
|
||||
"backToLogin": "Back to Login",
|
||||
"back": "Back",
|
||||
"next": "Next Step",
|
||||
"submit": "Create Account",
|
||||
"creating": "Creating account..."
|
||||
},
|
||||
"footer": {
|
||||
"prompt": "Already have an account?",
|
||||
"login": "Sign in"
|
||||
},
|
||||
"validation": {
|
||||
"fullName": "Name must be at least 2 characters",
|
||||
"email": "Invalid email",
|
||||
"password": "Password must be at least 6 characters",
|
||||
"passwordMismatch": "Passwords do not match",
|
||||
"phone": "Phone must be at least 10 digits",
|
||||
"birthDate": "Date of birth is required",
|
||||
"address": "Address must be at least 5 characters",
|
||||
"city": "City is required",
|
||||
"state": "State is required",
|
||||
"zipCode": "ZIP code must be 8 digits",
|
||||
"education": "Education level is required",
|
||||
"experience": "Professional experience is required",
|
||||
"acceptTerms": "You must accept the terms"
|
||||
}
|
||||
}
|
||||
},
|
||||
"common": { "loading": "Loading...", "error": "Error", "retry": "Retry", "noResults": "No results found" }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,5 +105,111 @@
|
|||
"backLogin": "← Volver al login"
|
||||
}
|
||||
},
|
||||
"register": {
|
||||
"candidate": {
|
||||
"title": "Crear Cuenta - Candidato",
|
||||
"subtitle": "Completa tus datos para crear tu cuenta",
|
||||
"success": "¡Registro completado! Inicia sesión para continuar.",
|
||||
"hero": {
|
||||
"title": "Regístrate como Candidato",
|
||||
"subtitle": "Crea tu cuenta y accede a las mejores oportunidades laborales. ¡Encuentra tu empleo soñado hoy mismo!",
|
||||
"bullets": {
|
||||
"jobs": "Acceso a miles de empleos",
|
||||
"fastApplications": "Postulaciones rápidas y fáciles",
|
||||
"profile": "Perfil profesional completo",
|
||||
"notifications": "Notificaciones de nuevas oportunidades"
|
||||
}
|
||||
},
|
||||
"progress": {
|
||||
"step": "Paso {current} de {total}"
|
||||
},
|
||||
"steps": {
|
||||
"personal": "Datos personales",
|
||||
"address": "Dirección y contacto",
|
||||
"professional": "Perfil profesional"
|
||||
},
|
||||
"fields": {
|
||||
"fullName": "Nombre completo",
|
||||
"email": "Correo electrónico",
|
||||
"password": "Contraseña",
|
||||
"confirmPassword": "Confirmar contraseña",
|
||||
"birthDate": "Fecha de nacimiento",
|
||||
"phone": "Teléfono",
|
||||
"address": "Dirección",
|
||||
"city": "Ciudad",
|
||||
"state": "Estado",
|
||||
"zipCode": "Código postal",
|
||||
"education": "Nivel de estudios",
|
||||
"experience": "Experiencia profesional",
|
||||
"skills": "Habilidades y competencias (opcional)",
|
||||
"objective": "Objetivo profesional (opcional)"
|
||||
},
|
||||
"placeholders": {
|
||||
"fullName": "Tu nombre completo",
|
||||
"email": "tu@email.com",
|
||||
"password": "Tu contraseña",
|
||||
"confirmPassword": "Confirma tu contraseña",
|
||||
"phone": "(11) 99999-9999",
|
||||
"address": "Calle, número, complemento",
|
||||
"city": "Tu ciudad",
|
||||
"state": "Estado",
|
||||
"zipCode": "00000-000",
|
||||
"education": "Selecciona tu nivel de estudios",
|
||||
"experience": "Selecciona tu experiencia",
|
||||
"skills": "Ej: JavaScript, React, Photoshop, Inglés fluido...",
|
||||
"objective": "Describe tus objetivos y lo que buscas..."
|
||||
},
|
||||
"education": {
|
||||
"fundamental": "Educación primaria",
|
||||
"highSchool": "Educación secundaria",
|
||||
"technical": "Técnico",
|
||||
"college": "Universidad",
|
||||
"postgrad": "Posgrado",
|
||||
"masters": "Maestría",
|
||||
"phd": "Doctorado"
|
||||
},
|
||||
"experience": {
|
||||
"none": "Sin experiencia",
|
||||
"upToOne": "Hasta 1 año",
|
||||
"oneToTwo": "1 a 2 años",
|
||||
"twoToFive": "2 a 5 años",
|
||||
"fiveToTen": "5 a 10 años",
|
||||
"moreThanTen": "Más de 10 años"
|
||||
},
|
||||
"acceptTerms": {
|
||||
"prefix": "Acepto los",
|
||||
"terms": "Términos de Uso",
|
||||
"and": "y",
|
||||
"privacy": "Política de Privacidad"
|
||||
},
|
||||
"acceptNewsletter": "Quiero recibir notificaciones sobre nuevas vacantes por email",
|
||||
"actions": {
|
||||
"backToLogin": "Volver al login",
|
||||
"back": "Volver",
|
||||
"next": "Siguiente paso",
|
||||
"submit": "Crear cuenta",
|
||||
"creating": "Creando cuenta..."
|
||||
},
|
||||
"footer": {
|
||||
"prompt": "¿Ya tienes una cuenta?",
|
||||
"login": "Inicia sesión"
|
||||
},
|
||||
"validation": {
|
||||
"fullName": "El nombre debe tener al menos 2 caracteres",
|
||||
"email": "Correo electrónico inválido",
|
||||
"password": "La contraseña debe tener al menos 6 caracteres",
|
||||
"passwordMismatch": "Las contraseñas no coinciden",
|
||||
"phone": "El teléfono debe tener al menos 10 dígitos",
|
||||
"birthDate": "La fecha de nacimiento es obligatoria",
|
||||
"address": "La dirección debe tener al menos 5 caracteres",
|
||||
"city": "La ciudad es obligatoria",
|
||||
"state": "El estado es obligatorio",
|
||||
"zipCode": "El código postal debe tener 8 dígitos",
|
||||
"education": "El nivel de estudios es obligatorio",
|
||||
"experience": "La experiencia profesional es obligatoria",
|
||||
"acceptTerms": "Debes aceptar los términos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"common": { "loading": "Cargando...", "error": "Error", "retry": "Reintentar", "noResults": "No se encontraron resultados" }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,5 +105,111 @@
|
|||
"backLogin": "← Voltar para login"
|
||||
}
|
||||
},
|
||||
"register": {
|
||||
"candidate": {
|
||||
"title": "Criar Conta - Candidato",
|
||||
"subtitle": "Preencha seus dados para criar sua conta",
|
||||
"success": "Cadastro realizado com sucesso! Faça login para continuar.",
|
||||
"hero": {
|
||||
"title": "Cadastre-se como Candidato",
|
||||
"subtitle": "Crie sua conta e tenha acesso às melhores oportunidades de emprego. Encontre a vaga dos seus sonhos hoje mesmo!",
|
||||
"bullets": {
|
||||
"jobs": "Acesso a milhares de vagas",
|
||||
"fastApplications": "Candidaturas rápidas e fáceis",
|
||||
"profile": "Perfil profissional completo",
|
||||
"notifications": "Notificações de novas oportunidades"
|
||||
}
|
||||
},
|
||||
"progress": {
|
||||
"step": "Etapa {current} de {total}"
|
||||
},
|
||||
"steps": {
|
||||
"personal": "Dados Pessoais",
|
||||
"address": "Endereço e Contato",
|
||||
"professional": "Perfil Profissional"
|
||||
},
|
||||
"fields": {
|
||||
"fullName": "Nome Completo",
|
||||
"email": "Email",
|
||||
"password": "Senha",
|
||||
"confirmPassword": "Confirmar Senha",
|
||||
"birthDate": "Data de Nascimento",
|
||||
"phone": "Telefone",
|
||||
"address": "Endereço",
|
||||
"city": "Cidade",
|
||||
"state": "Estado",
|
||||
"zipCode": "CEP",
|
||||
"education": "Nível de Escolaridade",
|
||||
"experience": "Experiência Profissional",
|
||||
"skills": "Habilidades e Competências (opcional)",
|
||||
"objective": "Objetivo Profissional (opcional)"
|
||||
},
|
||||
"placeholders": {
|
||||
"fullName": "Seu nome completo",
|
||||
"email": "seu@email.com",
|
||||
"password": "Sua senha",
|
||||
"confirmPassword": "Confirme sua senha",
|
||||
"phone": "(11) 99999-9999",
|
||||
"address": "Rua, número, complemento",
|
||||
"city": "Sua cidade",
|
||||
"state": "Estado",
|
||||
"zipCode": "00000-000",
|
||||
"education": "Selecione sua escolaridade",
|
||||
"experience": "Selecione sua experiência",
|
||||
"skills": "Ex: JavaScript, React, Photoshop, Inglês fluente...",
|
||||
"objective": "Descreva seus objetivos e o que busca em uma oportunidade..."
|
||||
},
|
||||
"education": {
|
||||
"fundamental": "Ensino Fundamental",
|
||||
"highSchool": "Ensino Médio",
|
||||
"technical": "Técnico",
|
||||
"college": "Ensino Superior",
|
||||
"postgrad": "Pós-graduação",
|
||||
"masters": "Mestrado",
|
||||
"phd": "Doutorado"
|
||||
},
|
||||
"experience": {
|
||||
"none": "Sem experiência",
|
||||
"upToOne": "Até 1 ano",
|
||||
"oneToTwo": "1 a 2 anos",
|
||||
"twoToFive": "2 a 5 anos",
|
||||
"fiveToTen": "5 a 10 anos",
|
||||
"moreThanTen": "Mais de 10 anos"
|
||||
},
|
||||
"acceptTerms": {
|
||||
"prefix": "Aceito os",
|
||||
"terms": "Termos de Uso",
|
||||
"and": "e",
|
||||
"privacy": "Política de Privacidade"
|
||||
},
|
||||
"acceptNewsletter": "Quero receber notificações sobre novas vagas por email",
|
||||
"actions": {
|
||||
"backToLogin": "Voltar ao Login",
|
||||
"back": "Voltar",
|
||||
"next": "Próxima Etapa",
|
||||
"submit": "Criar Conta",
|
||||
"creating": "Criando conta..."
|
||||
},
|
||||
"footer": {
|
||||
"prompt": "Já tem uma conta?",
|
||||
"login": "Faça login"
|
||||
},
|
||||
"validation": {
|
||||
"fullName": "Nome deve ter pelo menos 2 caracteres",
|
||||
"email": "Email inválido",
|
||||
"password": "Senha deve ter pelo menos 6 caracteres",
|
||||
"passwordMismatch": "Senhas não coincidem",
|
||||
"phone": "Telefone deve ter pelo menos 10 dígitos",
|
||||
"birthDate": "Data de nascimento é obrigatória",
|
||||
"address": "Endereço deve ter pelo menos 5 caracteres",
|
||||
"city": "Cidade é obrigatória",
|
||||
"state": "Estado é obrigatório",
|
||||
"zipCode": "CEP deve ter 8 dígitos",
|
||||
"education": "Nível de escolaridade é obrigatório",
|
||||
"experience": "Experiência profissional é obrigatória",
|
||||
"acceptTerms": "Você deve aceitar os termos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"common": { "loading": "Carregando...", "error": "Erro", "retry": "Tentar novamente", "noResults": "Nenhum resultado encontrado" }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue