350 lines
12 KiB
TypeScript
350 lines
12 KiB
TypeScript
"use client";
|
||
|
||
import React from "react";
|
||
import {
|
||
Box,
|
||
MenuItem,
|
||
Paper,
|
||
TextField,
|
||
Typography,
|
||
Divider,
|
||
Switch,
|
||
FormControlLabel,
|
||
Button,
|
||
} from "@mui/material";
|
||
import { Form, type FormikProps } from "formik";
|
||
import type { SkillsFormProps, SkillsFormValues } from "./types";
|
||
import { certTypes, proficiencyOptions } from "./constant";
|
||
|
||
type Props = FormikProps<SkillsFormValues> & SkillsFormProps;
|
||
|
||
export default function InnerSkillsForm(props: Props) {
|
||
const { values, errors, touched, handleChange, setFieldValue, isSubmitting } = props;
|
||
|
||
const handleBack = () => {
|
||
props.update({
|
||
computerSkill: values.computerSkill,
|
||
languageSkill: values.languageSkill,
|
||
});
|
||
props.setStep(props.step - 1);
|
||
};
|
||
|
||
const compFields = [
|
||
"pcUsage",
|
||
"word",
|
||
"excel",
|
||
"powerPoint",
|
||
"rahkaran",
|
||
"kasra",
|
||
"didgah",
|
||
"his",
|
||
] as const;
|
||
|
||
return (
|
||
<Form>
|
||
<Box sx={{ display: "grid", gap: 3 }}>
|
||
|
||
{/* 1. Computer Skills Section */}
|
||
<Paper
|
||
elevation={0}
|
||
sx={{
|
||
p: { xs: 2, md: 3 },
|
||
borderRadius: "24px",
|
||
border: "1px solid #e2e8f0",
|
||
backgroundColor: "#ffffff",
|
||
}}
|
||
>
|
||
<Typography variant="h6" sx={{ mb: 3, fontWeight: "bold", color: "#0f172a" }}>
|
||
مهارتهای کامپیوتری
|
||
</Typography>
|
||
|
||
<Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "repeat(4, 1fr)" }, gap: 2 }}>
|
||
{compFields.map((field) => {
|
||
const hasError = !!errors.computerSkill?.[field] && !!touched.computerSkill?.[field];
|
||
return (
|
||
<TextField
|
||
key={field}
|
||
select
|
||
label={field.toUpperCase()}
|
||
name={`computerSkill.${field}`}
|
||
value={values.computerSkill[field]}
|
||
onChange={handleChange}
|
||
error={hasError}
|
||
helperText={hasError ? errors.computerSkill?.[field] : ""}
|
||
fullWidth
|
||
>
|
||
{proficiencyOptions.map((o) => (
|
||
<MenuItem key={o.value} value={o.value}>
|
||
{o.label}
|
||
</MenuItem>
|
||
))}
|
||
</TextField>
|
||
);
|
||
})}
|
||
|
||
<TextField
|
||
label="سایر نرمافزارها"
|
||
name="computerSkill.otherSoftware"
|
||
value={values.computerSkill.otherSoftware || ""}
|
||
onChange={handleChange}
|
||
error={!!errors.computerSkill?.otherSoftware && !!touched.computerSkill?.otherSoftware}
|
||
helperText={
|
||
touched.computerSkill?.otherSoftware ? errors.computerSkill?.otherSoftware : ""
|
||
}
|
||
fullWidth
|
||
multiline
|
||
minRows={2}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
</Box>
|
||
</Paper>
|
||
|
||
{/* 2. Language Skills Section */}
|
||
<Paper
|
||
elevation={0}
|
||
sx={{
|
||
p: { xs: 2, md: 3 },
|
||
borderRadius: "24px",
|
||
border: "1px solid #e2e8f0",
|
||
backgroundColor: "#ffffff",
|
||
}}
|
||
>
|
||
<Typography variant="h6" sx={{ mb: 3, fontWeight: "bold", color: "#0f172a" }}>
|
||
آشنایی با زبانهای خارجه
|
||
</Typography>
|
||
|
||
<Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 2 }}>
|
||
|
||
{/* English */}
|
||
<TextField
|
||
select
|
||
label="زبان انگلیسی*"
|
||
name="languageSkill.englishLevel"
|
||
value={values.languageSkill.englishLevel}
|
||
onChange={handleChange}
|
||
error={!!errors.languageSkill?.englishLevel && !!touched.languageSkill?.englishLevel}
|
||
helperText={
|
||
touched.languageSkill?.englishLevel ? errors.languageSkill?.englishLevel : " "
|
||
}
|
||
fullWidth
|
||
>
|
||
{proficiencyOptions.map((o) => (
|
||
<MenuItem key={o.value} value={o.value}>
|
||
{o.label}
|
||
</MenuItem>
|
||
))}
|
||
</TextField>
|
||
|
||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||
<FormControlLabel
|
||
control={
|
||
<Switch
|
||
checked={values.languageSkill.hasEnglishCertificate}
|
||
onChange={(e) => {
|
||
const checked = e.target.checked;
|
||
setFieldValue("languageSkill.hasEnglishCertificate", checked);
|
||
if (!checked) {
|
||
// پاکسازی فیلد نوع مدرک در صورت غیرفعال شدن سوئیچ
|
||
setFieldValue("languageSkill.englishCertificateType", "");
|
||
}
|
||
}}
|
||
/>
|
||
}
|
||
label="مدرک معتبر زبان انگلیسی دارد"
|
||
/>
|
||
</Box>
|
||
|
||
{values.languageSkill.hasEnglishCertificate && (
|
||
<TextField
|
||
select
|
||
label="نوع مدرک*"
|
||
name="languageSkill.englishCertificateType"
|
||
value={values.languageSkill.englishCertificateType}
|
||
onChange={handleChange}
|
||
error={
|
||
!!errors.languageSkill?.englishCertificateType &&
|
||
!!touched.languageSkill?.englishCertificateType
|
||
}
|
||
helperText={
|
||
touched.languageSkill?.englishCertificateType
|
||
? errors.languageSkill?.englishCertificateType
|
||
: " "
|
||
}
|
||
fullWidth
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
>
|
||
<MenuItem value="">انتخاب...</MenuItem>
|
||
{certTypes.map((t) => (
|
||
<MenuItem key={t} value={t}>
|
||
{t}
|
||
</MenuItem>
|
||
))}
|
||
</TextField>
|
||
)}
|
||
|
||
<TextField
|
||
label="توضیحات زبان انگلیسی"
|
||
name="languageSkill.englishDescription"
|
||
value={values.languageSkill.englishDescription}
|
||
onChange={handleChange}
|
||
error={
|
||
!!errors.languageSkill?.englishDescription &&
|
||
!!touched.languageSkill?.englishDescription
|
||
}
|
||
helperText={
|
||
touched.languageSkill?.englishDescription
|
||
? errors.languageSkill?.englishDescription
|
||
: ""
|
||
}
|
||
fullWidth
|
||
multiline
|
||
minRows={2}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
|
||
<Divider sx={{ gridColumn: { xs: "1", md: "1 / -1" }, my: 1 }} />
|
||
|
||
{/* Arabic */}
|
||
<TextField
|
||
select
|
||
label="زبان عربی*"
|
||
name="languageSkill.arabicLevel"
|
||
value={values.languageSkill.arabicLevel}
|
||
onChange={handleChange}
|
||
error={!!errors.languageSkill?.arabicLevel && !!touched.languageSkill?.arabicLevel}
|
||
helperText={
|
||
touched.languageSkill?.arabicLevel ? errors.languageSkill?.arabicLevel : " "
|
||
}
|
||
fullWidth
|
||
>
|
||
{proficiencyOptions.map((o) => (
|
||
<MenuItem key={o.value} value={o.value}>
|
||
{o.label}
|
||
</MenuItem>
|
||
))}
|
||
</TextField>
|
||
|
||
<Box />
|
||
|
||
<TextField
|
||
label="توضیحات زبان عربی"
|
||
name="languageSkill.arabicDescription"
|
||
value={values.languageSkill.arabicDescription}
|
||
onChange={handleChange}
|
||
error={
|
||
!!errors.languageSkill?.arabicDescription &&
|
||
!!touched.languageSkill?.arabicDescription
|
||
}
|
||
helperText={
|
||
touched.languageSkill?.arabicDescription
|
||
? errors.languageSkill?.arabicDescription
|
||
: ""
|
||
}
|
||
fullWidth
|
||
multiline
|
||
minRows={2}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
|
||
<Divider sx={{ gridColumn: { xs: "1", md: "1 / -1" }, my: 1 }} />
|
||
|
||
{/* Other Skills */}
|
||
<TextField
|
||
label="سایر زبان ها (توضیحات در مورد میزان تسلط)"
|
||
name="languageSkill.otherLanguagesDescription"
|
||
value={values.languageSkill.otherLanguagesDescription}
|
||
onChange={handleChange}
|
||
error={
|
||
!!errors.languageSkill?.otherLanguagesDescription &&
|
||
!!touched.languageSkill?.otherLanguagesDescription
|
||
}
|
||
helperText={
|
||
touched.languageSkill?.otherLanguagesDescription
|
||
? errors.languageSkill?.otherLanguagesDescription
|
||
: ""
|
||
}
|
||
fullWidth
|
||
multiline
|
||
minRows={2}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
|
||
<TextField
|
||
label="آشنایی با گویش ها و لهجه های کشور (توضیحات در مورد میزان تسلط)"
|
||
name="languageSkill.dialectsDescription"
|
||
value={values.languageSkill.dialectsDescription}
|
||
onChange={handleChange}
|
||
error={
|
||
!!errors.languageSkill?.dialectsDescription &&
|
||
!!touched.languageSkill?.dialectsDescription
|
||
}
|
||
helperText={
|
||
touched.languageSkill?.dialectsDescription
|
||
? errors.languageSkill?.dialectsDescription
|
||
: ""
|
||
}
|
||
fullWidth
|
||
multiline
|
||
minRows={2}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
|
||
<TextField
|
||
label="سایر مهارت ها (اعم از ورزشی، هنری، فرهنگی، اجتماعی و ...)"
|
||
name="languageSkill.otherSkills"
|
||
value={values.languageSkill.otherSkills}
|
||
onChange={handleChange}
|
||
error={!!errors.languageSkill?.otherSkills && !!touched.languageSkill?.otherSkills}
|
||
helperText={
|
||
touched.languageSkill?.otherSkills ? errors.languageSkill?.otherSkills : ""
|
||
}
|
||
fullWidth
|
||
multiline
|
||
minRows={3}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
</Box>
|
||
</Paper>
|
||
|
||
{/* Wizard Navigation Buttons */}
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
justifyContent: "space-between",
|
||
mt: 2,
|
||
width: "100%",
|
||
}}
|
||
>
|
||
<Button
|
||
disabled={props.step === 1 || isSubmitting}
|
||
type="button"
|
||
onClick={handleBack}
|
||
sx={{
|
||
borderRadius: "12px",
|
||
color: "#64748b",
|
||
fontWeight: 700,
|
||
}}
|
||
>
|
||
بازگشت
|
||
</Button>
|
||
|
||
<Button
|
||
variant="contained"
|
||
type="submit"
|
||
disabled={isSubmitting}
|
||
sx={{
|
||
borderRadius: "12px",
|
||
px: 4,
|
||
py: 1.5,
|
||
bgcolor: props.step === 12 ? "green" : "#2563eb",
|
||
fontWeight: 700,
|
||
}}
|
||
>
|
||
{props.step === 12 ? "اتمام و ثبت نهایی" : "گام بعدی"}
|
||
</Button>
|
||
</Box>
|
||
</Box>
|
||
</Form>
|
||
);
|
||
}
|