208 lines
6.8 KiB
TypeScript
208 lines
6.8 KiB
TypeScript
"use client";
|
||
|
||
import React from "react";
|
||
import {
|
||
Box,
|
||
TextField,
|
||
IconButton,
|
||
Button,
|
||
Typography,
|
||
} from "@mui/material";
|
||
import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined";
|
||
import AddIcon from "@mui/icons-material/Add";
|
||
import { FieldArray, Form, getIn, type FormikProps } from "formik";
|
||
import { COURSE_EMPTY_ITEM, CourseFormProps, CourseFormValues, CourseItem } from "./CourseForm";
|
||
|
||
|
||
type Props = FormikProps<CourseFormValues> & CourseFormProps;
|
||
|
||
export default function InnerCourseForm(props: Props) {
|
||
const { values, errors, touched, handleChange, setFieldValue } = props;
|
||
|
||
const handleBack = () => {
|
||
props.update({ courses: props.values.courses });
|
||
props.setStep(props.step - 1);
|
||
};
|
||
|
||
return (
|
||
<Form>
|
||
<FieldArray name="courses">
|
||
{({ push, remove }) => (
|
||
<>
|
||
{values.courses.map((course: CourseItem, index: number) => {
|
||
const itemErrors = getIn(errors, `courses.${index}`) || {};
|
||
const itemTouched = getIn(touched, `courses.${index}`) || {};
|
||
|
||
return (
|
||
<Box
|
||
key={index}
|
||
sx={{
|
||
mb: 3,
|
||
position: "relative",
|
||
border: "1px solid #e2e8f0",
|
||
borderRadius: "16px",
|
||
p: 2,
|
||
backgroundColor: "#fff",
|
||
}}
|
||
>
|
||
{values.courses.length > 1 && (
|
||
<IconButton
|
||
onClick={() => remove(index)}
|
||
color="error"
|
||
sx={{ position: "absolute", top: 8, right: 8, zIndex: 2 }}
|
||
aria-label="remove-course"
|
||
>
|
||
<DeleteOutlineOutlinedIcon />
|
||
</IconButton>
|
||
)}
|
||
|
||
<Typography
|
||
sx={{
|
||
fontWeight: 700,
|
||
mb: 2,
|
||
color: "#0f172a",
|
||
}}
|
||
>
|
||
دوره {index + 1}
|
||
</Typography>
|
||
|
||
<Box
|
||
sx={{
|
||
display: "grid",
|
||
gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
|
||
gap: 2,
|
||
}}
|
||
>
|
||
<TextField
|
||
fullWidth
|
||
label="عنوان دوره"
|
||
name={`courses.${index}.title`}
|
||
value={course.title}
|
||
onChange={handleChange}
|
||
error={!!itemTouched.title && !!itemErrors.title}
|
||
helperText={itemTouched.title ? itemErrors.title : ""}
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
label="موسسه برگزار کننده"
|
||
name={`courses.${index}.institution`}
|
||
value={course.institution}
|
||
onChange={handleChange}
|
||
error={
|
||
!!itemTouched.institution && !!itemErrors.institution
|
||
}
|
||
helperText={
|
||
itemTouched.institution ? itemErrors.institution : ""
|
||
}
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
type="number"
|
||
label="سال برگزاری"
|
||
name={`courses.${index}.year`}
|
||
value={course.year}
|
||
onChange={(e) =>
|
||
setFieldValue(
|
||
`courses.${index}.year`,
|
||
e.target.value === "" ? "" : Number(e.target.value),
|
||
)
|
||
}
|
||
error={!!itemTouched.year && !!itemErrors.year}
|
||
helperText={itemTouched.year ? itemErrors.year : ""}
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
label="مدت دوره"
|
||
name={`courses.${index}.duration`}
|
||
value={course.duration}
|
||
onChange={handleChange}
|
||
placeholder="مثلاً 40 ساعت"
|
||
error={!!itemTouched.duration && !!itemErrors.duration}
|
||
helperText={itemTouched.duration ? itemErrors.duration : ""}
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
multiline
|
||
minRows={2}
|
||
label="توضیحات"
|
||
name={`courses.${index}.description`}
|
||
value={course.description || ""}
|
||
onChange={handleChange}
|
||
error={
|
||
!!itemTouched.description && !!itemErrors.description
|
||
}
|
||
helperText={
|
||
itemTouched.description ? itemErrors.description : ""
|
||
}
|
||
sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}
|
||
/>
|
||
</Box>
|
||
</Box>
|
||
);
|
||
})}
|
||
|
||
<Button
|
||
type="button"
|
||
variant="outlined"
|
||
startIcon={<AddIcon />}
|
||
onClick={() =>
|
||
push({
|
||
...COURSE_EMPTY_ITEM,
|
||
id: Date.now(),
|
||
})
|
||
}
|
||
sx={{
|
||
borderRadius: "12px",
|
||
mb: 3,
|
||
fontWeight: 700,
|
||
}}
|
||
>
|
||
افزودن دوره
|
||
</Button>
|
||
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
justifyContent: "space-between",
|
||
mt: 5,
|
||
width: "100%",
|
||
}}
|
||
>
|
||
<Button
|
||
disabled={props.step === 1}
|
||
type="button"
|
||
onClick={handleBack}
|
||
sx={{
|
||
borderRadius: "12px",
|
||
color: "#64748b",
|
||
fontWeight: 700,
|
||
}}
|
||
>
|
||
بازگشت
|
||
</Button>
|
||
|
||
<Button
|
||
variant="contained"
|
||
type="submit"
|
||
sx={{
|
||
borderRadius: "12px",
|
||
px: 4,
|
||
py: 1.5,
|
||
bgcolor: `${props.step === 12 ? "green" : "#2563eb"}`,
|
||
fontWeight: 700,
|
||
}}
|
||
>
|
||
{props.step === 12 ? "اتمام و ثبت نهايي" : "گام بعدی"}
|
||
</Button>
|
||
</Box>
|
||
</>
|
||
)}
|
||
</FieldArray>
|
||
</Form>
|
||
);
|
||
}
|