Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/app/(app)/karrier/components/application-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect, useRef, useState } from "react"
import {
MAX_CV_SIZE,
validateAnswers,
validateCVPresence,
type Answer,
type FormConfig,
type FormQuestion,
Expand Down Expand Up @@ -239,6 +240,11 @@ export default function ApplicationForm({
showError(validated.error, validated.field)
return
}
const cvPresence = validateCVPresence(!!cv, config)
if (cvPresence !== true) {
showError(cvPresence, "cv")
return
}
setStatus("submitting")
setErrorMessage(null)
setErrorField(undefined)
Expand Down Expand Up @@ -315,7 +321,14 @@ export default function ApplicationForm({
className="mb-2 flex items-center gap-2 text-sm font-medium"
>
<Paperclip size={17} aria-hidden />
{isEn ? "CV (optional)" : "Önéletrajz (opcionális)"}
{isEn ? "CV" : "Önéletrajz"}
{config.cvRequired ? (
" *"
) : (
<span className="font-normal text-career-muted">
{` (${isEn ? "optional" : "opcionális"})`}
</span>
)}
</label>
<p id="cv-help" className="mb-3 text-sm text-career-muted">
{isEn
Expand All @@ -329,6 +342,8 @@ export default function ApplicationForm({
type="file"
accept=".pdf,application/pdf"
aria-describedby="cv-help"
aria-invalid={errorField === "cv" || undefined}
required={config.cvRequired}
className="block w-full min-w-0 text-sm file:mr-3 file:rounded-lg file:border-0 file:bg-career-accent-soft file:px-4 file:py-2 file:text-career-accent"
onChange={(event) => {
const file = event.target.files?.[0] ?? null
Expand Down
7 changes: 3 additions & 4 deletions src/app/(app)/karrier/components/career-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,9 @@ export default function CareerGroup({
<div className="flex flex-1 items-center gap-4 px-5 py-5">
<div className="min-w-0 flex-1">
<h2 className="mb-2 text-2xl font-bold">{groupName}</h2>
{/* A sávban csak rövid, szöveges előnézet fér el. A CMS-ben a leírás
beágyazott képet is tartalmazhat — azt itt elrejtjük, különben
szétfeszítené a sávot. */}
<div className="rich-text-content line-clamp-3 text-sm break-words text-career-muted [&_img]:hidden">
{/* A teljes formázott leírást megjelenítjük. A CMS-ben beágyazott kép is
szerepelhet — azt itt elrejtjük, hogy ne feszítse szét a csoportsávot. */}
<div className="rich-text-content text-sm break-words text-career-muted [&_img]:hidden">
<RichText data={isEn ? group.descriptionEng : group.description} />
</div>
<p className="mt-3 text-xs uppercase tracking-wide text-career-muted">
Expand Down
2 changes: 2 additions & 0 deletions src/app/(app)/karrier/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export function applicationErrorText(code: string, isEn: boolean) {
return isEn ? "The upload is too large. The PDF may be at most 5 MiB." : "A feltöltés túl nagy. A PDF legfeljebb 5 MiB lehet."
case "INVALID_CV":
return isEn ? "Please choose a valid, unencrypted PDF document." : "Kérlek, válassz érvényes, jelszóval nem védett PDF-dokumentumot."
case "MISSING_CV":
return isEn ? "Please attach your CV in PDF format." : "Kérlek, csatold az önéletrajzodat PDF formátumban."
case "MISSING_FIELDS":
return isEn
? "Please fill in the required fields and accept the data processing consent."
Expand Down
7 changes: 7 additions & 0 deletions src/app/api/karrier/jelentkezes/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "@/lib/application-upload";
import {
resolveFormConfig,
validateCVPresence,
validateAnswers,
summarizeAnswers,
type CoreKey,
Expand Down Expand Up @@ -57,6 +58,12 @@ export async function POST(request: Request) {
{ error: parsed.error, field: parsed.field },
{ status: 400 },
);
const cvPresence = validateCVPresence(!!cv, formConfig);
if (cvPresence !== true)
return NextResponse.json(
{ error: cvPresence, field: "cv" },
{ status: 400 },
);
const language = body.language === "en" ? "en" : "hu";
if (cv) {
const bytes = await validateCV(cv);
Expand Down
11 changes: 11 additions & 0 deletions src/collections/CareerSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,17 @@ export const CareerSettings: GlobalConfig = {
return true;
},
},
{
name: "cvRequired",
type: "checkbox",
defaultValue: false,
label: "Önéletrajz kötelező",
admin: {
description:
"Bekapcsolva a beépített jelentkezési űrlap csak PDF önéletrajzzal küldhető be.",
condition: (data) => data?.applicationMode !== "googleForm",
},
},
{
name: "applicationsOpen",
type: "checkbox",
Expand Down
10 changes: 10 additions & 0 deletions src/lib/career-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface FormQuestion {
export interface FormConfig {
version: string
questions: FormQuestion[]
cvRequired: boolean
}
export const MAX_CV_SIZE = 5 * 1024 * 1024
export const DEFAULT_QUESTIONS: FormQuestion[] = [
Expand Down Expand Up @@ -99,6 +100,7 @@ export const DEFAULT_QUESTIONS: FormQuestion[] = [
export function resolveFormConfig(
settings?: {
formQuestions?: FormQuestion[] | null
cvRequired?: boolean | null
updatedAt?: string | null
} | null,
): FormConfig {
Expand All @@ -107,8 +109,16 @@ export function resolveFormConfig(
questions: settings?.formQuestions?.length
? settings.formQuestions
: DEFAULT_QUESTIONS,
cvRequired: settings?.cvRequired === true,
}
}

export function validateCVPresence(
hasCV: boolean,
config: Pick<FormConfig, "cvRequired">,
): true | "MISSING_CV" {
return config.cvRequired && !hasCV ? "MISSING_CV" : true
}
export function validateQuestions(questions: FormQuestion[]): true | string {
if (!questions.length || questions.length > 50)
return "Az űrlap 1–50 kérdést tartalmazhat."
Expand Down
Loading
Loading