Files
chat_room/web/src/components/onboarding/steps/EducationStep.tsx
T
mobiniqow cba4bc30da chore: merge web repo history into monorepo at web/
git-subtree-dir: web
git-subtree-mainline: 75a0ba593d
git-subtree-split: 8f624e7416
2026-09-27 10:31:24 +03:30

93 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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>
);
}