Feature/refahi register

This commit is contained in:
2025-02-05 11:50:43 +00:00
committed by AmirHossein Mahmoodi
parent 3bcedb43a2
commit 477c444340
38 changed files with 5407 additions and 232 deletions

View File

@@ -1,6 +1,8 @@
import { CenterLayout, FullPageLayout, NextLinkComposed, useUser } from "@witel/webapp-builder";
import { Button, Typography } from "@mui/material";
import { Button, Card, CardActions, CardContent, Stack, Typography } from "@mui/material";
import { useTranslations } from "next-intl";
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
const FirstComponent = () => {
const { user } = useUser();
@@ -9,23 +11,86 @@ const FirstComponent = () => {
<FullPageLayout>
<CenterLayout spacing={2}>
{user.permissions.includes("can_request_navgan_loan") ? (
<>
<Typography>{t("Dashboard.go_to_add_request_loan")}</Typography>
<Button
component={NextLinkComposed}
to={{ pathname: "/dashboard/navgan/add-request-loan" }}
variant={"contained"}
size={"large"}
<Stack direction={"row"} spacing={2}>
<Card
sx={{
minWidth: 345,
boxShadow: 3,
transition: "transform 0.3s ease-in-out",
"&:hover": { transform: "scale(1.05)" },
}}
>
{t("LoanRequest.loan_request_page")}
</Button>
</>
<CardContent
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<DirectionsCarIcon sx={{ fontSize: 50, color: "primary.main" }} />
<Typography variant="h6" gutterBottom>
{t("Dashboard.request_navgan_loan")}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("Dashboard.navgan_loan_description")}
</Typography>
</CardContent>
<CardActions>
<Button
component={NextLinkComposed}
to={{ pathname: "/dashboard/navgan/add-request-loan" }}
variant="contained"
size="large"
fullWidth
>
{t("Dashboard.navgan_loan_request_page")}
</Button>
</CardActions>
</Card>
<Card
sx={{
minWidth: 345,
boxShadow: 3,
transition: "transform 0.3s ease-in-out",
"&:hover": { transform: "scale(1.05)" },
}}
>
<CardContent
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<VolunteerActivismIcon sx={{ fontSize: 50, color: "secondary.main" }} />
<Typography variant="h6" gutterBottom>
{t("Dashboard.request_refahi_loan")}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("Dashboard.refahi_loan_description")}
</Typography>
</CardContent>
<CardActions>
<Button
component={NextLinkComposed}
to={{ pathname: "/dashboard/refahi/add-request-loan" }}
variant="contained"
size="large"
fullWidth
>
{t("Dashboard.refahi_loan_request_page")}
</Button>
</CardActions>
</Card>
</Stack>
) : (
<>
<Typography>{t("Dashboard.go_to_followUp-loan")}</Typography>
<Button
component={NextLinkComposed}
to={{ pathname: "/dashboard/navgan/followUp-loan" }}
to={{ pathname: "/dashboard/followUp-loan" }}
variant={"contained"}
size={"large"}
>

View File

@@ -0,0 +1,137 @@
import { Box, Chip, Divider, Grid, Skeleton, Stack, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import { SHOW_LOAN_REQUEST_NAVGAN } from "@/core/data/apiRoutes";
import RequestCard from "@/components/dashboard/followUp-loan/RequestCard";
import { FullPageLayout, useRequest } from "@witel/webapp-builder";
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";
import { useTranslations } from "next-intl";
const LoanFollowUpComponent = () => {
const t = useTranslations();
const requestServer = useRequest({ notification: false });
const [isLoadingNavgan, setIsLoadingNavgan] = useState(false);
const [isLoadingRefahi, setIsLoadingRefahi] = useState(false);
const [navganFollowUpList, setNavganFollowUpList] = useState([]);
const [refahiFollowUpList, setRefahiFollowUpList] = useState([]);
useEffect(() => {
setIsLoadingNavgan(true);
requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", { auth: true })
.then(({ data }) => {
setNavganFollowUpList(data.data);
setIsLoadingNavgan(false);
})
.catch(() => setIsLoadingNavgan(false));
setIsLoadingRefahi(true);
requestServer("SHOW_LOAN_REQUEST_NAVGAN", "get", { auth: true })
.then(({ data }) => {
setRefahiFollowUpList(data.data);
setIsLoadingRefahi(false);
})
.catch(() => setIsLoadingRefahi(false));
}, []);
return (
<FullPageLayout>
<Grid container columnSpacing={2} rowSpacing={2} sx={{ padding: "24px", justifyContent: "center" }}>
{isLoadingNavgan ? (
<Grid direction="row" container spacing={4} sx={{ justifyContent: "center", alignItems: "center" }}>
{[...Array(3)].map((_, index) => (
<Grid item>
<Skeleton
key={index}
variant="rectangular"
width={450}
height={150}
sx={{ borderRadius: 2 }}
/>
</Grid>
))}
</Grid>
) : (
navganFollowUpList.length > 0 && (
<>
<Stack
direction="row"
sx={{ mb: 4, width: "100%" }}
justifyContent="center"
alignItems="center"
>
<Divider sx={{ flex: 1, mx: 2 }} />
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<DirectionsCarIcon />}
label={
<Typography variant="h6" sx={{ fontWeight: 600 }}>
{t("LoanFollowUp.loan_follow_up_navgan")}
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
</Stack>
<Grid container spacing={2} sx={{ justifyContent: "center" }}>
{navganFollowUpList.map((item) => (
<RequestCard item={item} key={item.id} />
))}
</Grid>
</>
)
)}
{isLoadingRefahi ? (
<Grid
direction="row"
container
spacing={4}
sx={{ justifyContent: "center", alignItems: "center", my: 4 }}
>
{[...Array(3)].map((_, index) => (
<Grid item>
<Skeleton
key={index}
variant="rectangular"
width={450}
height={150}
sx={{ borderRadius: 2 }}
/>
</Grid>
))}
</Grid>
) : (
refahiFollowUpList.length > 0 && (
<>
<Stack
direction="row"
sx={{ my: 4, width: "100%" }}
justifyContent="center"
alignItems="center"
>
<Divider sx={{ flex: 1, mx: 2 }} />
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<VolunteerActivismIcon />}
label={
<Typography variant="h6" sx={{ fontWeight: 600 }}>
{t("LoanFollowUp.loan_follow_up_refahi")}
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
</Stack>
<Grid container spacing={2} sx={{ justifyContent: "center" }}>
{refahiFollowUpList.map((item) => (
<RequestCard item={item} key={item.id} />
))}
</Grid>
</>
)
)}
</Grid>
</FullPageLayout>
);
};
export default LoanFollowUpComponent;

View File

@@ -28,7 +28,7 @@ const AddFormComponent = () => {
</Typography>
<DoneIcon color={"success"} />
</Stack>
<Button variant={"contained"} component={NextLinkComposed} to={"/dashboard/navgan/followUp-loan"}>
<Button variant={"contained"} component={NextLinkComposed} to={"/dashboard/followUp-loan"}>
{t("LoanRequest.back_to_dashboard")}
</Button>
</CenterLayout>

View File

@@ -121,21 +121,21 @@ const CheckRules = ({ setRulesChecked }) => {
},
];
const renderRuleContent = (content) => {
const renderRuleContent = (content, index) => {
if (typeof content === "string") {
return (
<Box key={content.index} component="li" sx={{ mb: 0.5 }}>
<Box key={index} component="li" sx={{ mb: 0.5 }}>
<Typography variant="body2">{content}</Typography>
</Box>
);
}
return (
<Box key={content.index} component="li" sx={{ mb: 0.5 }}>
<Box key={index} component="li" sx={{ mb: 0.5 }}>
<Typography variant="body2" sx={{ mb: 0.5 }}>
{content.title}
</Typography>
<Box component="ul" sx={{ listStyleType: "circle", paddingLeft: "1.5rem" }}>
{content.subtitles.map((sub, index) => renderRuleContent(sub, index))}
{content.subtitles.map((sub, subIndex) => renderRuleContent(sub, subIndex))}
</Box>
</Box>
);

View File

@@ -78,7 +78,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => {
plate_part3: "",
plate_part4: "",
address: "",
company_date: "",
company_register_date: "",
education_id: "",
occupation_id: "",
checkedBox: false,
@@ -114,7 +114,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => {
occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")),
education_id: Yup.string().required(t("LoanRequest.error_message_education_id")),
address: Yup.string().required(t("LoanRequest.error_message_address")),
company_date: Yup.string().required(t("LoanRequest.error_message_date_of_birth")),
company_register_date: Yup.string().required(t("LoanRequest.error_message_date_of_birth")),
company_postal_code: Yup.mixed()
.test("max", `${t("LoanRequest.company_postal_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_company_postal_code")),
@@ -227,7 +227,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => {
plate_part3: values.plate_part3,
plate_part4: values.plate_part4,
address: values.address,
company_register_date: values.company_date.locale("en").format("YYYY-MM-DD"),
company_register_date: values.company_register_date.locale("en").format("YYYY-MM-DD"),
birthday: values.birthday.locale("en").format("YYYY-MM-DD"),
education_id: values.education_id,
occupation_id: values.occupation_id,
@@ -243,7 +243,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => {
data: _data,
})
.then(() => {
router.replace("/dashboard/navgan/followUp-loan");
router.replace("/dashboard/followUp-loan");
getUser((data) => {
changeUser(data);
});
@@ -453,9 +453,9 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => {
<Grid item xs={12} sm={4}>
<LegalPersonDatePicker
formik={formik}
error={formik.touched.company_date && Boolean(formik.errors.company_date)}
helperText={formik.touched.company_date && formik.errors.company_date}
onBlur={formik.handleBlur("company_date")}
error={formik.touched.company_register_date && Boolean(formik.errors.company_register_date)}
helperText={formik.touched.company_register_date && formik.errors.company_register_date}
onBlur={formik.handleBlur("company_register_date")}
/>
</Grid>
</Grid>

View File

@@ -211,7 +211,7 @@ const RealPersonForm = ({ setFinishLoanRequest }) => {
data: _data,
})
.then(() => {
router.replace("/dashboard/navgan/followUp-loan");
router.replace("/dashboard/followUp-loan");
getUser((data) => {
changeUser(data);
});

View File

@@ -1,54 +0,0 @@
import { Grid } from "@mui/material";
import { useEffect, useState } from "react";
import { SHOW_LOAN_REQUEST_NAVGAN } from "@/core/data/apiRoutes";
import RequestCard from "@/components/dashboard/navgan/followUp-loan/RequestCard";
import { FullPageLayout, LoadingHardPage, useRequest } from "@witel/webapp-builder";
import sidebarMenu from "@/core/data/sidebarMenu";
import BookmarkAddedIcon from "@mui/icons-material/BookmarkAdded";
const LoanFollowUpComponent = () => {
const requestServer = useRequest();
const [isLoading, setIsLoading] = useState(false);
const [requestsList, setRequestsList] = useState([]);
useEffect(() => {
setIsLoading(true);
requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", {
auth: true,
pending: false,
success: { notification: { show: false } },
})
.then(function ({ data }) {
const items = data.data;
setRequestsList(items);
setIsLoading(false);
})
.catch(function (error) {});
}, []);
return (
<FullPageLayout>
<Grid
container
columnSpacing={2}
rowSpacing={2}
sx={{ alignItems: "start", justifyContent: "center", padding: "24px" }}
>
<LoadingHardPage
loading={isLoading}
width={100}
height={100}
sx={{ position: "absolute", bgcolor: "#fffc" }}
icon={<BookmarkAddedIcon sx={{ width: "inherit", height: "inherit" }} />}
>
<Grid container sx={{ justifyContent: "center" }} spacing={2}>
{requestsList.map((item) => (
<RequestCard item={item} key={item.id} />
))}
</Grid>
</LoadingHardPage>
</Grid>
</FullPageLayout>
);
};
export default LoanFollowUpComponent;

View File

@@ -49,7 +49,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => {
user_committed_employment: LoanDetails.user_committed_employment || "",
applicant_payment: LoanDetails.person_share || "",
register_number: LoanDetails.register_number || "",
company_date: LoanDetails.company_register_date ? moment(LoanDetails.company_register_date) : "",
company_register_date: LoanDetails.company_register_date ? moment(LoanDetails.company_register_date) : "",
birthday: LoanDetails.birthday ? moment(LoanDetails.birthday) : "",
navgan_id: LoanDetails.navgan_id || "",
province_id: LoanDetails.province_id || "",
@@ -104,7 +104,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => {
})
.required(t("ShowLoan.error_message_tel_number")),
occupation_id: Yup.string().required(t("ShowLoan.error_message_occupation_id")),
company_date: Yup.string().required(t("ShowLoan.error_message_company_date")),
company_register_date: Yup.string().required(t("ShowLoan.error_message_company_date")),
company_name: Yup.string().required(t("ShowLoan.error_message_company_name")),
register_number: Yup.string().required(t("ShowLoan.error_message_register_number")),
boss_first_name: Yup.string().required(t("ShowLoan.error_message_boss_first_name")),
@@ -197,7 +197,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => {
formData.append("occupation_id", values.occupation_id);
formData.append("address", values.address);
formData.append("company_name", values.company_name);
formData.append("company_register_date", values.company_date.locale("en").format("YYYY-MM-DD"));
formData.append("company_register_date", values.company_register_date.locale("en").format("YYYY-MM-DD"));
formData.append("register_number", values.register_number);
await requestServer(UPDATE_LOAN + LoanId, "post", {
@@ -206,7 +206,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => {
data: formData,
})
.then(() => {
router.push("/dashboard/navgan/followUp-loan");
router.push("/dashboard/followUp-loan");
})
.catch(() => {})
.finally(() => {
@@ -372,9 +372,9 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => {
<LegalPersonDatePicker
formik={formik}
disabled={LoanDetails.state_id !== 17}
error={formik.touched.company_date && Boolean(formik.errors.company_date)}
helperText={formik.touched.company_date && formik.errors.company_date}
onBlur={formik.handleBlur("company_date")}
error={formik.touched.company_register_date && Boolean(formik.errors.company_register_date)}
helperText={formik.touched.company_register_date && formik.errors.company_register_date}
onBlur={formik.handleBlur("company_register_date")}
/>
</Grid>
</Grid>

View File

@@ -168,7 +168,7 @@ const UpdateFormReal = ({ LoanDetails, LoanId }) => {
data: formData,
})
.then(() => {
router.push("/dashboard/navgan/followUp-loan");
router.push("/dashboard/followUp-loan");
})
.catch(() => {})
.finally(() => {

View File

@@ -0,0 +1,86 @@
import { Button, Card, CardActions, CardContent, Stack, Typography } from "@mui/material";
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";
import BuildIcon from "@mui/icons-material/Build";
import MapsHomeWorkIcon from "@mui/icons-material/MapsHomeWork";
import { useTranslations } from "next-intl";
import { CenterLayout, FullPageLayout } from "@witel/webapp-builder";
const RefahiLoanType = ({ setRefahiLoanType }) => {
const t = useTranslations();
return (
<FullPageLayout>
<CenterLayout spacing={2}>
<Stack direction={"row"} spacing={2}>
<Card
sx={{
minWidth: 345,
boxShadow: 3,
transition: "transform 0.3s ease-in-out",
"&:hover": { transform: "scale(1.05)" },
}}
>
<CardContent
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<BuildIcon sx={{ fontSize: 50, color: "primary.main" }} />
<Typography variant="h6" gutterBottom>
{t("RefahiLoanRequest.restore_facilities")}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("RefahiLoanRequest.restore_facilities_description")}
</Typography>
</CardContent>
<CardActions>
<Button onClick={() => setRefahiLoanType(0)} variant="contained" size="large" fullWidth>
{t("RefahiLoanRequest.restore_facilities_request")}
</Button>
</CardActions>
</Card>
<Card
sx={{
minWidth: 345,
boxShadow: 3,
transition: "transform 0.3s ease-in-out",
"&:hover": { transform: "scale(1.05)" },
}}
>
<CardContent
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<MapsHomeWorkIcon sx={{ fontSize: 50, color: "secondary.main" }} />
<Typography variant="h6" gutterBottom>
{t("RefahiLoanRequest.building_facilities")}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("RefahiLoanRequest.building_facilities_description")}
</Typography>
</CardContent>
<CardActions>
<Button
onClick={() => setRefahiLoanType(1)}
variant="contained"
size="large"
color={"secondary"}
fullWidth
>
{t("RefahiLoanRequest.building_facilities_request")}
</Button>
</CardActions>
</Card>
</Stack>
</CenterLayout>
</FullPageLayout>
);
};
export default RefahiLoanType;

View File

@@ -0,0 +1,710 @@
import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material";
import SelectBox from "@/core/components/SelectBox";
import * as React from "react";
import useActivityType from "@/lib/app/hooks/useActivityType";
import { useTranslations } from "next-intl";
import MuiDatePicker from "@/core/components/MuiDatePicker";
import UseEducations from "@/lib/app/hooks/useEducations";
import useOccupations from "@/lib/app/hooks/useOccupations";
import { useFormik } from "formik";
import * as Yup from "yup";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { useEffect } from "react";
import useCities from "@/lib/app/hooks/useCities";
import LegalPersonDatePicker from "@/core/components/LegalPersonDatePicker";
const BuildLegalPersonalInfo = ({
state,
handleNext,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
const { activityType, isLoadingActivityType, errorActivityType } = useActivityType();
const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations();
const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations();
const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities();
const initialValues = {
person_type: state.person_type,
father_name: state.father_name,
province_id: state.province_id,
city_id: state.city_id,
telephone_number: state.telephone_number,
activity_type_id: state.activity_type_id,
refahi_type: state.refahi_type,
gender: state.gender,
welfare_complex_degree: state.welfare_complex_degree,
first_name: state.first_name,
last_name: state.last_name,
education_id: state.education_id,
occupation_id: state.occupation_id,
national_id: state.national_id,
national_serial_number: state.national_serial_number,
national_card_tracking_code: state.national_card_tracking_code,
national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code,
postal_code: state.postal_code,
address: state.address,
birthday: state.birthday,
company_register_date: state.company_register_date,
shenase_meli: state.shenase_meli,
register_number: state.register_number,
company_name: state.company_name,
};
const validationSchema = Yup.object().shape({
province_id: Yup.string().required(t("LoanRequest.error_message_province_id")),
city_id: Yup.string().required(t("LoanRequest.error_message_city_id")),
telephone_number: Yup.mixed()
.test("max", `${t("LoanRequest.company_tel_number_max")}`, (value) => {
const stringValue = String(value);
return stringValue.length === 11;
})
.required(t("LoanRequest.error_message_company_tel_number")),
activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")),
gender: Yup.string().required(t("LoanRequest.error_message_boss_gender")),
welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")),
first_name: Yup.string().required(t("LoanRequest.error_message_boss_first_name")),
last_name: Yup.string().required(t("LoanRequest.error_message_boss_last_name")),
occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")),
education_id: Yup.string().required(t("LoanRequest.error_message_education_id")),
national_id: Yup.mixed()
.test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value))
.test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0)
.test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_boss_national_id")),
national_serial_number: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_serial_number"
? schema
.test(
"max",
`${t("LoanRequest.national_serial_number_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_boss_shenasname_serial"))
: schema;
}
),
national_card_tracking_code: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_card_tracking_code"
? schema
.test(
"max",
`${t("LoanRequest.national_tracking_code_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_boss_national_card_tracking_code"))
: schema;
}
),
address: Yup.string().required(t("LoanRequest.error_message_address")),
birthday: Yup.string().required(t("LoanRequest.error_message_boss_date_of_birth")),
postal_code: Yup.mixed()
.test("max", `${t("LoanRequest.company_postal_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_company_postal_code")),
father_name: Yup.string().required(t("LoanRequest.error_message_boss_father_name")),
shenase_meli: Yup.mixed().when("person_type", ([person_type], schema) => {
return person_type === "legal"
? schema
.test("is-number", `${t("LoanRequest.national_number_number")}`, (value) => !isNaN(value))
.test("positive", `${t("LoanRequest.national_number_positive")}`, (value) => value >= 0)
.test(
"max",
`${t("LoanRequest.national_number_max")}`,
(value) => value && value.toString().length === 11
)
.required(t("LoanRequest.error_message_national_number"))
: schema;
}),
company_register_date: Yup.string().required(t("LoanRequest.error_message_company_date")),
register_number: Yup.string().required(t("LoanRequest.error_message_register_number")),
company_name: Yup.string().required(t("LoanRequest.error_message_company_name")),
});
const handleSubmit = async (values) => {
dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values });
handleNext();
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
useEffect(() => {
if (formik.values.province_id === "") return;
setProvinceID(formik.values.province_id);
}, [formik.values.province_id]);
return (
<>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="refahi_type"
variant="outlined"
size="small"
value={"ساخت مجتمع رفاهی"}
label={t("LoanRequest.text_field_navgan_plan_id")}
fullWidth
disabled
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="activity_type_id"
label={t("LoanRequest.text_field_activity_type")}
size="small"
selectType="activity_type_id"
isLoading={isLoadingActivityType}
errorEcured={errorActivityType}
selectors={activityType}
schema={{ value: "value", name: "name" }}
select={formik.values.activity_type_id}
value={formik.values.activity_type_id}
handleChange={(event) => {
formik.setFieldValue("activity_type_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)}
helperText={formik.touched.activity_type_id && formik.errors.activity_type_id}
onBlur={formik.handleBlur("activity_type_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="shenase_meli"
variant="outlined"
size="small"
value={formik.values.shenase_meli}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "shenase_meli",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_national_number")}
placeholder={t("LoanRequest.text_field_enter_your_national_number")}
onBlur={formik.handleBlur("shenase_meli")}
error={formik.touched.shenase_meli && Boolean(formik.errors.shenase_meli)}
helperText={formik.touched.shenase_meli && formik.errors.shenase_meli}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="company_name"
variant="outlined"
size="small"
value={formik.values.company_name}
label={t("LoanRequest.text_field_company_name")}
placeholder={t("LoanRequest.text_field_enter_your_company_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("company_name")}
error={formik.touched.company_name && Boolean(formik.errors.company_name)}
helperText={formik.touched.company_name && formik.errors.company_name}
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="register_number"
variant="outlined"
size="small"
value={formik.values.register_number}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "register_number",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_register_number")}
placeholder={t("LoanRequest.text_field_enter_your_register_number")}
onBlur={formik.handleBlur("register_number")}
error={formik.touched.register_number && Boolean(formik.errors.register_number)}
helperText={formik.touched.register_number && formik.errors.register_number}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<ToggleButtonGroup
color="primary"
fullWidth
size={"small"}
value={formik.values.national_serial_number_or_tracking_code}
exclusive
onChange={(e, value) => {
if (value === null) return;
formik.handleChange({
target: {
name: "national_serial_number_or_tracking_code",
value: value,
},
});
}}
>
<ToggleButton value="national_serial_number">
{t("LoanRequest.text_field_shenasname_serial")}
</ToggleButton>
<ToggleButton value="national_card_tracking_code">
{t("LoanRequest.text_field_national_trackin_code")}
</ToggleButton>
</ToggleButtonGroup>
</Grid>
{formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_serial_number"
variant="outlined"
size="small"
value={formik.values.national_serial_number}
label={t("LoanRequest.text_field_boss_national_serial_number")}
placeholder={t("LoanRequest.text_field_enter_your_boss_national_serial_number")}
fullWidth
onChange={(e) => {
const inputValue = e.target.value;
const regex = /^[A-Za-z0-9]*$/;
if (regex.test(inputValue)) {
formik.setFieldValue("national_serial_number", inputValue);
}
}}
onBlur={formik.handleBlur("national_serial_number")}
error={
formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number)
}
helperText={formik.touched.national_serial_number && formik.errors.national_serial_number}
/>
</Grid>
) : (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_card_tracking_code"
variant="outlined"
size="small"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
value={formik.values.national_card_tracking_code}
label={t("LoanRequest.text_field_boss_national_card_tracking_code")}
placeholder={t("LoanRequest.text_field_enter_your_boss_national_card_tracking_code")}
fullWidth
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_card_tracking_code",
value: inputValue,
},
});
}}
onBlur={formik.handleBlur("national_card_tracking_code")}
error={
formik.touched.national_card_tracking_code &&
Boolean(formik.errors.national_card_tracking_code)
}
helperText={
formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code
}
/>
</Grid>
)}
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_id"
variant="outlined"
size="small"
value={formik.values.national_id}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_id",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_boss_national_code")}
placeholder={t("LoanRequest.text_field_enter_your_boss_national_code")}
onBlur={formik.handleBlur("national_id")}
error={formik.touched.national_id && Boolean(formik.errors.national_id)}
helperText={formik.touched.national_id && formik.errors.national_id}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="first_name"
variant="outlined"
size="small"
value={formik.values.first_name}
label={t("LoanRequest.text_field_boss_first_name")}
placeholder={t("LoanRequest.text_field_enter_your_boss_first_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("first_name")}
error={formik.touched.first_name && Boolean(formik.errors.first_name)}
helperText={formik.touched.first_name && formik.errors.first_name}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="last_name"
variant="outlined"
size="small"
value={formik.values.last_name}
label={t("LoanRequest.text_field_boss_last_name")}
placeholder={t("LoanRequest.text_field_enter_your_boss_last_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("last_name")}
error={formik.touched.last_name && Boolean(formik.errors.last_name)}
helperText={formik.touched.last_name && formik.errors.last_name}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<SelectBox
name="province_id"
label={t("LoanRequest.text_field_province_id")}
size="small"
selectType="province_id"
isLoading={isLoadingProvinceList}
errorEcured={errorProvinceList}
selectors={provinceList}
schema={{ value: "value", name: "name" }}
select={formik.values.province_id}
value={formik.values.province_id}
handleChange={(event) => {
formik.setFieldValue("province_id", event.target.value);
formik.setFieldTouched("city_id", false, false);
formik.setFieldValue("city_id", "");
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.province_id && Boolean(formik.errors.province_id)}
helperText={formik.touched.province_id && formik.errors.province_id}
onBlur={formik.handleBlur("province_id")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="city_id"
label={
isLoadingCityList
? `${t("LoanRequest.enter_province")}`
: cityList.length === 0
? `${t("LoanRequest.cityList_empty")}`
: cityTextField
}
size="small"
selectType="city_id"
schema={{ value: "value", name: "name" }}
disabled={cityList.length === 0}
isLoading={isLoadingCityList}
selectors={cityList}
select={formik.values.city_id}
value={formik.values.city_id}
handleChange={(event) => formik.setFieldValue("city_id", event.target.value)}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.city_id && Boolean(formik.errors.city_id)}
helperText={formik.touched.city_id && formik.errors.city_id}
onBlur={formik.handleBlur("city_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="father_name"
variant="outlined"
value={formik.values.father_name}
onChange={formik.handleChange}
size="small"
label={t("LoanRequest.text_field_boss_father_name")}
placeholder={t("LoanRequest.text_field_enter_your_boss_father_name")}
onBlur={formik.handleBlur("father_name")}
error={formik.touched.father_name && Boolean(formik.errors.father_name)}
helperText={formik.touched.father_name && formik.errors.father_name}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="gender"
label={t("LoanRequest.text_field_boss_gender")}
size="small"
value={formik.values.gender}
selectType="gender"
selectors={[
{
id: 1,
value: 1,
name: "زن",
},
{
id: 2,
value: 0,
name: "مرد",
},
]}
schema={{ value: "value", name: "name" }}
select={formik.values.gender}
handleChange={(event) => {
formik.setFieldValue("gender", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.gender && Boolean(formik.errors.gender)}
helperText={formik.touched.gender && formik.errors.gender}
onBlur={formik.handleBlur("gender")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<MuiDatePicker
formik={formik}
error={formik.touched.birthday && Boolean(formik.errors.birthday)}
helperText={formik.touched.birthday && formik.errors.birthday}
onBlur={formik.handleBlur("birthday")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="postal_code"
variant="outlined"
value={formik.values.postal_code}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "postal_code",
value: inputValue,
},
});
}}
size="small"
label={t("LoanRequest.text_field_company_postal_code")}
placeholder={t("LoanRequest.text_field_enter_your_company_postal_code")}
fullWidth
onBlur={formik.handleBlur("postal_code")}
error={formik.touched.postal_code && Boolean(formik.errors.postal_code)}
helperText={formik.touched.postal_code && formik.errors.postal_code}
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="telephone_number"
variant="outlined"
value={formik.values.telephone_number}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
size="small"
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "telephone_number",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_company_tel_number")}
placeholder={t("LoanRequest.text_field_enter_your_company_tel_number")}
fullWidth
onBlur={formik.handleBlur("telephone_number")}
error={formik.touched.telephone_number && Boolean(formik.errors.telephone_number)}
helperText={formik.touched.telephone_number && formik.errors.telephone_number}
/>
</Grid>
<Grid item xs={12} sm={4}>
<LegalPersonDatePicker
formik={formik}
error={formik.touched.company_register_date && Boolean(formik.errors.company_register_date)}
helperText={formik.touched.company_register_date && formik.errors.company_register_date}
onBlur={formik.handleBlur("company_register_date")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<SelectBox
name="education_id"
label={t("LoanRequest.text_field_education_id")}
size="small"
isLoading={isLoadingEducationsList}
errorEcured={errorEducationsList}
selectType="education_id"
selectors={educationsList}
select={formik.values.education_id}
value={formik.values.education_id}
schema={{ value: "id", name: "title" }}
handleChange={(event) => {
formik.setFieldValue("education_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.education_id && Boolean(formik.errors.education_id)}
helperText={formik.touched.education_id && formik.errors.education_id}
onBlur={formik.handleBlur("education_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="occupation_id"
label={t("LoanRequest.text_field_occupation_id")}
size="small"
isLoading={isLoadingOccupationsList}
errorEcured={errorOccupationsList}
selectType="occupation_id"
schema={{ value: "id", name: "title" }}
selectors={occupationsList}
select={formik.values.occupation_id}
value={formik.values.occupation_id}
handleChange={(event) => {
formik.setFieldValue("occupation_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.occupation_id && Boolean(formik.errors.occupation_id)}
helperText={formik.touched.occupation_id && formik.errors.occupation_id}
onBlur={formik.handleBlur("occupation_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="welfare_complex_degree"
label={t("LoanRequest.text_field_degree")}
size="small"
value={formik.values.welfare_complex_degree}
selectType="welfare_complex_degree"
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.welfare_complex_degree}
handleChange={(event) => {
formik.setFieldValue("welfare_complex_degree", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)}
helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree}
onBlur={formik.handleBlur("welfare_complex_degree")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<TextField
multiline
rows={4}
sx={{ width: "100%" }}
name="address"
variant="outlined"
size="small"
label={t("LoanRequest.text_field_address")}
placeholder={t("LoanRequest.text_field_enter_your_address")}
fullWidth
value={formik.values.address}
onChange={formik.handleChange}
onBlur={formik.handleBlur("address")}
error={formik.touched.address && Boolean(formik.errors.address)}
helperText={formik.touched.address && formik.errors.address}
/>
</Grid>
</Grid>
<Stack
sx={{ mb: 5, mx: 2 }}
spacing={2}
direction={"row"}
alignItems={"center"}
justifyContent={"flex-end"}
>
<Button startIcon={<ExitToAppIcon />} variant={"outlined"} size={"large"} color={"primary"} disabled>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<KeyboardDoubleArrowLeftIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={formik.isSubmitting}
>
{t("RefahiLoanRequest.next-button")}
</Button>
</Stack>
</>
);
};
export default BuildLegalPersonalInfo;

View File

@@ -0,0 +1,232 @@
import { Button, Grid, Stack, TextField } from "@mui/material";
import SelectBox from "@/core/components/SelectBox";
import * as React from "react";
import { useTranslations } from "next-intl";
import useLimitedProvince from "@/lib/app/hooks/useLimitedProvince";
import useCities from "@/lib/app/hooks/useCities";
import * as Yup from "yup";
import { useFormik } from "formik";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { useEffect } from "react";
const BuildProjectInfo = ({
state,
handleNext,
handleBack,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const { cityList, setProvinceID, isLoadingCityList } = useCities();
const t = useTranslations();
const initialValues = {
project_province_id: state.project_province_id,
project_city_id: state.project_city_id,
project_axis: state.project_axis,
project_kilometer_marker: state.project_kilometer_marker,
project_direction: state.project_direction,
project_address: state.project_address,
};
const validationSchema = Yup.object().shape({
project_province_id: Yup.string().required(t("LoanRequest.error_message_project_province_id")),
project_city_id: Yup.string().required(t("LoanRequest.error_message_project_city_id")),
project_address: Yup.string().required(t("LoanRequest.error_message_execution_address")),
project_axis: Yup.string().required(t("LoanRequest.error_message_mehvar")),
project_kilometer_marker: Yup.string().required(t("LoanRequest.error_message_kilometer")),
project_direction: Yup.string().required(t("LoanRequest.error_message_samt")),
});
const handleSubmit = async (values) => {
dispatch({ type: "SET_PROJECT_INFO", projectInfo: values });
handleNext();
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
useEffect(() => {
if (formik.values.project_province_id === "") return;
setProvinceID(formik.values.project_province_id);
}, [formik.values.project_province_id]);
return (
<>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<SelectBox
name="project_province_id"
label={t("LoanRequest.text_field_project_province_id")}
size="small"
selectType="project_province_id"
isLoading={isLoadingProvinceList}
errorEcured={errorProvinceList}
selectors={provinceList}
schema={{ value: "value", name: "name" }}
select={formik.values.project_province_id}
value={formik.values.project_province_id}
handleChange={(event) => {
formik.setFieldValue("project_province_id", event.target.value);
formik.setFieldTouched("project_city_id", false, false);
formik.setFieldValue("project_city_id", "");
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.project_province_id && Boolean(formik.errors.project_province_id)}
helperText={formik.touched.project_province_id && formik.errors.project_province_id}
onBlur={formik.handleBlur("project_province_id")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="project_city_id"
label={
isLoadingCityList
? `${t("LoanRequest.enter_project_province_id")}`
: cityList.length === 0
? `${t("LoanRequest.project_cityList_empty")}`
: `${t("LoanRequest.project_city_id")}`
}
size="small"
selectType="project_city_id"
schema={{ value: "value", name: "name" }}
disabled={cityList.length === 0}
isLoading={isLoadingCityList}
selectors={cityList}
select={formik.values.project_city_id}
value={formik.values.project_city_id}
handleChange={(event) => formik.setFieldValue("project_city_id", event.target.value)}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.project_city_id && Boolean(formik.errors.project_city_id)}
helperText={formik.touched.project_city_id && formik.errors.project_city_id}
onBlur={formik.handleBlur("project_city_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="project_axis"
variant="outlined"
size="small"
value={formik.values.project_axis}
onChange={formik.handleChange}
label={t("LoanRequest.text_field_mehvar")}
placeholder={t("LoanRequest.text_field_enter_your_mehvar")}
onBlur={formik.handleBlur("project_axis")}
error={formik.touched.project_axis && Boolean(formik.errors.project_axis)}
helperText={formik.touched.project_axis && formik.errors.project_axis}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="project_kilometer_marker"
variant="outlined"
size="small"
value={formik.values.project_kilometer_marker}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "project_kilometer_marker",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_kilometer")}
placeholder={t("LoanRequest.text_field_enter_your_kilometer")}
onBlur={formik.handleBlur("project_kilometer_marker")}
error={
formik.touched.project_kilometer_marker && Boolean(formik.errors.project_kilometer_marker)
}
helperText={formik.touched.project_kilometer_marker && formik.errors.project_kilometer_marker}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="project_direction"
label={t("LoanRequest.text_field_samt")}
size="small"
value={formik.values.project_direction}
selectType="project_direction"
selectors={[
{
id: 1,
value: 1,
name: "رفت",
},
{
id: 2,
value: 0,
name: "برگشت",
},
]}
schema={{ value: "value", name: "name" }}
select={formik.values.project_direction}
handleChange={(event) => {
formik.setFieldValue("project_direction", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.project_direction && Boolean(formik.errors.project_direction)}
helperText={formik.touched.project_direction && formik.errors.project_direction}
onBlur={formik.handleBlur("project_direction")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<TextField
multiline
rows={4}
sx={{ width: "100%" }}
name="project_address"
variant="outlined"
size="small"
label={t("LoanRequest.text_field_execution_address")}
placeholder={t("LoanRequest.text_field_enter_your_execution_address")}
fullWidth
value={formik.values.project_address}
onChange={formik.handleChange}
onBlur={formik.handleBlur("project_address")}
error={formik.touched.project_address && Boolean(formik.errors.project_address)}
helperText={formik.touched.project_address && formik.errors.project_address}
/>
</Grid>
</Grid>
<Stack
onClick={handleBack}
sx={{ mx: 5 }}
spacing={2}
direction={"row"}
alignItems={"center"}
justifyContent={"flex-end"}
>
<Button startIcon={<ExitToAppIcon />} variant={"outlined"} size={"large"} color={"primary"}>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<KeyboardDoubleArrowLeftIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={formik.isSubmitting}
>
{t("RefahiLoanRequest.next-button")}
</Button>
</Stack>
</>
);
};
export default BuildProjectInfo;

View File

@@ -0,0 +1,605 @@
import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material";
import SelectBox from "@/core/components/SelectBox";
import * as React from "react";
import useActivityType from "@/lib/app/hooks/useActivityType";
import { useTranslations } from "next-intl";
import MuiDatePicker from "@/core/components/MuiDatePicker";
import UseEducations from "@/lib/app/hooks/useEducations";
import useOccupations from "@/lib/app/hooks/useOccupations";
import { useFormik } from "formik";
import * as Yup from "yup";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { useEffect } from "react";
import useCities from "@/lib/app/hooks/useCities";
const BuildRealPersonalInfo = ({
state,
handleNext,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
const { activityType, isLoadingActivityType, errorActivityType } = useActivityType();
const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations();
const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations();
const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities();
const initialValues = {
person_type: state.person_type,
province_id: state.province_id,
city_id: state.city_id,
father_name: state.father_name,
telephone_number: state.telephone_number,
activity_type_id: state.activity_type_id,
refahi_type: state.refahi_type,
gender: state.gender,
welfare_complex_degree: state.welfare_complex_degree,
first_name: state.first_name,
last_name: state.last_name,
education_id: state.education_id,
occupation_id: state.occupation_id,
national_id: state.national_id,
national_serial_number: state.national_serial_number,
national_card_tracking_code: state.national_card_tracking_code,
national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code,
postal_code: state.postal_code,
address: state.address,
birthday: state.birthday,
};
const validationSchema = Yup.object().shape({
province_id: Yup.string().required(t("LoanRequest.error_message_province_id")),
city_id: Yup.string().required(t("LoanRequest.error_message_city_id")),
telephone_number: Yup.mixed()
.test("max", `${t("LoanRequest.tel_number_max")}`, (value) => {
const stringValue = String(value);
return stringValue.length === 11;
})
.required(t("LoanRequest.error_message_tel_number")),
activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")),
gender: Yup.string().required(t("LoanRequest.error_message_gender")),
welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")),
first_name: Yup.string().required(t("LoanRequest.error_message_first_name")),
last_name: Yup.string().required(t("LoanRequest.error_message_last_name")),
occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")),
education_id: Yup.string().required(t("LoanRequest.error_message_education_id")),
national_id: Yup.mixed()
.test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value))
.test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0)
.test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_national_id")),
national_serial_number: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_serial_number"
? schema
.test(
"max",
`${t("LoanRequest.national_serial_number_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_shenasname_serial"))
: schema;
}
),
national_card_tracking_code: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_card_tracking_code"
? schema
.test(
"max",
`${t("LoanRequest.national_tracking_code_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_tracking_code"))
: schema;
}
),
address: Yup.string().required(t("LoanRequest.error_message_address")),
birthday: Yup.string().required(t("LoanRequest.error_message_date_of_birth")),
postal_code: Yup.mixed()
.test("max", `${t("LoanRequest.postal_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_postal_code")),
father_name: Yup.string().required(t("LoanRequest.error_message_father_name")),
});
const handleSubmit = async (values) => {
dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values });
handleNext();
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
useEffect(() => {
if (formik.values.province_id === "") return;
setProvinceID(formik.values.province_id);
}, [formik.values.province_id]);
return (
<>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="refahi_type"
variant="outlined"
size="small"
value={"ساخت مجتمع رفاهی"}
label={t("LoanRequest.text_field_navgan_plan_id")}
fullWidth
disabled
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="activity_type_id"
label={t("LoanRequest.text_field_activity_type")}
size="small"
selectType="activity_type_id"
isLoading={isLoadingActivityType}
errorEcured={errorActivityType}
selectors={activityType}
schema={{ value: "value", name: "name" }}
select={formik.values.activity_type_id}
value={formik.values.activity_type_id}
handleChange={(event) => {
formik.setFieldValue("activity_type_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)}
helperText={formik.touched.activity_type_id && formik.errors.activity_type_id}
onBlur={formik.handleBlur("activity_type_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<ToggleButtonGroup
color="primary"
fullWidth
size={"small"}
value={formik.values.national_serial_number_or_tracking_code}
exclusive
onChange={(e, value) => {
if (value === null) return;
formik.handleChange({
target: {
name: "national_serial_number_or_tracking_code",
value: value,
},
});
}}
>
<ToggleButton value="national_serial_number">
{t("LoanRequest.text_field_shenasname_serial")}
</ToggleButton>
<ToggleButton value="national_card_tracking_code">
{t("LoanRequest.text_field_national_trackin_code")}
</ToggleButton>
</ToggleButtonGroup>
</Grid>
{formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_serial_number"
variant="outlined"
size="small"
value={formik.values.national_serial_number}
label={t("LoanRequest.text_field_shenasname_serial")}
placeholder={t("LoanRequest.text_field_enter_your_shenasname_serial")}
fullWidth
onChange={(e) => {
const inputValue = e.target.value;
const regex = /^[A-Za-z0-9]*$/;
if (regex.test(inputValue)) {
formik.setFieldValue("national_serial_number", inputValue);
}
}}
onBlur={formik.handleBlur("national_serial_number")}
error={
formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number)
}
helperText={formik.touched.national_serial_number && formik.errors.national_serial_number}
/>
</Grid>
) : (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_card_tracking_code"
variant="outlined"
size="small"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
value={formik.values.national_card_tracking_code}
label={t("LoanRequest.text_field_national_trackin_code")}
placeholder={t("LoanRequest.text_field_enter_your_trackin_code")}
fullWidth
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_card_tracking_code",
value: inputValue,
},
});
}}
onBlur={formik.handleBlur("national_card_tracking_code")}
error={
formik.touched.national_card_tracking_code &&
Boolean(formik.errors.national_card_tracking_code)
}
helperText={
formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code
}
/>
</Grid>
)}
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_id"
variant="outlined"
size="small"
value={formik.values.national_id}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_id",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_national_code")}
placeholder={t("LoanRequest.text_field_enter_your_national_code")}
onBlur={formik.handleBlur("national_id")}
error={formik.touched.national_id && Boolean(formik.errors.national_id)}
helperText={formik.touched.national_id && formik.errors.national_id}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="first_name"
variant="outlined"
size="small"
value={formik.values.first_name}
label={t("LoanRequest.text_field_first_name")}
placeholder={t("LoanRequest.text_field_enter_your_first_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("first_name")}
error={formik.touched.first_name && Boolean(formik.errors.first_name)}
helperText={formik.touched.first_name && formik.errors.first_name}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="last_name"
variant="outlined"
size="small"
value={formik.values.last_name}
label={t("LoanRequest.text_field_last_name")}
placeholder={t("LoanRequest.text_field_enter_your_last_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("last_name")}
error={formik.touched.last_name && Boolean(formik.errors.last_name)}
helperText={formik.touched.last_name && formik.errors.last_name}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<SelectBox
name="province_id"
label={t("LoanRequest.text_field_province_id")}
size="small"
selectType="province_id"
isLoading={isLoadingProvinceList}
errorEcured={errorProvinceList}
selectors={provinceList}
schema={{ value: "value", name: "name" }}
select={formik.values.province_id}
value={formik.values.province_id}
handleChange={(event) => {
formik.setFieldValue("province_id", event.target.value);
formik.setFieldTouched("city_id", false, false);
formik.setFieldValue("city_id", "");
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.province_id && Boolean(formik.errors.province_id)}
helperText={formik.touched.province_id && formik.errors.province_id}
onBlur={formik.handleBlur("province_id")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="city_id"
label={
isLoadingCityList
? `${t("LoanRequest.enter_province")}`
: cityList.length === 0
? `${t("LoanRequest.cityList_empty")}`
: cityTextField
}
size="small"
selectType="city_id"
schema={{ value: "value", name: "name" }}
disabled={cityList.length === 0}
isLoading={isLoadingCityList}
selectors={cityList}
select={formik.values.city_id}
value={formik.values.city_id}
handleChange={(event) => formik.setFieldValue("city_id", event.target.value)}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.city_id && Boolean(formik.errors.city_id)}
helperText={formik.touched.city_id && formik.errors.city_id}
onBlur={formik.handleBlur("city_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="father_name"
variant="outlined"
value={formik.values.father_name}
onChange={formik.handleChange}
size="small"
label={t("LoanRequest.text_field_father_name")}
placeholder={t("LoanRequest.text_field_enter_your_father_name")}
onBlur={formik.handleBlur("father_name")}
error={formik.touched.father_name && Boolean(formik.errors.father_name)}
helperText={formik.touched.father_name && formik.errors.father_name}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="gender"
label={t("LoanRequest.text_field_gender")}
size="small"
value={formik.values.gender}
selectType="gender"
selectors={[
{
id: 1,
value: 1,
name: "زن",
},
{
id: 2,
value: 0,
name: "مرد",
},
]}
schema={{ value: "value", name: "name" }}
select={formik.values.gender}
handleChange={(event) => {
formik.setFieldValue("gender", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.gender && Boolean(formik.errors.gender)}
helperText={formik.touched.gender && formik.errors.gender}
onBlur={formik.handleBlur("gender")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<MuiDatePicker
formik={formik}
error={formik.touched.birthday && Boolean(formik.errors.birthday)}
helperText={formik.touched.birthday && formik.errors.birthday}
onBlur={formik.handleBlur("birthday")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="postal_code"
variant="outlined"
value={formik.values.postal_code}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "postal_code",
value: inputValue,
},
});
}}
size="small"
label={t("LoanRequest.text_field_postal_code")}
placeholder={t("LoanRequest.text_field_enter_your_postal_code")}
fullWidth
onBlur={formik.handleBlur("postal_code")}
error={formik.touched.postal_code && Boolean(formik.errors.postal_code)}
helperText={formik.touched.postal_code && formik.errors.postal_code}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="telephone_number"
variant="outlined"
value={formik.values.telephone_number}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
size="small"
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "telephone_number",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_tel_number")}
placeholder={t("LoanRequest.text_field_enter_your_tel_number")}
fullWidth
onBlur={formik.handleBlur("telephone_number")}
error={formik.touched.telephone_number && Boolean(formik.errors.telephone_number)}
helperText={formik.touched.telephone_number && formik.errors.telephone_number}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<SelectBox
name="education_id"
label={t("LoanRequest.text_field_education_id")}
size="small"
isLoading={isLoadingEducationsList}
errorEcured={errorEducationsList}
selectType="education_id"
selectors={educationsList}
select={formik.values.education_id}
value={formik.values.education_id}
schema={{ value: "id", name: "title" }}
handleChange={(event) => {
formik.setFieldValue("education_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.education_id && Boolean(formik.errors.education_id)}
helperText={formik.touched.education_id && formik.errors.education_id}
onBlur={formik.handleBlur("education_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="occupation_id"
label={t("LoanRequest.text_field_occupation_id")}
size="small"
isLoading={isLoadingOccupationsList}
errorEcured={errorOccupationsList}
selectType="occupation_id"
schema={{ value: "id", name: "title" }}
selectors={occupationsList}
select={formik.values.occupation_id}
value={formik.values.occupation_id}
handleChange={(event) => {
formik.setFieldValue("occupation_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.occupation_id && Boolean(formik.errors.occupation_id)}
helperText={formik.touched.occupation_id && formik.errors.occupation_id}
onBlur={formik.handleBlur("occupation_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="welfare_complex_degree"
label={t("LoanRequest.text_field_degree")}
size="small"
value={formik.values.welfare_complex_degree}
selectType="welfare_complex_degree"
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.welfare_complex_degree}
handleChange={(event) => {
formik.setFieldValue("welfare_complex_degree", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)}
helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree}
onBlur={formik.handleBlur("welfare_complex_degree")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<TextField
multiline
rows={4}
sx={{ width: "100%" }}
name="address"
variant="outlined"
size="small"
label={t("LoanRequest.text_field_address")}
placeholder={t("LoanRequest.text_field_enter_your_address")}
fullWidth
value={formik.values.address}
onChange={formik.handleChange}
onBlur={formik.handleBlur("address")}
error={formik.touched.address && Boolean(formik.errors.address)}
helperText={formik.touched.address && formik.errors.address}
/>
</Grid>
</Grid>
<Stack
sx={{ mb: 5, mx: 2 }}
spacing={2}
direction={"row"}
alignItems={"center"}
justifyContent={"flex-end"}
>
<Button startIcon={<ExitToAppIcon />} variant={"outlined"} size={"large"} color={"primary"} disabled>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<KeyboardDoubleArrowLeftIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={formik.isSubmitting}
>
{t("RefahiLoanRequest.next-button")}
</Button>
</Stack>
</>
);
};
export default BuildRealPersonalInfo;

View File

@@ -0,0 +1,464 @@
import { Button, Checkbox, FormControlLabel, FormHelperText, Grid, Stack, TextField, Typography } from "@mui/material";
import PriceField from "@/core/components/PriceField";
import * as React from "react";
import { useTranslations } from "next-intl";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import BeenhereIcon from "@mui/icons-material/Beenhere";
import * as Yup from "yup";
import { useFormik } from "formik";
import PickerWithDynamicField from "@/core/components/EditedDatePicker";
import UploadImage from "./UploadImage";
import { useRequest, useUser } from "@witel/webapp-builder";
import { SEND_LOAN_REQUEST_REFAHI } from "@/core/data/apiRoutes";
import { useState } from "react";
import { useRouter } from "next/router";
const BuildRequestDetail = ({ state, handleBack, setFinishRefahiLoanRequest, dispatch }) => {
const t = useTranslations();
const [submitting, setSubmitting] = useState(false);
const requestServer = useRequest();
const { getUser, changeUser } = useUser();
const router = useRouter();
const initialValues = {
requested_facility_amount: state.requested_facility_amount,
person_share: state.person_share,
investment_amount: state.investment_amount,
basic_approval_renewal_date: state.basic_approval_renewal_date,
basic_approval_number: state.basic_approval_number,
basic_approval_renewal_image: state.basic_approval_renewal_image,
user_committed_employment: state.user_committed_employment,
user_existing_employment: state.user_existing_employment,
basic_approval_image: state.basic_approval_image,
project_physical_progress: state.project_physical_progress,
checkedBox: state.checkedBox,
facility_usage_history: state.facility_usage_history,
};
const validationSchema = Yup.object().shape({
requested_facility_amount: Yup.string().required(t("LoanRequest.error_message_requested_facilities")),
person_share: Yup.string().required(t("LoanRequest.error_message_applicant_payment")),
investment_amount: Yup.string().required(t("LoanRequest.error_message_money_investment")),
basic_approval_number: Yup.string().required(t("LoanRequest.error_message_principle_agreement_number")),
basic_approval_renewal_date: Yup.string().required(t("LoanRequest.error_message_basic_approval_renewal_date")),
project_physical_progress: Yup.number()
.min(40, t("LoanRequest.error_message_progress_min_40"))
.max(100, t("LoanRequest.error_message_progress_max_100"))
.required(t("LoanRequest.error_message_progress_percentage")),
user_committed_employment: Yup.string().required(t("LoanRequest.error_message_user_committed_employment")),
user_existing_employment: Yup.string().required(t("LoanRequest.error_message_user_existing_employment")),
basic_approval_renewal_image: Yup.mixed()
.required(t("RefahiLoanRequest.upload_principle_agreement_img_required"))
.test("fileSize", `${t("RefahiLoanRequest.upload_principle_agreement_img_unit")}`, (value) => {
return value.size <= 2 * 1024 * 1024;
})
.test("fileType", `${t("RefahiLoanRequest.upload_principle_agreement_img_format")}`, (value) => {
const allowedTypes = ["image/jpg", "image/jpeg", "image/png"];
return allowedTypes.includes(value.type);
}),
basic_approval_image: Yup.mixed()
.required(t("RefahiLoanRequest.upload_refresh_date_img_required"))
.test("fileSize", `${t("RefahiLoanRequest.upload_principle_agreement_img_unit")}`, (value) => {
return value.size <= 2 * 1024 * 1024;
})
.test("fileType", `${t("RefahiLoanRequest.upload_principle_agreement_img_format")}`, (value) => {
const allowedTypes = ["image/jpg", "image/jpeg", "image/png"];
return allowedTypes.includes(value.type);
}),
checkedBox: Yup.boolean()
.oneOf([true], t("LoanRequest.checkbox_required"))
.required(t("LoanRequest.checkbox_required")),
});
const handleSubmit = async (values) => {
let updatedState = { ...state, ...values };
dispatch({ type: "SET_REQUEST_INFO", requestInfo: values });
const formData = new FormData();
const is_legal_person = updatedState.person_type === "real" ? 0 : 1;
delete updatedState.person_type;
if (updatedState.national_serial_number_or_tracking_code === "national_serial_number") {
formData.append("national_serial_number", updatedState.national_serial_number);
delete updatedState.national_card_tracking_code;
} else {
formData.append("national_tracking_code", updatedState.national_card_tracking_code);
delete updatedState.national_serial_number;
}
delete updatedState.national_serial_number_or_tracking_code;
delete updatedState.checkedBox;
formData.append("is_legal_person", is_legal_person);
updatedState = {
...updatedState,
birthday: updatedState.birthday.locale("en").format("YYYY-MM-DD"),
basic_approval_renewal_date: updatedState.basic_approval_renewal_date.locale("en").format("YYYY-MM-DD"),
company_register_date: updatedState.company_register_date
? updatedState.company_register_date.locale("en").format("YYYY-MM-DD")
: "",
facility_usage_history: updatedState.facility_usage_history ? 1 : 0,
};
Object.keys(updatedState).forEach((key) => {
if (updatedState[key] !== null && updatedState[key] !== undefined) {
formData.append(key, updatedState[key]);
}
});
if (!is_legal_person) {
formData.delete("company_register_date");
formData.delete("shenase_meli");
formData.delete("register_number");
formData.delete("company_name");
}
try {
setSubmitting(true);
await requestServer(SEND_LOAN_REQUEST_REFAHI, "post", {
auth: true,
notification: true,
data: formData,
});
// setFinishRefahiLoanRequest(true);
router.replace("/dashboard/followUp-loan");
getUser((data) => {
changeUser(data);
});
} catch (error) {
console.error("Error submitting request:", error);
} finally {
setSubmitting(false);
}
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
const handleAmountChange = (event) => {
if (!isNaN(event.target.value)) {
formik.setFieldValue("requested_facility_amount", event.target.value).then(() => {
formik.setFieldTouched("person_share", false, false);
formik.setFieldValue("person_share", Math.floor(event.target.value * 0.2));
});
} else {
formik.setFieldValue("requested_facility_amount", formik.values.requested_facilities);
}
};
return (
<>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<PriceField
name="investment_amount"
label={t("LoanRequest.text_field_money_investment")}
type="text"
size="small"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.investment_amount}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "investment_amount",
value: inputValue,
},
});
}}
onBlur={formik.handleBlur("investment_amount")}
error={formik.touched.investment_amount && Boolean(formik.errors.investment_amount)}
helperText={formik.touched.investment_amount && formik.errors.investment_amount}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<PriceField
name="requested_facility_amount"
label={t("LoanRequest.text_field_requested_facilities")}
type="text"
size="small"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.requested_facility_amount}
onChange={handleAmountChange}
onBlur={formik.handleBlur("requested_facility_amount")}
error={
formik.touched.requested_facility_amount && Boolean(formik.errors.requested_facility_amount)
}
helperText={formik.touched.requested_facility_amount && formik.errors.requested_facility_amount}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<PriceField
name="person_share"
label={t("LoanRequest.text_field_applicant_payment")}
type="text"
size="small"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.person_share}
disabled
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
rows={4}
sx={{ width: "100%" }}
name="user_committed_employment"
variant="outlined"
value={formik.values.user_committed_employment}
size="small"
type={"tel"}
label={t("LoanRequest.user_committed_employment")}
error={!!(formik.touched.user_committed_employment && formik.errors.user_committed_employment)}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "user_committed_employment",
value: inputValue,
},
});
}}
fullWidth
helperText={
formik.touched.user_committed_employment ? formik.errors.user_committed_employment : null
}
onBlur={formik.handleBlur("user_committed_employment")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
rows={4}
sx={{ width: "100%" }}
name="user_existing_employment"
variant="outlined"
type={"tel"}
value={formik.values.user_existing_employment}
size="small"
label={t("LoanRequest.user_existing_employment")}
error={!!(formik.touched.user_existing_employment && formik.errors.user_existing_employment)}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "user_existing_employment",
value: inputValue,
},
});
}}
fullWidth
helperText={
formik.touched.user_existing_employment ? formik.errors.user_existing_employment : null
}
onBlur={formik.handleBlur("user_existing_employment")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
rows={4}
sx={{ width: "100%" }}
name="project_physical_progress"
variant="outlined"
value={formik.values.project_physical_progress}
size="small"
type={"tel"}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
label={t("LoanRequest.text_field_progress_percentage")}
error={!!(formik.touched.project_physical_progress && formik.errors.project_physical_progress)}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "project_physical_progress",
value: inputValue,
},
});
}}
fullWidth
helperText={
formik.touched.project_physical_progress ? formik.errors.project_physical_progress : null
}
onBlur={formik.handleBlur("project_physical_progress")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
rows={4}
sx={{ width: "100%" }}
name="basic_approval_number"
variant="outlined"
value={formik.values.basic_approval_number}
size="small"
type={"tel"}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
label={t("LoanRequest.principle_agreement_number")}
error={!!(formik.touched.basic_approval_number && formik.errors.basic_approval_number)}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "basic_approval_number",
value: inputValue,
},
});
}}
fullWidth
helperText={formik.touched.basic_approval_number ? formik.errors.basic_approval_number : null}
onBlur={formik.handleBlur("basic_approval_number")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<PickerWithDynamicField
formik={formik}
fieldName="basic_approval_renewal_date"
label={t("LoanRequest.basic_approval_renewal_date")}
buttonLabel={t("LoanRequest.enter_basic_approval_renewal_date")}
disabled={false}
errorText={
!!(formik.touched.basic_approval_renewal_date && formik.errors.basic_approval_renewal_date)
}
helperText={
formik.touched.basic_approval_renewal_date
? formik.errors.basic_approval_renewal_date
: null
}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<Stack alignItems={"center"}>
<Typography
sx={{
fontSize: 14,
border: 1,
borderBottom: 0,
borderColor: "divider",
px: 2,
py: 1,
borderRadius: 2,
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
}}
>
{t("RefahiLoanRequest.upload_principle_agreement_img")}
</Typography>
<UploadImage formik={formik} fieldName={"basic_approval_image"} />
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack alignItems={"center"}>
<Typography
sx={{
fontSize: 14,
border: 1,
borderBottom: 0,
borderColor: "divider",
px: 2,
py: 1,
borderRadius: 2,
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
}}
>
{t("RefahiLoanRequest.upload_refresh_date_img")}
</Typography>
<UploadImage formik={formik} fieldName={"basic_approval_renewal_image"} />
</Stack>
</Grid>
</Grid>
<Grid container sx={{ padding: 2 }}>
<Grid item xs={12}>
<FormControlLabel
color={"error.main"}
control={
<Checkbox
checked={formik.values.facility_usage_history}
onChange={(event) => {
formik.setFieldValue("facility_usage_history", event.target.checked);
}}
/>
}
label={`${t("LoanRequest.history_facilities")}`}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<FormControlLabel
color={"error.main"}
control={
<Checkbox
checked={formik.values.checkedBox}
onChange={(event) => {
formik.setFieldValue("checkedBox", event.target.checked);
}}
onBlur={formik.handleBlur("checkedBox")}
/>
}
label={`${t("LoanRequest.checkbox")}`}
/>
<FormHelperText sx={{ color: "error.main" }}>
{formik.touched.checkedBox && formik.errors.checkedBox ? formik.errors.checkedBox : null}
</FormHelperText>
</Grid>
</Grid>
<Stack sx={{ mx: 5 }} spacing={2} direction={"row"} alignItems={"center"} justifyContent={"flex-end"}>
<Button
startIcon={<ExitToAppIcon />}
variant={"outlined"}
size={"large"}
color={"primary"}
onClick={handleBack}
>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<BeenhereIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={submitting}
>
{t("RefahiLoanRequest.submit-button")}
</Button>
</Stack>
</>
);
};
export default BuildRequestDetail;

View File

@@ -0,0 +1,54 @@
import { useState } from "react";
import { Stack, ToggleButton, ToggleButtonGroup } from "@mui/material";
import { useTranslations } from "next-intl";
import BuildLegalPersonalInfo from "./BuildLegalPersonalInfo";
import BuildRealPersonalInfo from "./BuildRealPersonalInfo";
const BuldToggleRealLegal = ({
state,
handleNext,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
return (
<>
<Stack sx={{ width: "100%", my: 3 }} justifyContent={"center"} alignItems={"center"}>
<ToggleButtonGroup
color="primary"
value={state.person_type}
exclusive
onChange={(e, value) => {
if (value === null) return;
dispatch({ type: "SET_PERSON_TYPE", person_type: value });
}}
>
<ToggleButton value="real">{t("LoanRequest.real_person")}</ToggleButton>
<ToggleButton value="legal">{t("LoanRequest.legal_person")}</ToggleButton>
</ToggleButtonGroup>
</Stack>
{state.person_type === "real" ? (
<BuildRealPersonalInfo
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
dispatch={dispatch}
handleNext={handleNext}
state={state}
/>
) : (
<BuildLegalPersonalInfo
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
state={state}
dispatch={dispatch}
handleNext={handleNext}
/>
)}
</>
);
};
export default BuldToggleRealLegal;

View File

@@ -0,0 +1,51 @@
import UploadSystem from "@/core/components/UploadSystem";
import * as React from "react";
import UploadFileNotification from "@/core/components/notifications/UploadFileNotification";
import { useState } from "react";
import { useTranslations } from "next-intl";
import { FormHelperText, Stack } from "@mui/material";
const UploadImage = ({ formik, fieldName }) => {
const t = useTranslations();
const [selectedImage, setSelectedImage] = useState("");
const [fileType, setFileType] = useState(null);
const [fileName, setFileName] = useState(null);
const [showAddIcon, setShowAddIcon] = useState(true);
const handleUploadChange = (event) => {
const uploadedFile = event.target?.files?.[0];
if (uploadedFile) {
const maxFileSize = 2 * 1024 * 1024;
if (uploadedFile.size > maxFileSize) {
UploadFileNotification(t);
event.target.value = "";
return;
}
const fileType = event.target?.files?.[0].type;
const fileName = event.target?.files?.[0].name;
setSelectedImage(URL.createObjectURL(uploadedFile));
setFileType(fileType);
setFileName(fileName);
formik.setFieldValue(fieldName, uploadedFile);
setShowAddIcon(false);
}
};
return (
<>
<UploadSystem
selectedImage={selectedImage}
handleUploadChange={handleUploadChange}
fileType={fileType}
fileName={fileName}
setSelectedImage={setSelectedImage}
imageSize={[250, 150]}
setShowAddIcon={setShowAddIcon}
showAddIcon={showAddIcon}
/>
<FormHelperText error={Boolean(formik.errors[fieldName])}>
{formik.touched[fieldName] && formik.errors[fieldName]}
</FormHelperText>
</>
);
};
export default UploadImage;

View File

@@ -0,0 +1,123 @@
import { useReducer, useState } from "react";
import { useTranslations } from "next-intl";
import * as React from "react";
import { Stack, Step, StepLabel, Stepper } from "@mui/material";
import BuldToggleRealLegal from "./BuildToggleRealLegal";
import BuildProjectInfo from "./BuildProjectInfo";
import BuildRequestDetail from "./BuildRequestDetail";
import useLimitedProvince from "@/lib/app/hooks/useLimitedProvince";
const _data = {
person_type: "real",
telephone_number: "",
activity_type_id: "",
refahi_type: 1,
requested_facility_amount: "",
person_share: "",
user_existing_employment: "",
user_committed_employment: "",
father_name: "",
gender: "",
welfare_complex_degree: "",
first_name: "",
last_name: "",
city_id: "",
project_city_id: "",
province_id: "",
project_province_id: "",
education_id: "",
occupation_id: "",
national_id: "",
national_serial_number: "",
national_card_tracking_code: "",
national_serial_number_or_tracking_code: "national_serial_number",
postal_code: "",
address: "",
birthday: "",
investment_amount: "",
basic_approval_renewal_date: "",
project_axis: "",
project_physical_progress: "",
project_kilometer_marker: "",
project_direction: "",
project_address: "",
basic_approval_number: "",
basic_approval_renewal_image: null,
basic_approval_image: null,
checkedBox: false,
facility_usage_history: false,
company_register_date: "",
shenase_meli: "",
register_number: "",
company_name: "",
};
const reducer = (state, action) => {
switch (action.type) {
case "SET_PERSONAL_INFO":
return { ...state, ...action.personalInfo };
case "SET_PROJECT_INFO":
return { ...state, ...action.projectInfo };
case "SET_REQUEST_INFO":
return { ...state, ...action.requestInfo };
case "SET_PERSON_TYPE":
return { ...state, person_type: action.person_type };
default:
return state;
}
};
const BuildForm = ({ setFinishRefahiLoanRequest }) => {
const t = useTranslations();
const [activeStep, setActiveStep] = useState(0);
const [state, dispatch] = useReducer(reducer, _data);
const { provinceList, isLoadingProvinceList, errorProvinceList } = useLimitedProvince();
const steps = [
t("RefahiLoanRequest.step_personal_info"),
t("RefahiLoanRequest.step_project_info"),
t("RefahiLoanRequest.step_contact_info"),
];
const handleNext = () => setActiveStep((prev) => prev + 1);
const handleBack = () => setActiveStep((prev) => prev - 1);
return (
<Stack>
<Stepper sx={{ my: 2 }} activeStep={activeStep} alternativeLabel>
{steps.map((label, index) => (
<Step key={index}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
{activeStep === 0 && (
<BuldToggleRealLegal
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
state={state}
dispatch={dispatch}
handleNext={handleNext}
/>
)}
{activeStep === 1 && (
<BuildProjectInfo
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
state={state}
dispatch={dispatch}
handleBack={handleBack}
handleNext={handleNext}
/>
)}
{activeStep === 2 && (
<BuildRequestDetail
state={state}
handleBack={handleBack}
dispatch={dispatch}
setFinishRefahiLoanRequest={setFinishRefahiLoanRequest}
/>
)}
</Stack>
);
};
export default BuildForm;

View File

@@ -0,0 +1,243 @@
import { Box, Button, Checkbox, FormControlLabel, FormGroup, Link, Stack, Typography } from "@mui/material";
import { CenterLayout } from "@witel/webapp-builder";
import { useTranslations } from "next-intl";
import { useState } from "react";
import DownloadIcon from "@mui/icons-material/Download";
const CheckRules = ({ setRulesChecked }) => {
const t = useTranslations();
const [rulesAccepted, setRulesAccepted] = useState(false);
const rules = [
{
title: "ضوابط و اسناد بالادستی",
subtitles: [
"قرارداد عاملیت سه جانبه فیمابین وزارت امور اقتصادی و دارائی، وزارت راه و شهرسازی وصندوق کارآفرینی امید ودستورالعمل اجرائی بند (الف)تبصره 18 قانون بودجه سال 1402",
],
},
{
title: "شرح خدمات تفاهم نامه",
subtitles: [
"اعطای تسهيلات تلفیقی،کمک های فنی و اعتباری و یارانه سود به اشخاص حقیقی وحقوقی، بخش های خصوصي غیردولتی و تعاونی های واجد شرایط در زمينه بازسازی ناوگان حمل و نقل مسافر واحداث و مرمت مجتمع های خدماتی و رفاهی",
],
},
{
title: "حوزه جغرافیایی",
subtitles: ["کل کشور"],
},
{
title: "نحوه فراخوان",
subtitles: [
"فراخوان متقاضيان مي بايست بصورت مستند (نظير چاپ در روزنامه رسمي و غيره )كه قابل ارايه به نهادهاي نظارتي باشد صورت پذيرد.",
],
},
{
title: "نحوه شناسایی و پذیرش متقاضیان",
subtitles: ["ثبت نام در سامانه مديريت درخواست تسهیلات به آدرس t18.rmto.ir و تایید کارگروه استانی"],
},
{
title: "بررسی مقدماتی اهلیت متقاضیان",
subtitles: [
"عدم دریافت تسهیلات از محل تبصره (18) قانون بودجه سنوات قبل",
"صرفاٌ به صورت آنلاین و از طریق سامانه مديريت درخواست تسهیلات به آدرس t18.rmto.ir و سامانه اسمارت صندوق کارآفرینی امید.",
"شرایط سنی: 18 تا 70 سال (با احتساب دوره باز پرداخت اقساط تسهیلات اعطایی) در خصوص متقاضیان بیش از 70 تا 80 سال ،منوط به رعایت ضوابط جاری صندوق و اخذ موافقت کتبی از مدیریت اعتبارات صندوق.",
"نداشتن بدهی غیر جاری (استعلام سامانه سمات)در شبکه بانکی و صندوق کارآفرینی امید و چک برگشتی در شبکه بانکی.",
],
},
{
title: "شرایط اختصاصی",
subtitles: [
{
title: "در حال احداث",
subtitles: [
"موافقت اصولی دارای اعتبار",
"پیشرفت فیزیکی بیش از 40 درصد ( اولویت با طرح هایی است که با دریافت تسهیلات، طرح قابل بهره برداری و افتتاح باشد.)",
"تقاضاي كتبي مالك براي استفاده از تسهيلات تبصره 18 به منظور احداث و یا مرمت مجتمع (لازم بذكر است چنانچه مالك بيش از يكنفر باشد ، رضايت محضري مابقي سهامداران براي استفاده از تسهيلات ضروري مي باشد)",
" داراي موافقت اصولي وتمديدي معتبر وداشتن پيشرفت فيزيكي بالاي 40درصد ",
"سرمایه گذاران مجتمع های خدماتی رفاهی و تیرپارکها از تاریخ شروع عملیات اجرایی نسبت به احداث اقدام می نمایند و ارائه تسهیلات پس از پیشرفت فیزیکی 40 درصد به ازای هر پروژه صورت خواهد پذیرفت که 40 درصد مبلغ تسهیلات در نظر گرفته شده همزمان با 40 درصد پیشرفت فیزیکی و مابقی در سه مرحله و به ازای افزایش 20 درصدی نسبت به پیشرفت فیزیکی قبلی پرداخت خواهد شد.",
"مبلغ تسهیلات برای احداث حداکثر 50میلیارد ریال می باشد.",
],
},
{
title: "مرمت و بازسازی",
subtitles: [
"جهت پرداخت تسهیلات در این زمینه، میبایست تاریخ بهره برداری آنها قبل از 1390/1/1 باشد.)",
"تسهیلات با اولویت بهسازی و مرمت نمازخانه ها و سرویس های بهداشتی واقع در مجتمع های خدماتی رفاهی صورت می پذیرد.",
"با توجه به اینکه مجتمع های خدماتی رفاهی و تیرپارکها در حال بهره برداری می باشند از تاریخ پرداخت تسهیلات نسبت به انجام مرمت ، بازسازی ، بهسازی و یا توسعه آن اقدام خواهد گردید.",
"مبلغ تسهیلات برای بهسازی و مرمت حداکثر10 میلیارد ریال می باشد.",
],
},
],
},
{
title: "تکمیل پرونده",
subtitles: [
"اعلام مدارک مورد نیاز به متقاضیان توسط موسسه عامل و تکمیل مدارک و مستندات مذکور توسط متقاضی ظرف 15 روز کاری.",
"بررسی توجیه اقتصادی و مالی طرح و تصویب در کمیته اعتباری و اعلام پذیرش یا رد ظرف 15 روز کاری.",
"انعقاد قرارداد با متقاضی و پرداخت تسهیلات منوط به تامین وثیقه و آورده از سوی متقاضی ظرف 15 روز کاری.",
"اخذ تعهد اشتغال از متقاضیان جهت امکان برخورد قانونی با متقاضی درصورت عدم ایفای تعهد.",
],
},
{
title: "وصایق و تضامین",
subtitles: ["مطابق با آخرین ضوابط و مقررات جاری صندوق ."],
},
{
title: "سهم آورنده",
subtitles: [
"سهم آورده متقاضیان مشمول و واجد شرایط بهره مندی از تسهیلات ماده (7) وفق ضوابط و مقررات جاری صندوق، دستورالعمل ها و بخشنامه های بانک مرکزی جمهوری اسلامی به میزان حداقل بیست درصد (20%) تعيين می گردد.",
],
},
{
title: "نرخ سود",
subtitles: [
{
title: "نرخ سود تسهیلات اعطایی مطابق ماده 10 این قرارداد 15.3٪ می باشد.",
subtitles: [
"اشتغال ثابت: مناطق غیر برخوردار و مرزی :13درصد و مناطق برخوردار: 15درصد",
"سرمایه در گردش: مناطق غیر برخوردار و مرزی : 18 درصد و مناطق بر خوردار: 20درصد",
],
},
],
},
{
title: "هزینه ها",
subtitles: [
"کلیه هزینه‌های مرتب بر تنظیم و عقد قراردادها (اعم از خرید سفته، هزینه عقد قرارداد در دفاتر رسمی و چه به‌صورت رسمی و چه به‌صورت تنظیمی داخلی و عادی) به عهده متقاضی است.",
],
},
{
title: "بازپرداخت",
subtitles: ["دوره مشارکت حداکثر 6 ماهه ، تنفس حداکثر 4 ماهه و دوره بازپرداخت تسهیلات سرمایه 5 سال است."],
},
{
title: "واریز تسهیلات",
subtitles: [
"واريز مبلغ تسهيلات توسط بانك و ثبت در سامانه به صورت مرحله ای و با توجه به پیشرفت پروژه خواهد بود",
],
},
{
title: "نظارت",
subtitles: [
"مطابق ماده 24 قرارداد عاملیت، نظارت و تایید تحقق اهداف موضوع اعطای تسهیلات و اعلام آن به «صندوق» حداکثر تا شش ماه پس از اتمام طرح (بابت اخذ تسهیلات از محل این قرارداد) بر عهده «واگذارنده اعتبار» (کمیته استانی نظارت) می‌باشد. در صورت اعلام «واگذارنده اعتبار» مبنی بر عدم تایید مراتب به «صندوق»، یارانه سود و تخفیفات مربوطه مشمول طرح نگردیده و متقاضی ملزم به پرداخت مابه‌التفاوت نرخ سود سهم «واگذارنده اعتبار» و نرخ سود تسهیلات مصوب شورای پول و اعتبار و وجه التزام مربوطه خواهد بود.",
],
},
{
title: "پیگیری بازپرداخت اصل ‌و فرع",
subtitles: [
"مطابق مواد 26 و 27 قرارداد عاملیت مسئولیت پیگیری بازپرداخت اصل ‌و فرع مجموع تسهیلات موضوع این قرارداد و انجام اقدامات قانونی برای وصول مانده مطالبات معوق تا پایان تسویه‌ حساب نهایی به عهده «صندوق» است. همچنین پرداخت هزینه های اجرایی و خسارات دادرسی (شامل: هزینه دادرسی، حق‌الوکاله وکیل و غیره) در صورت تعویق اقساط تسهیلات پرداختی، بر عهده متقاضی تسهیلات است.",
],
},
];
const renderRuleContent = (content, index) => {
if (typeof content === "string") {
return (
<Box key={index} component="li" sx={{ mb: 0.5 }}>
<Typography variant="body2">{content}</Typography>
</Box>
);
}
return (
<Box key={index} component="li" sx={{ mb: 0.5 }}>
<Typography variant="body2" sx={{ mb: 0.5 }}>
{content.title}
</Typography>
<Box component="ul" sx={{ listStyleType: "circle", paddingLeft: "1.5rem" }}>
{content.subtitles.map((sub, subIndex) => renderRuleContent(sub, subIndex))}
</Box>
</Box>
);
};
return (
<CenterLayout sx={{ p: 2 }}>
<Box
sx={{
border: 1,
p: { xs: 2, lg: 4 },
borderRadius: 4,
borderColor: "divider",
}}
>
<Typography variant="h5" align="center" sx={{ mb: 3, fontSize: { xs: "1.2rem", sm: "1.5rem" } }}>
{t("LoanRequest.accept_rules_title")}
</Typography>
<Box component="ul" sx={{ listStyleType: "none", paddingLeft: "1.5rem", mb: 3 }}>
{rules.map((rule, index) => (
<Box component="li" sx={{ mb: 2 }} key={index}>
<Typography variant="subtitle1" sx={{ fontWeight: "bold", mb: 1 }}>
{rule.title}
</Typography>
<ul style={{ listStyleType: "disc", paddingLeft: "1.5rem" }}>
{rule.subtitles.map((sub, index) => renderRuleContent(sub, index))}
</ul>
</Box>
))}
</Box>
<Stack>
<Typography variant="subtitle1" sx={{ fontWeight: "bold", fontSize: "1.1rem", mb: 2 }}>
مستندات
</Typography>
<Stack direction={"row"} spacing={4}>
<Button size={"small"} variant="contained" startIcon={<DownloadIcon />} sx={{ mb: 3 }}>
<Link
variant="subtitle1"
color={"white"}
download
underline="none"
href={"/files/قراردا عامليت.tif-.tif"}
>
قرارداد عاملیت
</Link>
</Button>
<Button size={"small"} variant="contained" startIcon={<DownloadIcon />} sx={{ mb: 3 }}>
<Link
variant="subtitle1"
color={"white"}
download
underline="none"
href={"/files/شيوه نامه تبصره 18-1402.pdf"}
>
شیوه نامه تبصره 18
</Link>
</Button>
</Stack>
<FormGroup sx={{ display: "flex", alignItems: "center", justifyContent: "center", mt: 5 }}>
<FormControlLabel
control={
<Checkbox
checked={rulesAccepted}
onChange={(e) => setRulesAccepted(e.target.checked)}
/>
}
label={t("LoanRequest.accept_all_rules")}
sx={{
textAlign: "center",
"& .MuiTypography-root": {
fontSize: "1rem", // Adjust font size
fontWeight: 500, // Adjust font weight (e.g., 400 for normal, 700 for bold)
},
}}
/>
</FormGroup>
</Stack>
<Stack alignItems={"center"} mt={2}>
<Button
variant="contained"
size="large"
disabled={!rulesAccepted}
onClick={setRulesChecked}
sx={{
px: { md: 25 },
py: 1,
}}
>
{t("LoanRequest.submit_rules")}
</Button>
</Stack>
</Box>
</CenterLayout>
);
};
export default CheckRules;

View File

@@ -0,0 +1,710 @@
import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material";
import SelectBox from "@/core/components/SelectBox";
import * as React from "react";
import useActivityType from "@/lib/app/hooks/useActivityType";
import { useTranslations } from "next-intl";
import MuiDatePicker from "@/core/components/MuiDatePicker";
import UseEducations from "@/lib/app/hooks/useEducations";
import useOccupations from "@/lib/app/hooks/useOccupations";
import { useFormik } from "formik";
import * as Yup from "yup";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { useEffect } from "react";
import useCities from "@/lib/app/hooks/useCities";
import LegalPersonDatePicker from "@/core/components/LegalPersonDatePicker";
const RestoreLegalPersonalInfo = ({
state,
handleNext,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
const { activityType, isLoadingActivityType, errorActivityType } = useActivityType();
const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations();
const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations();
const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities();
const initialValues = {
person_type: state.person_type,
province_id: state.province_id,
city_id: state.city_id,
father_name: state.father_name,
telephone_number: state.telephone_number,
activity_type_id: state.activity_type_id,
refahi_type: state.refahi_type,
gender: state.gender,
welfare_complex_degree: state.welfare_complex_degree,
first_name: state.first_name,
last_name: state.last_name,
education_id: state.education_id,
occupation_id: state.occupation_id,
national_id: state.national_id,
national_serial_number: state.national_serial_number,
national_card_tracking_code: state.national_card_tracking_code,
national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code,
postal_code: state.postal_code,
address: state.address,
birthday: state.birthday,
company_register_date: state.company_register_date,
shenase_meli: state.shenase_meli,
register_number: state.register_number,
company_name: state.company_name,
};
const validationSchema = Yup.object().shape({
province_id: Yup.string().required(t("LoanRequest.error_message_province_id")),
city_id: Yup.string().required(t("LoanRequest.error_message_city_id")),
telephone_number: Yup.mixed()
.test("max", `${t("LoanRequest.company_tel_number_max")}`, (value) => {
const stringValue = String(value);
return stringValue.length === 11;
})
.required(t("LoanRequest.error_message_company_tel_number")),
activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")),
gender: Yup.string().required(t("LoanRequest.error_message_boss_gender")),
welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")),
first_name: Yup.string().required(t("LoanRequest.error_message_boss_first_name")),
last_name: Yup.string().required(t("LoanRequest.error_message_boss_last_name")),
occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")),
education_id: Yup.string().required(t("LoanRequest.error_message_education_id")),
national_id: Yup.mixed()
.test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value))
.test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0)
.test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_boss_national_id")),
national_serial_number: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_serial_number"
? schema
.test(
"max",
`${t("LoanRequest.national_serial_number_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_boss_shenasname_serial"))
: schema;
}
),
national_card_tracking_code: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_card_tracking_code"
? schema
.test(
"max",
`${t("LoanRequest.national_tracking_code_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_boss_national_card_tracking_code"))
: schema;
}
),
address: Yup.string().required(t("LoanRequest.error_message_address")),
birthday: Yup.string().required(t("LoanRequest.error_message_boss_date_of_birth")),
postal_code: Yup.mixed()
.test("max", `${t("LoanRequest.company_postal_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_company_postal_code")),
father_name: Yup.string().required(t("LoanRequest.error_message_boss_father_name")),
shenase_meli: Yup.mixed().when("person_type", ([person_type], schema) => {
return person_type === "legal"
? schema
.test("is-number", `${t("LoanRequest.national_number_number")}`, (value) => !isNaN(value))
.test("positive", `${t("LoanRequest.national_number_positive")}`, (value) => value >= 0)
.test(
"max",
`${t("LoanRequest.national_number_max")}`,
(value) => value && value.toString().length === 11
)
.required(t("LoanRequest.error_message_national_number"))
: schema;
}),
company_register_date: Yup.string().required(t("LoanRequest.error_message_company_date")),
register_number: Yup.string().required(t("LoanRequest.error_message_register_number")),
company_name: Yup.string().required(t("LoanRequest.error_message_company_name")),
});
const handleSubmit = async (values) => {
dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values });
handleNext();
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
useEffect(() => {
if (formik.values.province_id === "") return;
setProvinceID(formik.values.province_id);
}, [formik.values.province_id]);
return (
<>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="refahi_type"
variant="outlined"
size="small"
value={"مرمت و بازسازی مجتمع رفاهی"}
label={t("LoanRequest.text_field_navgan_plan_id")}
fullWidth
disabled
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="activity_type_id"
label={t("LoanRequest.text_field_activity_type")}
size="small"
selectType="activity_type_id"
isLoading={isLoadingActivityType}
errorEcured={errorActivityType}
selectors={activityType}
schema={{ value: "value", name: "name" }}
select={formik.values.activity_type_id}
value={formik.values.activity_type_id}
handleChange={(event) => {
formik.setFieldValue("activity_type_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)}
helperText={formik.touched.activity_type_id && formik.errors.activity_type_id}
onBlur={formik.handleBlur("activity_type_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="shenase_meli"
variant="outlined"
size="small"
value={formik.values.shenase_meli}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "shenase_meli",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_national_number")}
placeholder={t("LoanRequest.text_field_enter_your_national_number")}
onBlur={formik.handleBlur("shenase_meli")}
error={formik.touched.shenase_meli && Boolean(formik.errors.shenase_meli)}
helperText={formik.touched.shenase_meli && formik.errors.shenase_meli}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="company_name"
variant="outlined"
size="small"
value={formik.values.company_name}
label={t("LoanRequest.text_field_company_name")}
placeholder={t("LoanRequest.text_field_enter_your_company_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("company_name")}
error={formik.touched.company_name && Boolean(formik.errors.company_name)}
helperText={formik.touched.company_name && formik.errors.company_name}
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="register_number"
variant="outlined"
size="small"
value={formik.values.register_number}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "register_number",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_register_number")}
placeholder={t("LoanRequest.text_field_enter_your_register_number")}
onBlur={formik.handleBlur("register_number")}
error={formik.touched.register_number && Boolean(formik.errors.register_number)}
helperText={formik.touched.register_number && formik.errors.register_number}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<ToggleButtonGroup
color="primary"
fullWidth
size={"small"}
value={formik.values.national_serial_number_or_tracking_code}
exclusive
onChange={(e, value) => {
if (value === null) return;
formik.handleChange({
target: {
name: "national_serial_number_or_tracking_code",
value: value,
},
});
}}
>
<ToggleButton value="national_serial_number">
{t("LoanRequest.text_field_shenasname_serial")}
</ToggleButton>
<ToggleButton value="national_card_tracking_code">
{t("LoanRequest.text_field_national_trackin_code")}
</ToggleButton>
</ToggleButtonGroup>
</Grid>
{formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_serial_number"
variant="outlined"
size="small"
value={formik.values.national_serial_number}
label={t("LoanRequest.text_field_boss_national_serial_number")}
placeholder={t("LoanRequest.text_field_enter_your_boss_national_serial_number")}
fullWidth
onChange={(e) => {
const inputValue = e.target.value;
const regex = /^[A-Za-z0-9]*$/;
if (regex.test(inputValue)) {
formik.setFieldValue("national_serial_number", inputValue);
}
}}
onBlur={formik.handleBlur("national_serial_number")}
error={
formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number)
}
helperText={formik.touched.national_serial_number && formik.errors.national_serial_number}
/>
</Grid>
) : (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_card_tracking_code"
variant="outlined"
size="small"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
value={formik.values.national_card_tracking_code}
label={t("LoanRequest.text_field_boss_national_card_tracking_code")}
placeholder={t("LoanRequest.text_field_enter_your_boss_national_card_tracking_code")}
fullWidth
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_card_tracking_code",
value: inputValue,
},
});
}}
onBlur={formik.handleBlur("national_card_tracking_code")}
error={
formik.touched.national_card_tracking_code &&
Boolean(formik.errors.national_card_tracking_code)
}
helperText={
formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code
}
/>
</Grid>
)}
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_id"
variant="outlined"
size="small"
value={formik.values.national_id}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_id",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_boss_national_code")}
placeholder={t("LoanRequest.text_field_enter_your_boss_national_code")}
onBlur={formik.handleBlur("national_id")}
error={formik.touched.national_id && Boolean(formik.errors.national_id)}
helperText={formik.touched.national_id && formik.errors.national_id}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="first_name"
variant="outlined"
size="small"
value={formik.values.first_name}
label={t("LoanRequest.text_field_boss_first_name")}
placeholder={t("LoanRequest.text_field_enter_your_boss_first_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("first_name")}
error={formik.touched.first_name && Boolean(formik.errors.first_name)}
helperText={formik.touched.first_name && formik.errors.first_name}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="last_name"
variant="outlined"
size="small"
value={formik.values.last_name}
label={t("LoanRequest.text_field_boss_last_name")}
placeholder={t("LoanRequest.text_field_enter_your_boss_last_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("last_name")}
error={formik.touched.last_name && Boolean(formik.errors.last_name)}
helperText={formik.touched.last_name && formik.errors.last_name}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<SelectBox
name="province_id"
label={t("LoanRequest.text_field_province_id")}
size="small"
selectType="province_id"
isLoading={isLoadingProvinceList}
errorEcured={errorProvinceList}
selectors={provinceList}
schema={{ value: "value", name: "name" }}
select={formik.values.province_id}
value={formik.values.province_id}
handleChange={(event) => {
formik.setFieldValue("province_id", event.target.value);
formik.setFieldTouched("city_id", false, false);
formik.setFieldValue("city_id", "");
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.province_id && Boolean(formik.errors.province_id)}
helperText={formik.touched.province_id && formik.errors.province_id}
onBlur={formik.handleBlur("province_id")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="city_id"
label={
isLoadingCityList
? `${t("LoanRequest.enter_province")}`
: cityList.length === 0
? `${t("LoanRequest.cityList_empty")}`
: cityTextField
}
size="small"
selectType="city_id"
schema={{ value: "value", name: "name" }}
disabled={cityList.length === 0}
isLoading={isLoadingCityList}
selectors={cityList}
select={formik.values.city_id}
value={formik.values.city_id}
handleChange={(event) => formik.setFieldValue("city_id", event.target.value)}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.city_id && Boolean(formik.errors.city_id)}
helperText={formik.touched.city_id && formik.errors.city_id}
onBlur={formik.handleBlur("city_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="father_name"
variant="outlined"
value={formik.values.father_name}
onChange={formik.handleChange}
size="small"
label={t("LoanRequest.text_field_boss_father_name")}
placeholder={t("LoanRequest.text_field_enter_your_boss_father_name")}
onBlur={formik.handleBlur("father_name")}
error={formik.touched.father_name && Boolean(formik.errors.father_name)}
helperText={formik.touched.father_name && formik.errors.father_name}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="gender"
label={t("LoanRequest.text_field_boss_gender")}
size="small"
value={formik.values.gender}
selectType="gender"
selectors={[
{
id: 1,
value: 1,
name: "زن",
},
{
id: 2,
value: 0,
name: "مرد",
},
]}
schema={{ value: "value", name: "name" }}
select={formik.values.gender}
handleChange={(event) => {
formik.setFieldValue("gender", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.gender && Boolean(formik.errors.gender)}
helperText={formik.touched.gender && formik.errors.gender}
onBlur={formik.handleBlur("gender")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<MuiDatePicker
formik={formik}
error={formik.touched.birthday && Boolean(formik.errors.birthday)}
helperText={formik.touched.birthday && formik.errors.birthday}
onBlur={formik.handleBlur("birthday")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="postal_code"
variant="outlined"
value={formik.values.postal_code}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "postal_code",
value: inputValue,
},
});
}}
size="small"
label={t("LoanRequest.text_field_company_postal_code")}
placeholder={t("LoanRequest.text_field_enter_your_company_postal_code")}
fullWidth
onBlur={formik.handleBlur("postal_code")}
error={formik.touched.postal_code && Boolean(formik.errors.postal_code)}
helperText={formik.touched.postal_code && formik.errors.postal_code}
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="telephone_number"
variant="outlined"
value={formik.values.telephone_number}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
size="small"
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "telephone_number",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_company_tel_number")}
placeholder={t("LoanRequest.text_field_enter_your_company_tel_number")}
fullWidth
onBlur={formik.handleBlur("telephone_number")}
error={formik.touched.telephone_number && Boolean(formik.errors.telephone_number)}
helperText={formik.touched.telephone_number && formik.errors.telephone_number}
/>
</Grid>
<Grid item xs={12} sm={4}>
<LegalPersonDatePicker
formik={formik}
error={formik.touched.company_register_date && Boolean(formik.errors.company_register_date)}
helperText={formik.touched.company_register_date && formik.errors.company_register_date}
onBlur={formik.handleBlur("company_register_date")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<SelectBox
name="education_id"
label={t("LoanRequest.text_field_education_id")}
size="small"
isLoading={isLoadingEducationsList}
errorEcured={errorEducationsList}
selectType="education_id"
selectors={educationsList}
select={formik.values.education_id}
value={formik.values.education_id}
schema={{ value: "id", name: "title" }}
handleChange={(event) => {
formik.setFieldValue("education_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.education_id && Boolean(formik.errors.education_id)}
helperText={formik.touched.education_id && formik.errors.education_id}
onBlur={formik.handleBlur("education_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="occupation_id"
label={t("LoanRequest.text_field_occupation_id")}
size="small"
isLoading={isLoadingOccupationsList}
errorEcured={errorOccupationsList}
selectType="occupation_id"
schema={{ value: "id", name: "title" }}
selectors={occupationsList}
select={formik.values.occupation_id}
value={formik.values.occupation_id}
handleChange={(event) => {
formik.setFieldValue("occupation_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.occupation_id && Boolean(formik.errors.occupation_id)}
helperText={formik.touched.occupation_id && formik.errors.occupation_id}
onBlur={formik.handleBlur("occupation_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="welfare_complex_degree"
label={t("LoanRequest.text_field_degree")}
size="small"
value={formik.values.welfare_complex_degree}
selectType="welfare_complex_degree"
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.welfare_complex_degree}
handleChange={(event) => {
formik.setFieldValue("welfare_complex_degree", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)}
helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree}
onBlur={formik.handleBlur("welfare_complex_degree")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<TextField
multiline
rows={4}
sx={{ width: "100%" }}
name="address"
variant="outlined"
size="small"
label={t("LoanRequest.text_field_address")}
placeholder={t("LoanRequest.text_field_enter_your_address")}
fullWidth
value={formik.values.address}
onChange={formik.handleChange}
onBlur={formik.handleBlur("address")}
error={formik.touched.address && Boolean(formik.errors.address)}
helperText={formik.touched.address && formik.errors.address}
/>
</Grid>
</Grid>
<Stack
sx={{ mb: 5, mx: 2 }}
spacing={2}
direction={"row"}
alignItems={"center"}
justifyContent={"flex-end"}
>
<Button startIcon={<ExitToAppIcon />} variant={"outlined"} size={"large"} color={"primary"} disabled>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<KeyboardDoubleArrowLeftIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={formik.isSubmitting}
>
{t("RefahiLoanRequest.next-button")}
</Button>
</Stack>
</>
);
};
export default RestoreLegalPersonalInfo;

View File

@@ -0,0 +1,232 @@
import { Button, Grid, Stack, TextField } from "@mui/material";
import SelectBox from "@/core/components/SelectBox";
import * as React from "react";
import { useTranslations } from "next-intl";
import * as Yup from "yup";
import { useFormik } from "formik";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { useEffect } from "react";
import useCities from "@/lib/app/hooks/useCities";
const RestoreProjectInfo = ({
state,
handleNext,
handleBack,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
const { cityList, setProvinceID, isLoadingCityList } = useCities();
const initialValues = {
project_province_id: state.project_province_id,
project_city_id: state.project_city_id,
project_axis: state.project_axis,
project_kilometer_marker: state.project_kilometer_marker,
project_direction: state.project_direction,
project_address: state.project_address,
};
const validationSchema = Yup.object().shape({
project_province_id: Yup.string().required(t("LoanRequest.error_message_project_province_id")),
project_city_id: Yup.string().required(t("LoanRequest.error_message_project_city_id")),
project_address: Yup.string().required(t("LoanRequest.error_message_execution_address")),
project_axis: Yup.string().required(t("LoanRequest.error_message_mehvar")),
project_kilometer_marker: Yup.string().required(t("LoanRequest.error_message_kilometer")),
project_direction: Yup.string().required(t("LoanRequest.error_message_samt")),
});
const handleSubmit = async (values) => {
dispatch({ type: "SET_PROJECT_INFO", projectInfo: values });
handleNext();
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
useEffect(() => {
if (formik.values.project_province_id === "") return;
setProvinceID(formik.values.project_province_id);
}, [formik.values.project_province_id]);
return (
<>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<SelectBox
name="project_province_id"
label={t("LoanRequest.text_field_project_province_id")}
size="small"
selectType="project_province_id"
isLoading={isLoadingProvinceList}
errorEcured={errorProvinceList}
selectors={provinceList}
schema={{ value: "value", name: "name" }}
select={formik.values.project_province_id}
value={formik.values.project_province_id}
handleChange={(event) => {
formik.setFieldValue("project_province_id", event.target.value);
formik.setFieldTouched("project_city_id", false, false);
formik.setFieldValue("project_city_id", "");
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.project_province_id && Boolean(formik.errors.project_province_id)}
helperText={formik.touched.project_province_id && formik.errors.project_province_id}
onBlur={formik.handleBlur("project_province_id")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="project_city_id"
label={
isLoadingCityList
? `${t("LoanRequest.enter_project_province_id")}`
: cityList.length === 0
? `${t("LoanRequest.project_cityList_empty")}`
: `${t("LoanRequest.project_city_id")}`
}
size="small"
selectType="project_city_id"
schema={{ value: "value", name: "name" }}
disabled={cityList.length === 0}
isLoading={isLoadingCityList}
selectors={cityList}
select={formik.values.project_city_id}
value={formik.values.project_city_id}
handleChange={(event) => formik.setFieldValue("project_city_id", event.target.value)}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.project_city_id && Boolean(formik.errors.project_city_id)}
helperText={formik.touched.project_city_id && formik.errors.project_city_id}
onBlur={formik.handleBlur("project_city_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="project_axis"
variant="outlined"
size="small"
value={formik.values.project_axis}
onChange={formik.handleChange}
label={t("LoanRequest.text_field_mehvar")}
placeholder={t("LoanRequest.text_field_enter_your_mehvar")}
onBlur={formik.handleBlur("project_axis")}
error={formik.touched.project_axis && Boolean(formik.errors.project_axis)}
helperText={formik.touched.project_axis && formik.errors.project_axis}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="project_kilometer_marker"
variant="outlined"
size="small"
value={formik.values.project_kilometer_marker}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "project_kilometer_marker",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_kilometer")}
placeholder={t("LoanRequest.text_field_enter_your_kilometer")}
onBlur={formik.handleBlur("project_kilometer_marker")}
error={
formik.touched.project_kilometer_marker && Boolean(formik.errors.project_kilometer_marker)
}
helperText={formik.touched.project_kilometer_marker && formik.errors.project_kilometer_marker}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="project_direction"
label={t("LoanRequest.text_field_samt")}
size="small"
value={formik.values.project_direction}
selectType="project_direction"
selectors={[
{
id: 1,
value: 1,
name: "رفت",
},
{
id: 2,
value: 0,
name: "برگشت",
},
]}
schema={{ value: "value", name: "name" }}
select={formik.values.project_direction}
handleChange={(event) => {
formik.setFieldValue("project_direction", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.project_direction && Boolean(formik.errors.project_direction)}
helperText={formik.touched.project_direction && formik.errors.project_direction}
onBlur={formik.handleBlur("project_direction")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<TextField
multiline
rows={4}
sx={{ width: "100%" }}
name="project_address"
variant="outlined"
size="small"
label={t("LoanRequest.text_field_execution_address")}
placeholder={t("LoanRequest.text_field_enter_your_execution_address")}
fullWidth
value={formik.values.project_address}
onChange={formik.handleChange}
onBlur={formik.handleBlur("project_address")}
error={formik.touched.project_address && Boolean(formik.errors.project_address)}
helperText={formik.touched.project_address && formik.errors.project_address}
/>
</Grid>
</Grid>
<Stack
onClick={handleBack}
sx={{ mx: 5 }}
spacing={2}
direction={"row"}
alignItems={"center"}
justifyContent={"flex-end"}
>
<Button startIcon={<ExitToAppIcon />} variant={"outlined"} size={"large"} color={"primary"}>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<KeyboardDoubleArrowLeftIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={formik.isSubmitting}
>
{t("RefahiLoanRequest.next-button")}
</Button>
</Stack>
</>
);
};
export default RestoreProjectInfo;

View File

@@ -0,0 +1,605 @@
import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material";
import SelectBox from "@/core/components/SelectBox";
import * as React from "react";
import useActivityType from "@/lib/app/hooks/useActivityType";
import { useTranslations } from "next-intl";
import MuiDatePicker from "@/core/components/MuiDatePicker";
import UseEducations from "@/lib/app/hooks/useEducations";
import useOccupations from "@/lib/app/hooks/useOccupations";
import { useFormik } from "formik";
import * as Yup from "yup";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { useEffect } from "react";
import useCities from "@/lib/app/hooks/useCities";
const RestoreRealPersonalInfo = ({
state,
handleNext,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
const { activityType, isLoadingActivityType, errorActivityType } = useActivityType();
const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations();
const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations();
const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities();
const initialValues = {
person_type: state.person_type,
father_name: state.father_name,
province_id: state.province_id,
city_id: state.city_id,
telephone_number: state.telephone_number,
activity_type_id: state.activity_type_id,
refahi_type: state.refahi_type,
gender: state.gender,
welfare_complex_degree: state.welfare_complex_degree,
first_name: state.first_name,
last_name: state.last_name,
education_id: state.education_id,
occupation_id: state.occupation_id,
national_id: state.national_id,
national_serial_number: state.national_serial_number,
national_card_tracking_code: state.national_card_tracking_code,
national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code,
postal_code: state.postal_code,
address: state.address,
birthday: state.birthday,
};
const validationSchema = Yup.object().shape({
province_id: Yup.string().required(t("LoanRequest.error_message_province_id")),
city_id: Yup.string().required(t("LoanRequest.error_message_city_id")),
telephone_number: Yup.mixed()
.test("max", `${t("LoanRequest.tel_number_max")}`, (value) => {
const stringValue = String(value);
return stringValue.length === 11;
})
.required(t("LoanRequest.error_message_tel_number")),
activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")),
gender: Yup.string().required(t("LoanRequest.error_message_gender")),
welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")),
first_name: Yup.string().required(t("LoanRequest.error_message_first_name")),
last_name: Yup.string().required(t("LoanRequest.error_message_last_name")),
occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")),
education_id: Yup.string().required(t("LoanRequest.error_message_education_id")),
national_id: Yup.mixed()
.test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value))
.test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0)
.test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_national_id")),
national_serial_number: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_serial_number"
? schema
.test(
"max",
`${t("LoanRequest.national_serial_number_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_shenasname_serial"))
: schema;
}
),
national_card_tracking_code: Yup.string().when(
"national_serial_number_or_tracking_code",
([national_serial_number_or_tracking_code], schema) => {
return national_serial_number_or_tracking_code === "national_card_tracking_code"
? schema
.test(
"max",
`${t("LoanRequest.national_tracking_code_max")}`,
(value) => value && value.toString().length === 10
)
.required(t("LoanRequest.error_message_tracking_code"))
: schema;
}
),
address: Yup.string().required(t("LoanRequest.error_message_address")),
birthday: Yup.string().required(t("LoanRequest.error_message_date_of_birth")),
postal_code: Yup.mixed()
.test("max", `${t("LoanRequest.postal_code_max")}`, (value) => value.toString().length === 10)
.required(t("LoanRequest.error_message_postal_code")),
father_name: Yup.string().required(t("LoanRequest.error_message_father_name")),
});
const handleSubmit = async (values) => {
dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values });
handleNext();
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
useEffect(() => {
if (formik.values.province_id === "") return;
setProvinceID(formik.values.province_id);
}, [formik.values.province_id]);
return (
<>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="refahi_type"
variant="outlined"
size="small"
value={"مرمت و بازسازی مجتمع رفاهی"}
label={t("LoanRequest.text_field_navgan_plan_id")}
fullWidth
disabled
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="activity_type_id"
label={t("LoanRequest.text_field_activity_type")}
size="small"
selectType="activity_type_id"
isLoading={isLoadingActivityType}
errorEcured={errorActivityType}
selectors={activityType}
schema={{ value: "value", name: "name" }}
select={formik.values.activity_type_id}
value={formik.values.activity_type_id}
handleChange={(event) => {
formik.setFieldValue("activity_type_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)}
helperText={formik.touched.activity_type_id && formik.errors.activity_type_id}
onBlur={formik.handleBlur("activity_type_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<ToggleButtonGroup
color="primary"
fullWidth
size={"small"}
value={formik.values.national_serial_number_or_tracking_code}
exclusive
onChange={(e, value) => {
if (value === null) return;
formik.handleChange({
target: {
name: "national_serial_number_or_tracking_code",
value: value,
},
});
}}
>
<ToggleButton value="national_serial_number">
{t("LoanRequest.text_field_shenasname_serial")}
</ToggleButton>
<ToggleButton value="national_card_tracking_code">
{t("LoanRequest.text_field_national_trackin_code")}
</ToggleButton>
</ToggleButtonGroup>
</Grid>
{formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_serial_number"
variant="outlined"
size="small"
value={formik.values.national_serial_number}
label={t("LoanRequest.text_field_shenasname_serial")}
placeholder={t("LoanRequest.text_field_enter_your_shenasname_serial")}
fullWidth
onChange={(e) => {
const inputValue = e.target.value;
const regex = /^[A-Za-z0-9]*$/;
if (regex.test(inputValue)) {
formik.setFieldValue("national_serial_number", inputValue);
}
}}
onBlur={formik.handleBlur("national_serial_number")}
error={
formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number)
}
helperText={formik.touched.national_serial_number && formik.errors.national_serial_number}
/>
</Grid>
) : (
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_card_tracking_code"
variant="outlined"
size="small"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
value={formik.values.national_card_tracking_code}
label={t("LoanRequest.text_field_national_trackin_code")}
placeholder={t("LoanRequest.text_field_enter_your_trackin_code")}
fullWidth
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_card_tracking_code",
value: inputValue,
},
});
}}
onBlur={formik.handleBlur("national_card_tracking_code")}
error={
formik.touched.national_card_tracking_code &&
Boolean(formik.errors.national_card_tracking_code)
}
helperText={
formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code
}
/>
</Grid>
)}
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="national_id"
variant="outlined"
size="small"
value={formik.values.national_id}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "national_id",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_national_code")}
placeholder={t("LoanRequest.text_field_enter_your_national_code")}
onBlur={formik.handleBlur("national_id")}
error={formik.touched.national_id && Boolean(formik.errors.national_id)}
helperText={formik.touched.national_id && formik.errors.national_id}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="first_name"
variant="outlined"
size="small"
value={formik.values.first_name}
label={t("LoanRequest.text_field_first_name")}
placeholder={t("LoanRequest.text_field_enter_your_first_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("first_name")}
error={formik.touched.first_name && Boolean(formik.errors.first_name)}
helperText={formik.touched.first_name && formik.errors.first_name}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="last_name"
variant="outlined"
size="small"
value={formik.values.last_name}
label={t("LoanRequest.text_field_last_name")}
placeholder={t("LoanRequest.text_field_enter_your_last_name")}
fullWidth
onChange={formik.handleChange}
onBlur={formik.handleBlur("last_name")}
error={formik.touched.last_name && Boolean(formik.errors.last_name)}
helperText={formik.touched.last_name && formik.errors.last_name}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<SelectBox
name="province_id"
label={t("LoanRequest.text_field_province_id")}
size="small"
selectType="province_id"
isLoading={isLoadingProvinceList}
errorEcured={errorProvinceList}
selectors={provinceList}
schema={{ value: "value", name: "name" }}
select={formik.values.province_id}
value={formik.values.province_id}
handleChange={(event) => {
formik.setFieldValue("province_id", event.target.value);
formik.setFieldTouched("city_id", false, false);
formik.setFieldValue("city_id", "");
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.province_id && Boolean(formik.errors.province_id)}
helperText={formik.touched.province_id && formik.errors.province_id}
onBlur={formik.handleBlur("province_id")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectBox
name="city_id"
label={
isLoadingCityList
? `${t("LoanRequest.enter_province")}`
: cityList.length === 0
? `${t("LoanRequest.cityList_empty")}`
: cityTextField
}
size="small"
selectType="city_id"
schema={{ value: "value", name: "name" }}
disabled={cityList.length === 0}
isLoading={isLoadingCityList}
selectors={cityList}
select={formik.values.city_id}
value={formik.values.city_id}
handleChange={(event) => formik.setFieldValue("city_id", event.target.value)}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.city_id && Boolean(formik.errors.city_id)}
helperText={formik.touched.city_id && formik.errors.city_id}
onBlur={formik.handleBlur("city_id")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<TextField
sx={{ width: "100%" }}
name="father_name"
variant="outlined"
value={formik.values.father_name}
onChange={formik.handleChange}
size="small"
label={t("LoanRequest.text_field_father_name")}
placeholder={t("LoanRequest.text_field_enter_your_father_name")}
onBlur={formik.handleBlur("father_name")}
error={formik.touched.father_name && Boolean(formik.errors.father_name)}
helperText={formik.touched.father_name && formik.errors.father_name}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="gender"
label={t("LoanRequest.text_field_gender")}
size="small"
value={formik.values.gender}
selectType="gender"
selectors={[
{
id: 1,
value: 1,
name: "زن",
},
{
id: 2,
value: 0,
name: "مرد",
},
]}
schema={{ value: "value", name: "name" }}
select={formik.values.gender}
handleChange={(event) => {
formik.setFieldValue("gender", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.gender && Boolean(formik.errors.gender)}
helperText={formik.touched.gender && formik.errors.gender}
onBlur={formik.handleBlur("gender")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<MuiDatePicker
formik={formik}
error={formik.touched.birthday && Boolean(formik.errors.birthday)}
helperText={formik.touched.birthday && formik.errors.birthday}
onBlur={formik.handleBlur("birthday")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="postal_code"
variant="outlined"
value={formik.values.postal_code}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "postal_code",
value: inputValue,
},
});
}}
size="small"
label={t("LoanRequest.text_field_postal_code")}
placeholder={t("LoanRequest.text_field_enter_your_postal_code")}
fullWidth
onBlur={formik.handleBlur("postal_code")}
error={formik.touched.postal_code && Boolean(formik.errors.postal_code)}
helperText={formik.touched.postal_code && formik.errors.postal_code}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
sx={{ width: "100%" }}
name="telephone_number"
variant="outlined"
value={formik.values.telephone_number}
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
type={"tel"}
size="small"
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "telephone_number",
value: inputValue,
},
});
}}
label={t("LoanRequest.text_field_tel_number")}
placeholder={t("LoanRequest.text_field_enter_your_tel_number")}
fullWidth
onBlur={formik.handleBlur("telephone_number")}
error={formik.touched.telephone_number && Boolean(formik.errors.telephone_number)}
helperText={formik.touched.telephone_number && formik.errors.telephone_number}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<SelectBox
name="education_id"
label={t("LoanRequest.text_field_education_id")}
size="small"
isLoading={isLoadingEducationsList}
errorEcured={errorEducationsList}
selectType="education_id"
selectors={educationsList}
select={formik.values.education_id}
value={formik.values.education_id}
schema={{ value: "id", name: "title" }}
handleChange={(event) => {
formik.setFieldValue("education_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.education_id && Boolean(formik.errors.education_id)}
helperText={formik.touched.education_id && formik.errors.education_id}
onBlur={formik.handleBlur("education_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="occupation_id"
label={t("LoanRequest.text_field_occupation_id")}
size="small"
isLoading={isLoadingOccupationsList}
errorEcured={errorOccupationsList}
selectType="occupation_id"
schema={{ value: "id", name: "title" }}
selectors={occupationsList}
select={formik.values.occupation_id}
value={formik.values.occupation_id}
handleChange={(event) => {
formik.setFieldValue("occupation_id", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.occupation_id && Boolean(formik.errors.occupation_id)}
helperText={formik.touched.occupation_id && formik.errors.occupation_id}
onBlur={formik.handleBlur("occupation_id")}
/>
</Grid>
<Grid item xs={12} sm={4}>
<SelectBox
name="welfare_complex_degree"
label={t("LoanRequest.text_field_degree")}
size="small"
value={formik.values.welfare_complex_degree}
selectType="welfare_complex_degree"
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.welfare_complex_degree}
handleChange={(event) => {
formik.setFieldValue("welfare_complex_degree", event.target.value);
}}
setFieldTouched={formik.setFieldTouched}
error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)}
helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree}
onBlur={formik.handleBlur("welfare_complex_degree")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<TextField
multiline
rows={4}
sx={{ width: "100%" }}
name="address"
variant="outlined"
size="small"
label={t("LoanRequest.text_field_address")}
placeholder={t("LoanRequest.text_field_enter_your_address")}
fullWidth
value={formik.values.address}
onChange={formik.handleChange}
onBlur={formik.handleBlur("address")}
error={formik.touched.address && Boolean(formik.errors.address)}
helperText={formik.touched.address && formik.errors.address}
/>
</Grid>
</Grid>
<Stack
sx={{ mb: 5, mx: 2 }}
spacing={2}
direction={"row"}
alignItems={"center"}
justifyContent={"flex-end"}
>
<Button startIcon={<ExitToAppIcon />} variant={"outlined"} size={"large"} color={"primary"} disabled>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<KeyboardDoubleArrowLeftIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={formik.isSubmitting}
>
{t("RefahiLoanRequest.next-button")}
</Button>
</Stack>
</>
);
};
export default RestoreRealPersonalInfo;

View File

@@ -0,0 +1,413 @@
import { Button, Checkbox, FormControlLabel, FormHelperText, Grid, Stack, TextField, Typography } from "@mui/material";
import PriceField from "@/core/components/PriceField";
import * as React from "react";
import { useTranslations } from "next-intl";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import BeenhereIcon from "@mui/icons-material/Beenhere";
import * as Yup from "yup";
import { useFormik } from "formik";
import PickerWithDynamicField from "@/core/components/EditedDatePicker";
import UploadImage from "@/components/dashboard/refahi/add-request-loan/forms/BuildForm/UploadImage";
import { SEND_LOAN_REQUEST_REFAHI } from "@/core/data/apiRoutes";
import { useState } from "react";
import { useRequest, useUser } from "@witel/webapp-builder";
import { useRouter } from "next/router";
const RestoreRequestDetail = ({ state, handleBack, dispatch, setFinishRefahiLoanRequest }) => {
const t = useTranslations();
const [submitting, setSubmitting] = useState(false);
const requestServer = useRequest();
const { getUser, changeUser } = useUser();
const router = useRouter();
const initialValues = {
requested_facility_amount: state.requested_facility_amount,
person_share: state.person_share,
investment_amount: state.investment_amount,
exploitation_date: state.exploitation_date,
exploitation_license_renewal_date: state.exploitation_license_renewal_date,
user_committed_employment: state.user_committed_employment,
user_existing_employment: state.user_existing_employment,
exploitation_license_image: state.exploitation_license_image,
exploitation_license_renewal_image: state.exploitation_license_renewal_image,
checkedBox: state.checkedBox,
facility_usage_history: state.facility_usage_history,
};
const validationSchema = Yup.object().shape({
requested_facility_amount: Yup.string().required(t("LoanRequest.error_message_requested_facilities")),
person_share: Yup.string().required(t("LoanRequest.error_message_applicant_payment")),
investment_amount: Yup.string().required(t("LoanRequest.error_message_money_investment")),
exploitation_date: Yup.string().required(t("LoanRequest.error_message_operation_date")),
exploitation_license_renewal_date: Yup.string().required(t("LoanRequest.error_message_refresh_date")),
user_committed_employment: Yup.string().required(t("LoanRequest.error_message_user_committed_employment")),
user_existing_employment: Yup.string().required(t("LoanRequest.error_message_user_existing_employment")),
exploitation_license_image: Yup.mixed()
.required(t("RefahiLoanRequest.upload_operating_license_img_required"))
.test("fileSize", `${t("RefahiLoanRequest.upload_operating_license_img_unit")}`, (value) => {
return value.size <= 2 * 1024 * 1024;
})
.test("fileType", `${t("RefahiLoanRequest.upload_operating_license_img_format")}`, (value) => {
const allowedTypes = ["image/jpg", "image/jpeg", "image/png"];
return allowedTypes.includes(value.type);
}),
exploitation_license_renewal_image: Yup.mixed()
.required(t("RefahiLoanRequest.upload_refresh_date_img_required"))
.test("fileSize", `${t("RefahiLoanRequest.upload_refresh_date_img_unit")}`, (value) => {
return value.size <= 2 * 1024 * 1024;
})
.test("fileType", `${t("RefahiLoanRequest.upload_refresh_date_img_format")}`, (value) => {
const allowedTypes = ["image/jpg", "image/jpeg", "image/png"];
return allowedTypes.includes(value.type);
}),
checkedBox: Yup.boolean()
.oneOf([true], t("LoanRequest.checkbox_required"))
.required(t("LoanRequest.checkbox_required")),
});
const handleSubmit = async (values, props) => {
let updatedState = { ...state, ...values };
dispatch({ type: "SET_REQUEST_INFO", requestInfo: values });
const formData = new FormData();
const is_legal_person = updatedState.person_type === "real" ? 0 : 1;
delete updatedState.person_type;
if (updatedState.national_serial_number_or_tracking_code === "national_serial_number") {
formData.append("national_serial_number", updatedState.national_serial_number);
delete updatedState.national_card_tracking_code;
} else {
formData.append("national_tracking_code", updatedState.national_card_tracking_code);
delete updatedState.national_serial_number;
}
delete updatedState.national_serial_number_or_tracking_code;
delete updatedState.checkedBox;
formData.append("is_legal_person", is_legal_person);
updatedState = {
...updatedState,
birthday: updatedState.birthday.locale("en").format("YYYY-MM-DD"),
exploitation_license_renewal_date: updatedState.exploitation_license_renewal_date
.locale("en")
.format("YYYY-MM-DD"),
exploitation_date: updatedState.exploitation_date.locale("en").format("YYYY-MM-DD"),
company_register_date: updatedState.company_register_date
? updatedState.company_register_date.locale("en").format("YYYY-MM-DD")
: "",
facility_usage_history: updatedState.facility_usage_history ? 1 : 0,
};
Object.keys(updatedState).forEach((key) => {
if (updatedState[key] !== null && updatedState[key] !== undefined) {
formData.append(key, updatedState[key]);
}
});
if (!is_legal_person) {
formData.delete("company_register_date");
formData.delete("shenase_meli");
formData.delete("register_number");
formData.delete("company_name");
}
try {
setSubmitting(true);
await requestServer(SEND_LOAN_REQUEST_REFAHI, "post", {
auth: true,
notification: true,
data: formData,
});
// setFinishRefahiLoanRequest(true);
router.replace("/dashboard/followUp-loan");
getUser((data) => {
changeUser(data);
});
} catch (error) {
console.error("Error submitting request:", error);
} finally {
setSubmitting(false);
}
};
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit,
});
const handleAmountChange = (event) => {
if (!isNaN(event.target.value)) {
formik.setFieldValue("requested_facility_amount", event.target.value).then(() => {
formik.setFieldTouched("person_share", false, false);
formik.setFieldValue("person_share", Math.floor(event.target.value * 0.2));
});
} else {
formik.setFieldValue("requested_facility_amount", formik.values.requested_facilities);
}
};
return (
<>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12} sm={4}>
<PriceField
name="investment_amount"
label={t("LoanRequest.text_field_money_investment")}
type="text"
size="small"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.investment_amount}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "investment_amount",
value: inputValue,
},
});
}}
onBlur={formik.handleBlur("investment_amount")}
error={formik.touched.investment_amount && Boolean(formik.errors.investment_amount)}
helperText={formik.touched.investment_amount && formik.errors.investment_amount}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<PriceField
name="requested_facility_amount"
label={t("LoanRequest.text_field_requested_facilities")}
type="text"
size="small"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.requested_facility_amount}
onChange={handleAmountChange}
onBlur={formik.handleBlur("requested_facility_amount")}
error={
formik.touched.requested_facility_amount && Boolean(formik.errors.requested_facility_amount)
}
helperText={formik.touched.requested_facility_amount && formik.errors.requested_facility_amount}
fullWidth
/>
</Grid>
<Grid item xs={12} sm={4}>
<PriceField
name="person_share"
label={t("LoanRequest.text_field_applicant_payment")}
type="text"
size="small"
inputProps={{
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
variant="outlined"
value={formik.values.person_share}
disabled
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<TextField
rows={4}
sx={{ width: "100%" }}
name="user_committed_employment"
variant="outlined"
value={formik.values.user_committed_employment}
size="small"
type={"tel"}
label={t("LoanRequest.user_committed_employment")}
error={!!(formik.touched.user_committed_employment && formik.errors.user_committed_employment)}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "user_committed_employment",
value: inputValue,
},
});
}}
fullWidth
helperText={
formik.touched.user_committed_employment ? formik.errors.user_committed_employment : null
}
onBlur={formik.handleBlur("user_committed_employment")}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
rows={4}
sx={{ width: "100%" }}
name="user_existing_employment"
variant="outlined"
type={"tel"}
value={formik.values.user_existing_employment}
size="small"
label={t("LoanRequest.user_existing_employment")}
error={!!(formik.touched.user_existing_employment && formik.errors.user_existing_employment)}
onChange={(event) => {
const inputValue = event.target.value;
if (isNaN(Number(inputValue))) {
return;
}
formik.handleChange({
target: {
name: "user_existing_employment",
value: inputValue,
},
});
}}
fullWidth
helperText={
formik.touched.user_existing_employment ? formik.errors.user_existing_employment : null
}
onBlur={formik.handleBlur("user_existing_employment")}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<PickerWithDynamicField
formik={formik}
fieldName="exploitation_date"
label={t("LoanRequest.operation_date")}
buttonLabel={t("LoanRequest.enter_operation_date")}
disabled={false}
errorText={!!(formik.touched.exploitation_date && formik.errors.exploitation_date)}
helperText={formik.touched.exploitation_date ? formik.errors.exploitation_date : null}
/>
</Grid>
<Grid item xs={12} sm={6}>
<PickerWithDynamicField
formik={formik}
fieldName="exploitation_license_renewal_date"
label={t("LoanRequest.refresh_date")}
buttonLabel={t("LoanRequest.enter_refresh_date")}
disabled={false}
errorText={
!!(
formik.touched.exploitation_license_renewal_date &&
formik.errors.exploitation_license_renewal_date
)
}
helperText={
formik.touched.exploitation_license_renewal_date
? formik.errors.exploitation_license_renewal_date
: null
}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ p: 2 }}>
<Grid item xs={12} sm={6}>
<Stack alignItems={"center"}>
<Typography
sx={{
fontSize: 14,
border: 1,
borderBottom: 0,
borderColor: "divider",
px: 2,
py: 1,
borderRadius: 2,
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
}}
>
{t("RefahiLoanRequest.upload_operating_license_img")}
</Typography>
<UploadImage formik={formik} fieldName={"exploitation_license_image"} />
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack alignItems={"center"}>
<Typography
sx={{
fontSize: 14,
border: 1,
borderBottom: 0,
borderColor: "divider",
px: 2,
py: 1,
borderRadius: 2,
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
}}
>
{t("RefahiLoanRequest.upload_refresh_date_img")}
</Typography>
<UploadImage formik={formik} fieldName={"exploitation_license_renewal_image"} />
</Stack>
</Grid>
</Grid>
<Grid container sx={{ padding: 2 }}>
<Grid item xs={12}>
<FormControlLabel
control={
<Checkbox
checked={formik.values.facility_usage_history}
onChange={(event) => {
formik.setFieldValue("facility_usage_history", event.target.checked);
}}
/>
}
label={`${t("LoanRequest.history_facilities")}`}
/>
</Grid>
</Grid>
<Grid container spacing={2} sx={{ padding: 2 }}>
<Grid item xs={12}>
<FormControlLabel
control={
<Checkbox
checked={formik.values.checkedBox}
onChange={(event) => {
formik.setFieldValue("checkedBox", event.target.checked);
}}
onBlur={formik.handleBlur("checkedBox")}
/>
}
label={`${t("LoanRequest.checkbox")}`}
/>
<FormHelperText sx={{ color: "error.main" }}>
{formik.touched.checkedBox && formik.errors.checkedBox ? formik.errors.checkedBox : null}
</FormHelperText>
</Grid>
</Grid>
<Stack sx={{ mx: 5 }} spacing={2} direction={"row"} alignItems={"center"} justifyContent={"flex-end"}>
<Button
startIcon={<ExitToAppIcon />}
variant={"outlined"}
size={"large"}
color={"primary"}
onClick={handleBack}
>
{t("RefahiLoanRequest.back-button")}
</Button>
<Button
onClick={formik.handleSubmit}
endIcon={<BeenhereIcon />}
variant={"contained"}
size={"large"}
color={"primary"}
disabled={submitting}
>
{t("RefahiLoanRequest.submit-button")}
</Button>
</Stack>
</>
);
};
export default RestoreRequestDetail;

View File

@@ -0,0 +1,54 @@
import { useState } from "react";
import { Stack, ToggleButton, ToggleButtonGroup } from "@mui/material";
import RestoreRealPersonalInfo from "./RestoreRealPersonalInfo";
import RestoreLegalPersonalInfo from "./RestoreLegalPersonalInfo";
import { useTranslations } from "next-intl";
const RestoreToggleRealLegal = ({
state,
handleNext,
dispatch,
isLoadingProvinceList,
errorProvinceList,
provinceList,
}) => {
const t = useTranslations();
return (
<>
<Stack sx={{ width: "100%", my: 3 }} justifyContent={"center"} alignItems={"center"}>
<ToggleButtonGroup
color="primary"
value={state.person_type}
exclusive
onChange={(e, value) => {
if (value === null) return;
dispatch({ type: "SET_PERSON_TYPE", person_type: value });
}}
>
<ToggleButton value="real">{t("LoanRequest.real_person")}</ToggleButton>
<ToggleButton value="legal">{t("LoanRequest.legal_person")}</ToggleButton>
</ToggleButtonGroup>
</Stack>
{state.person_type === "real" ? (
<RestoreRealPersonalInfo
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
dispatch={dispatch}
handleNext={handleNext}
state={state}
/>
) : (
<RestoreLegalPersonalInfo
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
state={state}
dispatch={dispatch}
handleNext={handleNext}
/>
)}
</>
);
};
export default RestoreToggleRealLegal;

View File

@@ -0,0 +1,122 @@
import { useReducer, useState } from "react";
import { useTranslations } from "next-intl";
import * as React from "react";
import { Stack, Step, StepLabel, Stepper } from "@mui/material";
import RestoreProjectInfo from "./RestoreProjectInfo";
import RestoreRequestDetail from "./RestoreRequestDetail";
import RestoreToggleRealLegal from "./RestoreToggleRealLegal";
import useLimitedProvince from "@/lib/app/hooks/useLimitedProvince";
const _data = {
person_type: "real",
telephone_number: "",
activity_type_id: "",
refahi_type: 2,
requested_facility_amount: "",
person_share: "",
user_existing_employment: "",
user_committed_employment: "",
father_name: "",
gender: "",
welfare_complex_degree: "",
first_name: "",
last_name: "",
city_id: "",
project_city_id: "",
province_id: "",
project_province_id: "",
education_id: "",
occupation_id: "",
national_id: "",
national_serial_number: "",
national_card_tracking_code: "",
national_serial_number_or_tracking_code: "national_serial_number",
postal_code: "",
address: "",
birthday: "",
investment_amount: "",
exploitation_date: "",
exploitation_license_renewal_date: "",
project_axis: "",
project_kilometer_marker: "",
project_direction: "",
project_address: "",
exploitation_license_image: null,
exploitation_license_renewal_image: null,
checkedBox: false,
facility_usage_history: false,
company_register_date: "",
shenase_meli: "",
register_number: "",
company_name: "",
};
const reducer = (state, action) => {
switch (action.type) {
case "SET_PERSONAL_INFO":
return { ...state, ...action.personalInfo };
case "SET_PROJECT_INFO":
return { ...state, ...action.projectInfo };
case "SET_REQUEST_INFO":
return { ...state, ...action.requestInfo };
case "SET_PERSON_TYPE":
return { ...state, person_type: action.person_type };
default:
return state;
}
};
const RestoreForm = ({ setFinishRefahiLoanRequest }) => {
const t = useTranslations();
const [activeStep, setActiveStep] = useState(0);
const { provinceList, isLoadingProvinceList, errorProvinceList } = useLimitedProvince();
const [state, dispatch] = useReducer(reducer, _data);
const steps = [
t("RefahiLoanRequest.step_personal_info"),
t("RefahiLoanRequest.step_project_info"),
t("RefahiLoanRequest.step_contact_info"),
];
const handleNext = () => setActiveStep((prev) => prev + 1);
const handleBack = () => setActiveStep((prev) => prev - 1);
return (
<Stack>
<Stepper sx={{ my: 2 }} activeStep={activeStep} alternativeLabel>
{steps.map((label, index) => (
<Step key={index}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
{activeStep === 0 && (
<RestoreToggleRealLegal
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
state={state}
dispatch={dispatch}
handleNext={handleNext}
/>
)}
{activeStep === 1 && (
<RestoreProjectInfo
provinceList={provinceList}
isLoadingProvinceList={isLoadingProvinceList}
errorProvinceList={errorProvinceList}
state={state}
dispatch={dispatch}
handleBack={handleBack}
handleNext={handleNext}
/>
)}
{activeStep === 2 && (
<RestoreRequestDetail
state={state}
dispatch={dispatch}
handleBack={handleBack}
setFinishRefahiLoanRequest={setFinishRefahiLoanRequest}
/>
)}
</Stack>
);
};
export default RestoreForm;

View File

@@ -0,0 +1,46 @@
import { Button, Stack, Typography } from "@mui/material";
import { useTranslations } from "next-intl";
import { CenterLayout } from "@witel/webapp-builder";
import { useState } from "react";
import DoneIcon from "@mui/icons-material/Done";
import { NextLinkComposed } from "@witel/webapp-builder/dist/utils/linkRouting";
import SvgDone from "@/core/components/svgs/SvgDone";
import CheckRules from "./forms/CheckRules";
import RefahiLoanType from "./RefahiLoanType";
import RestoreForm from "./forms/RestoreForm";
import BuildForm from "./forms/BuildForm";
const AddRequestLoan = () => {
const t = useTranslations();
const [finishRefahiLoanRequest, setFinishRefahiLoanRequest] = useState(false);
const [rulesChecked, setRulesChecked] = useState(false);
const [refahiLoanType, setRefahiLoanType] = useState(null);
return (
<>
{finishRefahiLoanRequest ? (
<CenterLayout>
<SvgDone width={200} height={200} />
<Stack direction={"row"} spacing={0.7} sx={{ mb: 4 }}>
<Typography variant={"h5"} align={"center"}>
{t("LoanRequest.finish_loan_request")}
</Typography>
<DoneIcon color={"success"} />
</Stack>
<Button variant={"contained"} component={NextLinkComposed} to={"/dashboard/refahi/followUp-loan"}>
{t("LoanRequest.back_to_dashboard")}
</Button>
</CenterLayout>
) : !rulesChecked ? (
<CheckRules rulesChecked={rulesChecked} setRulesChecked={setRulesChecked} />
) : refahiLoanType === null ? (
<RefahiLoanType setRefahiLoanType={setRefahiLoanType} />
) : refahiLoanType === 0 ? (
<RestoreForm setFinishRefahiLoanRequest={setFinishRefahiLoanRequest} />
) : (
<BuildForm setFinishRefahiLoanRequest={setFinishRefahiLoanRequest} />
)}
</>
);
};
export default AddRequestLoan;

View File

@@ -0,0 +1,138 @@
import { FormControl, FormHelperText } from "@mui/material";
import Button from "@mui/material/Button";
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { faIR } from "@mui/x-date-pickers/locales";
import moment from "jalali-moment";
import { useState, useMemo } from "react";
function DynamicButtonField(props) {
const {
label,
id,
disabled,
InputProps: { ref } = {},
inputProps: { "aria-label": ariaLabel } = {},
error,
selectedDate,
buttonLabel,
onClick,
} = props;
return (
<Button
sx={{ width: "100%", padding: 0.8 }}
variant="outlined"
color={error ? "error" : "primary"}
id={id}
disabled={disabled}
ref={ref}
aria-label={ariaLabel}
onClick={onClick}
>
{selectedDate ? `${buttonLabel} : ${selectedDate}` : buttonLabel ? buttonLabel : label}
</Button>
);
}
function DynamicDatePicker({
formik,
fieldName,
label,
disabled,
minDate,
maxDate,
errorText,
helperText,
buttonLabel,
onChange,
}) {
const [open, setOpen] = useState(false);
const computedMinMaxDates = useMemo(() => {
const today = moment();
const min = minDate ? moment(minDate, "jYYYY-jMM-jDD").toDate() : null;
const max = maxDate ? moment(maxDate, "jYYYY-jMM-jDD").toDate() : null;
return { min, max };
}, [minDate, maxDate]);
const selectedDate = useMemo(() => {
if (formik.values[fieldName]) {
return moment(formik.values[fieldName]).locale("fa").format("YYYY/MM/DD");
}
return null;
}, [formik.values, fieldName]);
return (
<DatePicker
slots={{ field: DynamicButtonField }}
slotProps={{
field: {
setOpen,
selectedDate,
buttonLabel,
error: formik.touched[fieldName] && Boolean(formik.errors[fieldName]),
helperText: helperText || formik.errors[fieldName],
onClick: () => setOpen((prev) => !prev),
},
}}
label={label}
disabled={disabled}
disableFuture
open={open}
minDate={computedMinMaxDates.min}
maxDate={computedMinMaxDates.max}
value={formik.values[fieldName] ? formik.values[fieldName].toDate() : null}
onChange={(newValue) => {
const formattedValue = moment(newValue);
formik.setFieldValue(fieldName, formattedValue);
onChange?.(formattedValue);
}}
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
/>
);
}
export default function PickerWithDynamicField({
formik,
fieldName,
label,
disabled = false,
minDate,
maxDate,
buttonLabel,
errorText,
helperText,
}) {
return (
<FormControl variant="outlined" fullWidth size="small">
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={{
...faIR.components.MuiLocalizationProvider.defaultProps.localeText,
okButtonLabel: "تایید",
}}
>
<DynamicDatePicker
onChange={(newValue) => {
formik.setFieldValue(fieldName, moment(newValue));
}}
formik={formik}
fieldName={fieldName}
label={label}
disabled={disabled}
minDate={minDate}
maxDate={maxDate}
buttonLabel={buttonLabel}
errorText={errorText}
helperText={helperText}
/>
</LocalizationProvider>
<FormHelperText error={Boolean(formik.errors[fieldName])}>
{formik.touched[fieldName] && formik.errors[fieldName]}
</FormHelperText>
</FormControl>
);
}

View File

@@ -24,7 +24,8 @@ function ButtonField(props) {
sx={{ width: "100%", padding: 0.8 }}
variant="outlined"
color={
props.slotProps.formik.touched.company_date && Boolean(props.slotProps.formik.errors.company_date)
props.slotProps.formik.touched.company_register_date &&
Boolean(props.slotProps.formik.errors.company_register_date)
? "error"
: "primary"
}
@@ -50,7 +51,7 @@ function ButtonDatePicker(props) {
formik: props.formik,
field: { setOpen },
textField: {
helperText: props.formik.errors.company_date ? `${t("company_date")}` : null,
helperText: props.formik.errors.company_register_date ? `${t("company_date")}` : null,
},
}}
{...props}
@@ -74,18 +75,24 @@ const LegalPersonDatePicker = ({ formik, disabled }) => {
>
<ButtonDatePicker
label={
formik.values.company_date !== "" &&
formik.values.company_date?.locale("fa").format("YYYY/MM/DD")
formik.values.company_register_date !== "" &&
formik.values.company_register_date?.locale("fa").format("YYYY/MM/DD")
}
value={
formik.values.company_register_date !== ""
? formik.values.company_register_date?.toDate()
: null
}
value={formik.values.company_date !== "" ? formik.values.company_date?.toDate() : null}
formik={formik}
disabled={disabled}
onChange={(newValue) => {
formik.setFieldValue("company_date", moment(newValue));
formik.setFieldValue("company_register_date", moment(newValue));
}}
/>
</LocalizationProvider>
<FormHelperText>{formik.touched.company_date && formik.errors.company_date}</FormHelperText>
<FormHelperText>
{formik.touched.company_register_date && formik.errors.company_register_date}
</FormHelperText>
</FormControl>
);
};

View File

@@ -1,156 +1,95 @@
import { Box, Button, FormHelperText, TextField, Typography } from "@mui/material";
import { useTranslations } from "next-intl";
import Image from "next/image";
import { Box, Button, Paper, Typography } from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import DeleteForeverIcon from "@mui/icons-material/DeleteForever";
import { useRef, useState } from "react";
import { useRef } from "react";
const UploadSystem = ({
fieldName,
default_image,
helperText,
error,
setFieldValue,
imageAlt,
label,
enableDelete,
}) => {
const t = useTranslations();
const UploadSystem = ({ selectedImage, handleUploadChange, imageSize, fileType, showAddIcon }) => {
const fileInputRef = useRef(null);
const [selectedImage, setSelectedImage] = useState(default_image || "/images/upload-image.svg");
const [fileType, setFileType] = useState(null);
const [fileName, setFileName] = useState("");
// upload files
const handleUploadChange = (event) => {
const uploadedFile = event.target?.files?.[0];
if (uploadedFile) {
setSelectedImage(URL.createObjectURL(uploadedFile));
setFileType(uploadedFile.type);
setFileName(uploadedFile.name);
setFieldValue(fieldName, uploadedFile);
}
};
// end upload files
const uploadBoxStyle = error
? {
cursor: "pointer",
objectFit: "contain",
border: "1px dashed #d32f2f",
borderRadius: "5px",
padding: "5px",
}
: {
cursor: "pointer",
objectFit: "contain",
border: "1px dashed #e1e1e1",
borderRadius: "5px",
padding: "5px",
};
const handleClick = () => {
fileInputRef.current.click();
};
const handleDeleteImage = () => {
setselectedImage("/images/upload-image.svg");
setFieldValue(fieldname, null);
};
return (
<Box sx={{ my: 2 }}>
<Typography
margin={1}
sx={{
fontWeight: 500,
fontSize: "0.9rem",
color: "#a19d9d",
}}
textAlign="center"
>
{label}
</Typography>
<Box sx={{ position: "relative" }}></Box>
{selectedImage === "/images/upload-image.svg" || selectedImage === default_image ? (
<Image
src={selectedImage}
priority
alt={imageAlt}
width={200}
height={200}
onClick={handleClick}
style={uploadBoxStyle}
/>
) : fileType && fileType.startsWith("image/") ? (
<Image
src={selectedImage}
priority
alt={imageAlt}
width={200}
height={200}
onClick={handleClick}
style={uploadBoxStyle}
/>
) : (
<Box sx={{ width: "100%" }}>
{showAddIcon ? (
<Box
sx={{
display: "flex",
border: "1px dashed #e1e1e1",
cursor: "pointer",
borderRadius: "5px",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
width: "200px",
height: "200px",
border: 1,
borderColor: "divider",
borderRadius: 2,
cursor: "pointer",
padding: "5px",
height: imageSize[1],
}}
onClick={handleClick}
>
<AddIcon sx={{ fontSize: "2rem", color: "#a19d9d" }} />
<Typography
margin={2}
variant="subtitle2"
sx={{
fontWeight: 600,
fontSize: "1rem",
fontSize: "0.8rem",
color: "#a19d9d",
textAlign: "center",
display: "flex",
justifyContent: "end",
overflow: "hidden",
mt: 1,
}}
textAlign="center"
>
{fileName}
فرمت قابل قبول : png, jpg
<br />
حداکثر 2Mb
</Typography>
</Box>
) : (
<>
{fileType && fileType.startsWith("image/") && (
<Box
width="100%"
height={imageSize[1]}
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
cursor: "pointer",
objectFit: "contain",
border: "1px solid #b3b3b3",
borderRadius: "10px",
padding: "5px",
overflow: "hidden",
}}
onClick={handleClick}
>
<Paper
elevation={0}
sx={{
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundSize: "contain",
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
backgroundImage: `url(${selectedImage})`,
}}
/>
</Box>
)}
</>
)}
<TextField
id="avatar-upload"
<input
type="file"
accept="image/*"
style={{ display: "none" }}
onChange={(e) => handleUploadChange(e)}
inputRef={fileInputRef}
onChange={handleUploadChange}
ref={fileInputRef}
/>
{enableDelete ? (
<Button
sx={{
width: "100%",
borderTopLeftRadius: "unset",
borderTopRightRadius: "unset",
}}
color="error"
disabled={selectedImage === "/images/upload-image.svg"}
endIcon={<DeleteForeverIcon />}
variant="contained"
onClick={handleDeleteImage}
>
{t("delete")}
</Button>
) : (
""
)}
<FormHelperText sx={{ color: "#d32f2f" }}>{helperText}</FormHelperText>
</Box>
);
};
export default UploadSystem;

View File

@@ -0,0 +1,40 @@
import DangerousIcon from "@mui/icons-material/Dangerous";
import { Box, Typography } from "@mui/material";
import { toast } from "react-toastify";
const UploadFileNotification = (t) => {
toast(
({ closeToast }) => (
<>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "start",
justifyContent: "start",
}}
>
<Box sx={{ display: "flex", alignItems: "center" }}>
<DangerousIcon color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography color="error" variant="button">
{t("UploadSystem.uploadfile_error")}
</Typography>
</Box>
</Box>
</Box>
</>
),
{
containerId: "validation",
toastId: "upload",
autoClose: 3000,
hideProgressBar: true,
pauseOnHover: true,
closeOnClick: false,
draggable: true,
}
);
};
export default UploadFileNotification;

View File

@@ -27,3 +27,4 @@ export const UPDATE_LOAN = BASE_URL + "/navgan/loan/update/";
export const GET_PROJECT_TITLE = BASE_URL + "/navgan_plans";
export const GET_ACTIVITY_LIST = BASE_URL + "/activity_types";
export const GET_PRIORITY_LIST = BASE_URL + "/activity_priorities";
export const SEND_LOAN_REQUEST_REFAHI = BASE_URL + "/refahi/loan/store";

View File

@@ -1,6 +1,7 @@
import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard";
import BookmarkAddedIcon from "@mui/icons-material/BookmarkAdded";
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
const sidebarMenu = [
[
@@ -14,19 +15,30 @@ const sidebarMenu = [
permission: "all",
},
{
key: "sidebar.add-request-loan",
name: "sidebar.add-request-loan",
key: "sidebar.add-request-navgan-loan",
name: "sidebar.add-request-navgan-loan",
secondary: "secondary.navgan",
type: "page",
route: "/dashboard/navgan/add-request-loan",
icon: <DataSaverOnIcon sx={{ width: "inherit", height: "inherit" }} />,
icon: <DirectionsCarIcon sx={{ width: "inherit", height: "inherit" }} />,
selected: false,
permission: "can_request_navgan_loan",
},
{
key: "sidebar.add-request-refahi-loan",
name: "sidebar.add-request-refahi-loan",
secondary: "secondary.refahi",
type: "page",
route: "/dashboard/refahi/add-request-loan",
icon: <VolunteerActivismIcon sx={{ width: "inherit", height: "inherit" }} />,
selected: false,
permission: "can_request_refahi_loan",
},
{
key: "sidebar.followUp-loan",
name: "sidebar.followUp-loan",
type: "page",
route: "/dashboard/navgan/followUp-loan",
route: "/dashboard/followUp-loan",
icon: <BookmarkAddedIcon sx={{ width: "inherit", height: "inherit" }} />,
selected: false,
permission: "all",

View File

@@ -3,7 +3,7 @@ import { useRequest } from "@witel/webapp-builder";
import { useEffect, useState } from "react";
const useLimitedProvince = () => {
const [isLoadingProvinceList, setIsLoadingProvinceList] = useState(false);
const [isLoadingProvinceList, setIsLoadingProvinceList] = useState(true);
const [errorProvinceList, setErrorProvinceList] = useState(false);
const [provinceList, setProvinceList] = useState([]);
const requestServer = useRequest({ auth: true, notification: false });

View File

@@ -1,18 +1,23 @@
import { CenterLayout, FullPageLayout, useConfig } from "@witel/webapp-builder";
import { CenterLayout, FullPageLayout } from "@witel/webapp-builder";
import moment from "jalali-moment";
import SvgMaintenance from "@/core/components/svgs/SvgMaintenance";
import { Typography } from "@mui/material";
import { useTranslations } from "next-intl";
const RegisterDeadlineMiddleware = ({ children, serverToday }) => {
const { config } = useConfig();
const RegisterDeadlineMiddleware = ({
children,
serverToday,
registration_start_date,
registration_end_date,
registration_status,
}) => {
const t = useTranslations();
const fromDate = moment(config.navgan_registration_start_date, "YYYY/MM/DD HH:mm:ss");
const toDate = moment(config.navgan_registration_end_date, "YYYY/MM/DD HH:mm:ss");
const fromDate = moment(registration_start_date, "YYYY/MM/DD HH:mm:ss");
const toDate = moment(registration_end_date, "YYYY/MM/DD HH:mm:ss");
const today = moment(serverToday);
if (config.navgan_registration_status) {
if (registration_status) {
if (today.isBetween(fromDate, toDate, null, "[]")) {
return children;
} else if (today.isAfter(toDate, null)) {

View File

@@ -1,4 +1,4 @@
import LoanFollowUpComponent from "@/components/dashboard/navgan/followUp-loan";
import LoanFollowUpComponent from "src/components/dashboard/followUp-loan";
import { globalServerProps } from "@/core/utils/globalServerProps";
export default function FollowUpLoan() {
@@ -9,7 +9,7 @@ export async function getServerSideProps({ req, locale }) {
return {
props: {
...(await globalServerProps({ req, locale })),
title: "LoanRequest.loan_request_page",
title: "LoanFollowUp.loan_follow_up_page",
layout: { name: "DashboardLayout" },
},
};

View File

@@ -1,10 +1,17 @@
import LoanRequestComponent from "@/components/dashboard/navgan/add-request-loan";
import { globalServerProps } from "@/core/utils/globalServerProps";
import RegisterDeadlineMiddleware from "@/middlewares/RegisterDeadline";
import { useConfig } from "@witel/webapp-builder";
export default function AddLoanRequest(props) {
const { config } = useConfig();
return (
<RegisterDeadlineMiddleware serverToday={props.today}>
<RegisterDeadlineMiddleware
registration_start_date={config.navgan_registration_start_date}
registration_end_date={config.navgan_registration_end_date}
registration_status={config.navgan_registration_status}
serverToday={props.today}
>
<LoanRequestComponent />
</RegisterDeadlineMiddleware>
);

View File

@@ -0,0 +1,28 @@
import LoanRequestComponent from "@/components/dashboard/refahi/add-request-loan";
import { globalServerProps } from "@/core/utils/globalServerProps";
import RegisterDeadlineMiddleware from "@/middlewares/RegisterDeadline";
import { useConfig } from "@witel/webapp-builder";
export default function AddLoanRequest(props) {
const { config } = useConfig();
return (
<RegisterDeadlineMiddleware
registration_start_date={config.refahi_registration_start_date}
registration_end_date={config.refahi_registration_end_date}
registration_status={config.refahi_registration_status}
serverToday={props.today}
>
<LoanRequestComponent />
</RegisterDeadlineMiddleware>
);
}
export async function getServerSideProps({ req, locale }) {
return {
props: {
...(await globalServerProps({ req, locale })),
title: "LoanRequest.loan_request_page",
layout: { name: "DashboardLayout", props: { permissions: ["can_request_refahi_loan"] } },
},
};
}