Files
hounam-submit-form-frontend/ui/forms/jobRequest/InnerJobRequestForm.tsx
2026-06-02 17:08:52 +03:30

335 lines
11 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 React from "react";
import {
Box,
MenuItem,
TextField,
Typography,
Button,
IconButton,
Paper,
} 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 type {
JobRequestFormProps,
JobRequestFormValues,
JobRequestItem,
} from "./types";
import {
JOB_REQUEST_EMPTY_ITEM,
defaultCategories,
defaultJobs,
relationTypes,
shiftTypes,
} from "./constant";
type Props = FormikProps<JobRequestFormValues> & JobRequestFormProps;
export default function InnerJobRequestForm(props: Props) {
const {
values,
errors,
touched,
handleChange,
setFieldValue,
jobCategories = defaultCategories,
jobs = defaultJobs,
isSubmitting,
} = props;
const handleBack = () => {
props.update({
jobRequests: props.values.jobRequests,
});
props.setStep(props.step - 1);
};
return (
<Form>
<FieldArray name="jobRequests">
{({ push, remove }) => (
<>
{values.jobRequests.map((item: JobRequestItem, index: number) => {
const itemErrors = getIn(errors, `jobRequests.${index}`) || {};
const itemTouched = getIn(touched, `jobRequests.${index}`) || {};
const filteredJobs = jobs.filter(
(job) => job.jobCategoryId === item.jobCategoryId,
);
return (
<Paper
key={item.id || index}
elevation={0}
sx={{
borderRadius: "24px",
backgroundColor: "#ffffff",
border: "1px solid #e2e8f0",
p: 3,
mb: 3,
position: "relative",
}}
>
{values.jobRequests.length > 1 && (
<IconButton
onClick={() => remove(index)}
color="error"
sx={{
position: "absolute",
top: 12,
right: 12,
zIndex: 1,
}}
aria-label="remove-job-request"
>
<DeleteOutlineOutlinedIcon />
</IconButton>
)}
<Typography
sx={{
fontWeight: 700,
mb: 3,
color: "#0f172a",
}}
>
درخواست شغلی {index + 1}
</Typography>
<Box
sx={{
display: "grid",
gridTemplateColumns:
"repeat(auto-fit, minmax(340px, 1fr))",
gap: 2,
}}
>
<TextField
select
fullWidth
label="رسته شغلی*"
name={`jobRequests.${index}.jobCategoryId`}
value={item.jobCategoryId}
onChange={(e) => {
const categoryId = e.target.value;
setFieldValue(
`jobRequests.${index}.jobCategoryId`,
categoryId,
);
setFieldValue(`jobRequests.${index}.jobId`, "");
}}
error={
!!itemTouched.jobCategoryId &&
!!itemErrors.jobCategoryId
}
helperText={
itemTouched.jobCategoryId
? itemErrors.jobCategoryId
: " "
}
>
<MenuItem value="">انتخاب...</MenuItem>
{jobCategories.map((category) => (
<MenuItem key={category.id} value={category.id}>
{category.name}
</MenuItem>
))}
</TextField>
<TextField
select
fullWidth
label="شغل درخواستی*"
name={`jobRequests.${index}.jobId`}
value={item.jobId}
onChange={handleChange}
error={!!itemTouched.jobId && !!itemErrors.jobId}
helperText={itemTouched.jobId ? itemErrors.jobId : " "}
disabled={!item.jobCategoryId}
>
<MenuItem value="">انتخاب...</MenuItem>
{filteredJobs.map((job) => (
<MenuItem key={job.id} value={job.id}>
{job.title}
</MenuItem>
))}
</TextField>
<TextField
fullWidth
label="توضیحات شغل درخواست"
name={`jobRequests.${index}.requestedJobDescription`}
value={item.requestedJobDescription}
onChange={handleChange}
error={
!!itemTouched.requestedJobDescription &&
!!itemErrors.requestedJobDescription
}
helperText={
itemTouched.requestedJobDescription
? itemErrors.requestedJobDescription
: ""
}
/>
<TextField
select
fullWidth
label="نوع رابطه کاری*"
name={`jobRequests.${index}.employmentRelationType`}
value={item.employmentRelationType}
onChange={handleChange}
error={
!!itemTouched.employmentRelationType &&
!!itemErrors.employmentRelationType
}
helperText={
itemTouched.employmentRelationType
? itemErrors.employmentRelationType
: " "
}
>
<MenuItem value="">انتخاب...</MenuItem>
{relationTypes.map((relation) => (
<MenuItem key={relation} value={relation}>
{relation}
</MenuItem>
))}
</TextField>
<TextField
select
fullWidth
label="نوع شیفت درخواستی"
name={`jobRequests.${index}.requestedShiftType`}
value={item.requestedShiftType}
onChange={handleChange}
error={
!!itemTouched.requestedShiftType &&
!!itemErrors.requestedShiftType
}
helperText={
itemTouched.requestedShiftType
? itemErrors.requestedShiftType
: ""
}
>
<MenuItem value="">انتخاب...</MenuItem>
{shiftTypes.map((shift) => (
<MenuItem key={shift} value={shift}>
{shift}
</MenuItem>
))}
</TextField>
<TextField
fullWidth
label="حقوق درخواستی (ریال)"
name={`jobRequests.${index}.expectedSalary`}
value={item.expectedSalary}
onChange={(e) => {
const onlyDigits = e.target.value.replace(/[^\d]/g, "");
setFieldValue(
`jobRequests.${index}.expectedSalary`,
onlyDigits,
);
}}
error={
!!itemTouched.expectedSalary &&
!!itemErrors.expectedSalary
}
helperText={
itemTouched.expectedSalary
? itemErrors.expectedSalary
: ""
}
/>
<Box sx={{ gridColumn: { xs: "1", md: "1 / -1" } }}>
<TextField
fullWidth
label="توضیحات"
name={`jobRequests.${index}.description`}
value={item.description}
onChange={handleChange}
multiline
minRows={3}
error={
!!itemTouched.description && !!itemErrors.description
}
helperText={
itemTouched.description ? itemErrors.description : ""
}
/>
</Box>
</Box>
</Paper>
);
})}
<Button
type="button"
variant="outlined"
startIcon={<AddIcon />}
onClick={() =>
push({
...JOB_REQUEST_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 || 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>
</>
)}
</FieldArray>
</Form>
);
}