cba4bc30da
git-subtree-dir: web git-subtree-mainline:75a0ba593dgit-subtree-split:8f624e7416
93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
import { StepFooterButton } from "@/components/onboarding/StepFooterButton";
|
||
import { ErrorBanner } from "@/components/ui/ErrorBanner";
|
||
import { FullScreenLoader } from "@/components/ui/FullScreenLoader";
|
||
import { OptionPicker } from "@/components/ui/OptionPicker";
|
||
import { getOptions, submitEducation, Option, FullProfile } from "@/lib/api";
|
||
import { formatApiError } from "@/lib/hooks";
|
||
|
||
function findSelection(profile: FullProfile | null, key: string): number[] {
|
||
return profile?.selections.find((s) => s.category_key === key)?.option_ids ?? [];
|
||
}
|
||
|
||
export function EducationStep({
|
||
initialProfile,
|
||
onNext,
|
||
}: {
|
||
initialProfile: FullProfile | null;
|
||
onNext: () => void;
|
||
}) {
|
||
const [levelOptions, setLevelOptions] = useState<Option[] | null>(null);
|
||
const [fieldOptions, setFieldOptions] = useState<Option[] | null>(null);
|
||
const [levelId, setLevelId] = useState<number[]>(
|
||
findSelection(initialProfile, "education_level")
|
||
);
|
||
const [fieldId, setFieldId] = useState<number[]>(
|
||
findSelection(initialProfile, "field_of_study")
|
||
);
|
||
const [loading, setLoading] = useState(false);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
useEffect(() => {
|
||
Promise.all([getOptions("education_level"), getOptions("field_of_study")])
|
||
.then(([lvl, field]) => {
|
||
setLevelOptions(lvl);
|
||
setFieldOptions(field);
|
||
})
|
||
.catch((err) => setError(formatApiError(err)));
|
||
}, []);
|
||
|
||
const isValid = levelId.length === 1 && fieldId.length === 1;
|
||
|
||
async function handleSubmit() {
|
||
if (!isValid) return;
|
||
setLoading(true);
|
||
setError(null);
|
||
try {
|
||
await submitEducation({
|
||
education_level_option_id: levelId[0],
|
||
field_of_study_option_id: fieldId[0],
|
||
});
|
||
onNext();
|
||
} catch (err) {
|
||
setError(formatApiError(err));
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}
|
||
|
||
if (!levelOptions || !fieldOptions) return <FullScreenLoader label="گزینهها رو میاریم..." />;
|
||
|
||
if (levelOptions.length === 0 || fieldOptions.length === 0) {
|
||
return (
|
||
<ErrorBanner message="هنوز گزینهای برای تحصیلات توی پنل ادمین ثبت نشده. اول باید ادمین اینها رو اضافه کنه." />
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="flex flex-col gap-7">
|
||
<div className="flex flex-col gap-3">
|
||
<label className="text-[13px] font-semibold text-(--color-content-secondary) px-1">
|
||
سطح تحصیلات
|
||
</label>
|
||
<OptionPicker options={levelOptions} selectedIds={levelId} onChange={setLevelId} mode="single" />
|
||
</div>
|
||
|
||
<div className="flex flex-col gap-3">
|
||
<label className="text-[13px] font-semibold text-(--color-content-secondary) px-1">
|
||
رشته تحصیلی
|
||
</label>
|
||
<OptionPicker options={fieldOptions} selectedIds={fieldId} onChange={setFieldId} mode="single" />
|
||
</div>
|
||
|
||
<ErrorBanner message={error} />
|
||
|
||
<StepFooterButton disabled={!isValid} isLoading={loading} onClick={handleSubmit}>
|
||
بریم مرحله بعد
|
||
</StepFooterButton>
|
||
</div>
|
||
);
|
||
}
|