Files
expert-front/src/components/dashboard/machinary-office/Form/ConfirmForm/ConfirmContent.jsx

378 lines
18 KiB
JavaScript

import UploadSystem from "@/core/components/UploadSystem";
import useNotification from "@/lib/app/hooks/useNotification";
import useRequest from "@/lib/app/hooks/useRequest";
import {
Button,
DialogActions,
DialogContent,
FormHelperText,
Grid,
LinearProgress,
Stack,
TextField,
Typography
} from "@mui/material"
import {useFormik} from "formik";
import {useTranslations} from "next-intl";
import {CONFIRM_MACHINARY_OFFICE, CONFIRM_MACHINARY_OFFICE_DETAILS} from "@/core/data/apiRoutes";
import {useEffect, useState} from "react";
import PriceField from "@/core/components/PriceField";
import * as Yup from "yup";
import CustomAccordion from "@/core/components/CustomAccordion";
import ImageContent from "@/core/components/ImageContent";
import SelectBox from "@/core/components/SelectBox";
const vehicle_amount = {
"اتوبوس": 7000,
"مینی بوس": 2000,
}
const ConfirmContent = ({mutate, setOpenConfirmDialog, rowId, vehicle_type, handleSizeChangeClick}) => {
const t = useTranslations();
const [selectedImage, setSelectedImage] = useState("");
const [fileType, setfileType] = useState(null);
const [fileName, setfileName] = useState(null);
const [showAddIcon, setShowAddIcon] = useState(true);
const requestServer = useRequest({auth: true, notification: false})
const {update_notification} = useNotification()
const [accordionStates, setAccordionStates] = useState([]);
const [hasImageShown, setHasImageShown] = useState(false);
const [imageLink, setImageLink] = useState(null);
const [detailsList, setDetailsData] = useState(null);
const [loading, setLoading] = useState(true);
const [isSkeleton, setIsSkeleton] = useState(false);
useEffect(() => {
requestServer(`${CONFIRM_MACHINARY_OFFICE_DETAILS}/${rowId}`, 'get')
.then((response) => {
const booleanData = Array.from({length: response.data.data.attachment_files.length}, () => false);
setAccordionStates(booleanData);
setDetailsData(response.data)
})
.catch(() => {
}).finally(() => {
setLoading(false);
});
}, []);
const handleAccordionChange = (index) => {
const newAccordionStates = accordionStates.map((state, i) => i === index ? !state : false);
setAccordionStates(newAccordionStates);
if (!newAccordionStates[index]) {
handleSizeChangeClick('sm');
setHasImageShown(false);
setIsSkeleton(false)
} else {
handleSizeChangeClick('xl');
setHasImageShown(true);
setImageLink(detailsList.data.attachment_files[index])
setIsSkeleton(true)
}
};
const validationSchema = Yup.object().shape({
proposed_amount: Yup.mixed()
.test(
"is-number",
`${t("ConfirmDialog.proposed_amount_number")}`,
(value) => !isNaN(value)
)
.test("max-amount", `${t("MachinaryOffice.max_amount", {value: parseInt(vehicle_amount[vehicle_type]).toLocaleString('en')})}`,
(value) => value <= vehicle_amount[vehicle_type])
.test("positive", `${t("ConfirmDialog.proposed_amount_positive")}`, (value) => value >= 0)
.required(t("ConfirmDialog.proposed_amount_error")),
sakht_period: Yup.mixed()
.test("is-number", `${t("ConfirmDialog.sakht_period_number")}`,
(value) => !isNaN(value))
.test("positive", `${t("ConfirmDialog.sakht_period_positive")}`, (value) => value > 0)
.required(t("ConfirmDialog.sakht_period_error")),
tanafos_period: Yup.mixed()
.test("is-number", `${t("ConfirmDialog.tanafos_period_number")}`,
(value) => !isNaN(value))
.test("positive", `${t("ConfirmDialog.tanafos_period_positive")}`, (value) => value > 0)
.required(t("ConfirmDialog.tanafos_period_error")),
confirm_img: Yup.mixed()
.required(t("MachinaryOffice.upload_file_required"))
.test('fileSize', `${t("MachinaryOffice.upload_file_unit")}`, (value) => {
return value.size <= 2 * 1024 * 1024;
})
.test('fileType', `${t("MachinaryOffice.upload_file_format")}`, (value) => {
const allowedTypes = ['image/jpg', 'image/jpeg', 'image/png', 'application/pdf'];
return allowedTypes.includes(value.type);
})
});
const formik = useFormik({
initialValues: {
description: "",
proposed_amount: "",
sakht_period: "",
tanafos_period: "",
confirm_img: null
}, validationSchema,
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
formData.append("proposed_amount", values.proposed_amount);
formData.append("sakht_period", values.sakht_period);
formData.append("tanafos_period", values.tanafos_period);
if (values.description != "") formData.append("expert_description", values.description);
if (values.confirm_img != null) {
const attachments = [
{
title: "فایل ضمیمه کارتابل قیمت گذاری",
file: values.confirm_img
}
];
attachments.forEach((attachment, index) => {
formData.append(`attachment[${index}][title]`, attachment.title);
formData.append(`attachment[${index}][file]`, attachment.file);
});
}
requestServer(`${CONFIRM_MACHINARY_OFFICE}/${rowId}`, 'post', {
data: formData,
notification: true
}).then((response) => {
setOpenConfirmDialog(false)
mutate()
update_notification()
}).catch(() => {
}).finally(() => {
setSubmitting(false);
});
},
});
const handleDescriptionChange = (event) => {
formik.setFieldValue("description", event.target.value)
};
const handleUploadChange = (event) => {
const uploadedFile = event.target?.files?.[0];
if (uploadedFile) {
const fileType = event.target?.files?.[0].type;
const fileName = event.target?.files?.[0].name;
setSelectedImage(URL.createObjectURL(uploadedFile));
setfileType(fileType);
setfileName(fileName);
formik.setFieldValue("confirm_img", uploadedFile).then(() => {
formik.setFieldTouched("confirm_img", true);
})
setShowAddIcon(false);
}
};
const handleAmountChange = (event) => {
if (!isNaN(event.target.value)) {
formik.setFieldValue("proposed_amount", event.target.value)
} else {
formik.setFieldValue("proposed_amount", formik.values.proposed_amount)
}
};
const renderCustomAccordions = () => {
if (detailsList && detailsList.data && detailsList.data.attachment_files) {
return detailsList.data.attachment_files.map((file, index) => (
<CustomAccordion
key={index}
title={`${file.title}`}
hasOpened={accordionStates[index]}
hasAccordionOpened={null}
handleAccordionChange={() => handleAccordionChange(index)}
accordionIndex={index}
downloadFile={file.attachment}
/>
));
}
return null;
};
return (
<>
<DialogContent>
<Grid container spacing={2}>
<Grid item xs={hasImageShown ? 6 : 12}>
{loading ? <LinearProgress/> : renderCustomAccordions()}
<Stack spacing={2}>
<Stack>
<TextField
name="description"
multiline
rows={8}
label={<>
<span>{t("ConfirmDialog.description")}</span><small>{t("ConfirmDialog.optional")}</small></>}
value={formik.values.description}
onChange={handleDescriptionChange}
fullWidth
variant="outlined"
sx={{mt: 1}}
/>
</Stack>
<Stack>
<PriceField
name="proposed_amount"
label={<>
<span>{t("ConfirmDialog.proposed_amount")}</span><small>{t("ConfirmDialog.unit")}</small></>}
type="text"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.proposed_amount}
onChange={handleAmountChange}
onBlur={formik.handleBlur("proposed_amount")}
error={
formik.touched.proposed_amount &&
Boolean(formik.errors.proposed_amount)
}
helperText={
formik.touched.proposed_amount && formik.errors.proposed_amount
}
sx={{mt: 1}}
fullWidth
/>
</Stack>
<Stack>
<SelectBox
name="sakht_period"
label={t("ConfirmDialog.sakht_period")}
size="small"
value={formik.values.sakht_period}
selectType="sakht_period"
selectors={[
{
id: 1,
value: "30",
name: "1 ماه - 30 روز"
},
{
id: 2,
value: "60",
name: "2 ماه - 60 روز"
},
{
id: 3,
value: "90",
name: "3 ماه - 90 روز"
},
{
id: 4,
value: "120",
name: "4 ماه - 120 روز"
},
{
id: 5,
value: "150",
name: "5 ماه - 150 روز"
},
{
id: 6,
value: "180",
name: "6 ماه - 180 روز"
}
]}
schema={{value: 'value', name: 'name'}}
select={formik.values.sakht_period}
handleChange={(event) => {
formik.setFieldValue('sakht_period', event.target.value)
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.sakht_period && Boolean(formik.errors.sakht_period)}
helperText={formik.touched.sakht_period && formik.errors.sakht_period}
onBlur={formik.handleBlur("sakht_period")}
/>
</Stack>
<Stack>
<SelectBox
name="tanafos_period"
label={t("ConfirmDialog.tanafos_period")}
size="small"
value={formik.values.tanafos_period}
selectType="tanafos_period"
selectors={[
{
id: 1,
value: "1",
name: "1 ماه"
},
{
id: 2,
value: "2",
name: "2 ماه"
},
{
id: 3,
value: "3",
name: "3 ماه"
},
{
id: 4,
value: "4",
name: "4 ماه"
}
]}
schema={{value: 'value', name: 'name'}}
select={formik.values.tanafos_period}
handleChange={(event) => {
formik.setFieldValue('tanafos_period', event.target.value)
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.tanafos_period && Boolean(formik.errors.tanafos_period)}
helperText={formik.touched.tanafos_period && formik.errors.tanafos_period}
onBlur={formik.handleBlur("tanafos_period")}
/>
</Stack>
<Stack>
<Typography>{t("MachinaryOffice.upload_file")}</Typography>
<UploadSystem
selectedImage={selectedImage}
handleUploadChange={handleUploadChange} // Pass the updated function directly
setselectedImage={setSelectedImage}
setFieldValue={formik.setFieldValue} // Remove props.setFieldValue, use formik.setFieldValue
fieldname="confirm_img"
fileType={fileType}
fileName={fileName}
imageAlt={t("app_name")}
imageSize={[250, 150]}
onBlur={formik.handleBlur("confirm_img")}
error={
formik.touched.confirm_img &&
Boolean(formik.errors.confirm_img)
}
setShowAddIcon={setShowAddIcon}
showAddIcon={showAddIcon}
/>
<FormHelperText
error={Boolean(formik.errors.confirm_img)}
>
{formik.touched.confirm_img && formik.errors.confirm_img}
</FormHelperText>
</Stack>
</Stack>
</Grid>
<Grid item xs={6}>
<Stack sx={{
display: hasImageShown ? 'flex' : 'none',
alignItems: 'center',
gap: 0.5,
justifyContent: 'center'
}}>
<ImageContent imageLink={imageLink} isSkeleton={isSkeleton} setIsSkeleton={setIsSkeleton}/>
</Stack>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenConfirmDialog(false)} variant="outlined" color="secondary"
disabled={formik.isSubmitting} autoFocus>
{t("ConfirmDialog.button-cancel")}
</Button>
<Button onClick={formik.handleSubmit} variant="contained" color="primary"
disabled={formik.isSubmitting || !formik.dirty || !formik.isValid}>
{t("ConfirmDialog.button-confirm")}
</Button>
</DialogActions>
</>
)
}
export default ConfirmContent