diff --git a/package.json b/package.json
index f5cf4ed..18812a0 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,10 @@
"@mui/lab": "^5.0.0-alpha.152",
"@mui/material": "^5.12.0",
"@witel/webapp-builder": "^1.2.3",
+ "@mui/x-date-pickers": "^6.18.5",
"axios": "^1.4.0",
"colord": "^2.9.3",
+ "date-fns-jalali": "^2.13.0-0",
"eslint": "8.36.0",
"formik": "^2.2.9",
"fs-extra": "^11.1.1",
diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json
index 950e384..c6999fb 100644
--- a/public/locales/fa/app.json
+++ b/public/locales/fa/app.json
@@ -1,7 +1,14 @@
{
"app_name": "سامانه جامع تسهیلات",
"app_short_name": "سامانه تسهیلات",
+ "birthday": "تاریخ تولد",
+ "birthday_error": "تاریخ تولد خود را وارد کنید!",
"dashboard": "داشبورد",
+ "text_field_city_id": "شهر",
+ "text_field_error_fetching_cities": "لطفا شهر خود را وارد کنید!",
+ "text_field_loading_cities_list": "درحال دریافت اطلاعات شهر ها...",
+ "text_field_loading": "درحال دریافت اطلاعات",
+ "text_field_error_fetching": "خطا در دریافت اطلاعات",
"first_page": "خوش آمدید",
"powered_by_witel": "توسعه یافته توسط وایتل",
"login": "ورود",
@@ -20,6 +27,7 @@
"online_message": "شما به اینترنت وصل هستید",
"offline_message": "اتصال شما به اینترنت قطع شده است",
"routing_to": "در حال انتقال به صفحه",
+ "error_message_plate_number": "لطفا شماره پلاک خود را وارد کنید!",
"header": {
"open_profile": "پروفایل",
"edit_profile": "ویرایش پروفایل",
@@ -132,48 +140,74 @@
"loan_details": "نمایش"
},
"LoanRequest": {
+ "finish_loan_request": "درخواست شما با موفقیت ثبت شد",
+ "button_while_submit": "درحال بارگذاری ...",
+ "checkbox": "بدینوسیله صحت کلیه اطلاعات مندرج در این فرم را تایید و گواهی میدهم .",
+ "back_to_dashboard": "پیگیری درخواست ها",
+ "cityList_empty": "ابتدا استان را وارد کنید",
+ "cityList_loading": "درحال دریافت لیست شهر ها ...",
"loan_request_page": "ثبت درخواست وام",
"personal_info": "اطلاعات شخصی",
+ "national_code_number": "کد ملی می بایست شامل اعداد باشد",
+ "national_code_max": "کد ملی می بایست 10 رقم باشد",
+ "shenasname_serial_max": "سریال پشت کارت ملی می بایست شامل 10 بخش باشد",
+ "postal_code_max": "کد پستی می بایست 10 رقم باشد",
+ "tel_number_max": "شماره ثابت می بایست 11 رقم باشد",
+ "national_code_positive": "کد ملی می بایست مثبت باشد",
"uploading_documents": "اسناد",
"error_message_name": "لطفا نام خود را وارد کنید!",
- "error_message_phone_number": "لطفا شماره تلفن خود را وارد کنید!",
+ "error_message_plate_number": "لطفا شماره پلاک را به درستی وارد کنید!",
+ "error_message_occupation_id": "لطفا کد شغل را به درستی وارد کنید!",
+ "error_message_education_id": "لطفا تحصیلات را به درستی وارد کنید!",
+ "error_message_tel_number": "لطفا شماره ثابت (با پیش شماره استان) خود را وارد کنید!",
"error_message_vehicle_type": "لطفا نوع وسیله نقلیه خود را وارد کنید!",
- "error_message_plate_number": "لطفا شماره پلاک خود را وارد کنید!",
- "error_message_navgan_id": "لطفا کد ناوگان خود را وارد کنید!",
+ "error_message_navgan_id": "لطفا کد هوشمند ناوگان خود را وارد کنید!",
"error_message_province_id": "لطفا استان خود را وارد کنید!",
"error_message_national_id": "لطفا کد ملی خود را وارد کنید!",
- "error_message_shenasname_id": "لطفا شماره شناسنامه خود را وارد کنید!",
- "text_field_phone_number": "شماره تلفن",
- "text_field_enter_your_phone_number": "شماره تلفن خود را وارد کنید",
+ "error_message_date_of_birth": "لطفا تاریخ تولد خود را وارد کنید!",
+ "error_message_shenasname_serial": "لطفا سریال پشت کارت ملی خود را وارد کنید!",
+ "error_message_postal_code": "لطفا کد پستی خود را وارد کنید!",
+ "error_message_national_code": "لطفا کد ملی خود را وارد کنید!",
+ "error_message_checkedBox": "لطفا کد صحت اطلاعات خود را تایید کنید!",
+ "error_message_navgan_type": "لطفا نوع ناوگان خود را وارد کنید!",
+ "error_message_address": "لطفا آدرس خود را وارد کنید!",
+ "text_field_tel_number": "شماره ثابت (با پیش شماره استان)",
+ "text_field_education_id": "تحصیلات",
+ "text_field_occupation_id": "شغل",
+ "text_field_enter_your_tel_number": "شماره ثابت (با پیش شماره استان) خود را وارد کنید",
"text_field_name": "نام",
+ "text_field_plate_part4": "بخش چهارم",
+ "text_field_plate_part3": "بخش سوم",
+ "text_field_plate_part2": "بخش دوم",
+ "text_field_plate_part1": "بخش اول",
+ "text_field_postal_code": "کد پستی",
+ "text_field_navgan_type": "نوع ناوگان",
+ "text_field_address": "آدرس",
+ "text_field_enter_your_plate_part1": "بخش اول پلاک را وارد کنید",
+ "text_field_enter_your_plate_part2": "بخش دوم پلاک را وارد کنید",
+ "text_field_enter_your_plate_part3": "بخش سوم پلاک را وارد کنید",
+ "text_field_enter_your_plate_part4": "بخش چهارم پلاک راوارد کنید",
+ "text_field_enter_your_address": "آدرس خود راوارد کنید",
"text_field_enter_your_name": "نام خود را وارد کنید",
- "text_field_vehicle_type": "نام وسیله نقلیه",
- "text_field_enter_your_vehicle_type": "نام وسیله نقلیه خود را وارد کنید",
+ "text_field_enter_your_postal_code": "کد پستی خود را وارد کنید",
+ "text_field_vehicle_type": "نوع وسیله نقلیه",
+ "text_field_enter_your_vehicle_type": "نوع وسیله نقلیه خود را وارد کنید",
"text_field_province_id": "استان",
- "text_field_loading_provinces_list": "درحال دریافت استان ها",
+ "text_field_loading_provinces_list": "درحال دریافت استان ها ...",
"text_field_error_fetching_provinces": "خطا در دریافت استان ها",
+ "text_field_enter_your_national_code": "کد ملی خود را وارد کنید",
"text_field_enter_your_province_id": "استان خود را وارد کنید",
- "text_field_navgan_id": "شماره ناوگان",
- "text_field_enter_your_navgan_id": "شماره ناوگان خود را وارد کنید",
+ "text_field_enter_your_city_id": "شهر خود را وارد کنید",
+ "text_field_navgan_id": "کد هوشمند ناوگان",
+ "text_field_enter_your_navgan_id": "کد هوشمند ناوگان خود را وارد کنید",
"text_field_national_code": "کد ملی",
"text_field_enter_your_national_id": "کد ملی خود را وارد کنید",
- "text_field_shenasname_id": "شماره شناسنامه",
- "text_field_enter_your_shenasname_id": "شماره شناسنامه خود را وارد کنید",
+ "text_field_shenasname_serial": "سریال پشت کارت ملی",
+ "text_field_enter_your_shenasname_serial": "سریال پشت کارت ملی خود را وارد کنید",
"text_field_plate_number": "شماره پلاک",
"text_field_enter_your_plate_number": "شماره پلاک خود را وارد کنید",
"button_submit": "ثبت درخواست",
- "file_field_sherkat_naft_doc": "مجوز شرکت نفت",
- "file_field_estate_doc": "سند مالکیت",
- "file_field_agreement_doc": "موافقت نامه اصولی",
- "error_message_sherkat_naft_doc": "مجوز شرکت نفت خود را وارد کنید",
- "error_message_estate_doc": "سند مالکیت خود را وارد کنید",
- "error_message_agreement_doc": "موافقت نامه اصولی خود را وارد کنید",
- "file_field_shenasname_image": "تصویر شناسنامه",
- "file_field_national_card_image": "تصویر کارت ملی",
- "file_field_payan_khedmat_image": "تصویر کارت پایان خدمت",
- "error_message_national_card_image": "تصویر کارت ملی خود را وارد کنید",
- "error_message_shenasname_image": "تصویر شناسنامه خود را وارد کنید",
- "error_message_payan_khedmat_image": "تصویر کارت پایان خدمت خود را وارد کنید",
+ "error_message_city_id": "لطفا شهر خود را وارد کنید!",
"add_loan_request_permission": "اکنون امکان ثبت درخواست جدید برای شما مقدور نیست"
},
"EditLoanRequest": {
diff --git a/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx b/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx
index df79a4c..6d9f9bc 100644
--- a/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx
+++ b/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx
@@ -1,463 +1,471 @@
-import Notifications from "@/core/components/notifications";
import SelectBox from "@/core/components/SelectBox";
-import StyledForm from "@/core/components/StyledForm";
-import UploadSystem from "@/core/components/UploadSystem";
-import {GET_PROVINCE_LIST, SEND_LOAN_REQUEST_NAVGAN,} from "@/core/data/apiRoutes";
-import useDirection from "@/lib/app/hooks/useDirection";
-import useUser from "@/lib/app/hooks/useUser";
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
-import {Box, Button, Stack, TextField} from "@mui/material";
-import axios from "axios";
-import {Field, Formik} from "formik";
+import {Box, Button, Checkbox, FormControlLabel, Grid, Stack, TextField, Typography} from "@mui/material";
+import {useFormik} from "formik";
import {useTranslations} from "next-intl";
-import {useEffect, useState} from "react";
import * as Yup from "yup";
+import {CenterLayout, useRequest} from "@witel/webapp-builder";
+import useProvince from "@/lib/app/hooks/useProvince";
+import useCities from "@/lib/app/hooks/useCities";
+import PlateNumber from "@/core/components/PlateNumber";
+import MuiDatePicker from "@/core/components/MuiDatePicker";
+import UseEducations from "@/lib/app/hooks/useEducations";
+import useOccupations from "@/lib/app/hooks/useOccupations";
+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 {SEND_LOAN_REQUEST_NAVGAN} from "@/core/data/apiRoutes";
const AddFormComponent = () => {
const t = useTranslations();
- const {directionApp} = useDirection();
- const {token} = useUser();
+ const [finishLoanRequest, setFinishLoanRequest] = useState(false)
+ const [checked, setChecked] = useState(false);
+ const requestServer = useRequest()
+ const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince()
+ const {cityTextField, cityList, setProvinceID, isLoadingCityList} = useCities()
+ const {educationsList, isLoadingEducationsList, errorEducationsList} = UseEducations()
+ const {occupationsList, isLoadingOccupationsList, errorOccupationsList} = useOccupations()
- // get province list
- const [provinceList, setProvinceList] = useState([]);
- useEffect(() => {
- axios
- .get(GET_PROVINCE_LIST, {
- headers: {Authorization: `Bearer ${token}`},
- })
- .then(({data}) => {
- const formattedData = data.map((province, index) => ({
- id: index,
- name: province.name,
- value: province.id,
- }));
- setProvinceList(formattedData);
- })
- .catch((error) => {
- Notifications(t, error.response);
- });
- }, []);
- // end get province list
-
- // upload files
- const [selectedImageShenasname, setSelectedImageShenasname] = useState(
- "/images/upload-image.svg"
- );
- const [fileTypeShenasname, setFileTypeShenasname] = useState(null);
- const [fileNameShenasname, setFileNameShenasname] = useState(null);
- const [selectedImageNationalCard, setSelectedImageNationalCard] = useState(
- "/images/upload-image.svg"
- );
- const [fileTypeNationalCard, setFileTypeNationalCard] = useState(null);
- const [fileNameNationalCard, setFileNameNationalCard] = useState(null);
-
- const handleUploadChangeShenasname = (event, setFieldValue) => {
- const uploadedFile = event.target?.files?.[0];
- if (uploadedFile) {
- const fileType = event.target?.files?.[0].type;
- const fileName = event.target?.files?.[0].name;
- setSelectedImageShenasname(URL.createObjectURL(uploadedFile));
- setFileTypeShenasname(fileType);
- setFileNameShenasname(fileName);
- setFieldValue("shenasname_img", uploadedFile);
- }
- };
- const handleUploadChangeNationalCard = (event, setFieldValue) => {
- const uploadedFile = event.target?.files?.[0];
- const fileType = event.target.files[0].type;
- const fileName = event.target.files[0].name;
- if (uploadedFile) {
- setSelectedImageNationalCard(URL.createObjectURL(uploadedFile));
- setFileTypeNationalCard(fileType);
- setFileNameNationalCard(fileName);
- setFieldValue("national_card_img", uploadedFile);
- }
- };
- // end upload files
-
- // initial values
const initialValues = {
- name: "",
- phone_number: "",
+ telephone_number: "",
vehicle_type: "",
- plate_number: "",
province_id: "",
+ city_id: "",
navgan_id: "",
- national_code: "",
- shenasname_id: "",
- national_card_img: null,
- shenasname_img: null,
+ national_id: "",
+ national_serial_number: "",
+ postal_code: "",
+ navgan_type: "",
+ plate_part1: "",
+ plate_part2: "الف",
+ plate_part3: "",
+ plate_part4: "",
+ address: "",
+ birthday: "",
+ education_id: "",
+ occupation_id: "",
+ checkedBox: false
};
- // end initial values
- // validation
const validationSchema = Yup.object().shape({
- name: Yup.string().required(t("LoanRequest.error_message_name")),
- phone_number: Yup.string().required(
- t("LoanRequest.error_message_phone_number")
- ),
+ 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")),
vehicle_type: Yup.string().required(
t("LoanRequest.error_message_vehicle_type")
),
- plate_number: Yup.string().required(
- t("LoanRequest.error_message_plate_number")
+ navgan_type: Yup.string().required(
+ t("LoanRequest.error_message_navgan_type")
),
- navgan_id: Yup.string().required(t("LoanRequest.error_message_navgan_id")),
+ 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")
+ ),
+ 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")
+ ),
+ plate_part1: Yup.mixed().test("max", `${t("LoanRequest.error_message_plate_number")}`, (value) => value.toString().length === 2)
+ .required(
+ t("LoanRequest.error_message_plate_number")
+ ),
+ plate_part2: Yup.mixed()
+ .required(
+ t("LoanRequest.error_message_plate_number")
+ ),
+ plate_part3: Yup.mixed().test("max", `${t("LoanRequest.error_message_plate_number")}`, (value) => value.toString().length === 3)
+ .required(
+ t("LoanRequest.error_message_plate_number")
+ ),
+ plate_part4: Yup.mixed().test("max", `${t("LoanRequest.error_message_plate_number")}`, (value) => value.toString().length === 2)
+ .required(
+ t("LoanRequest.error_message_plate_number")
+ ),
+ navgan_id: Yup.mixed().required(t("LoanRequest.error_message_navgan_id")),
province_id: Yup.string().required(t("LoanRequest.error_message_province_id")),
- national_code: Yup.string().required(
- t("LoanRequest.error_message_national_code")
- ),
- shenasname_id: Yup.string().required(
- t("LoanRequest.error_message_shenasname_id")
- ),
+ city_id: Yup.string().required(t("LoanRequest.error_message_city_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().required(t("LoanRequest.error_message_shenasname_serial")),
});
- // end validation
- // submit
+
const handleSubmit = async (values, props) => {
- Notifications(t, undefined);
- const formData = new FormData();
- formData.append("name", values.name);
- formData.append("phone_number", values.phone_number);
- formData.append("vehicle_type", values.vehicle_type);
- formData.append("plate_number", values.plate_number);
- formData.append("province_id", values.province_id);
- formData.append("navgan_id", values.navgan_id);
- formData.append("national_code", values.national_code);
- formData.append("shenasname_id", values.shenasname_id);
- if (values.shenasname_img != null)
- formData.append("shenasname_image", values.shenasname_img);
- if (values.national_card_img != null)
- formData.append("national_card_image", values.national_card_img);
+ props.setSubmitting(true)
- await axios
- .post(SEND_LOAN_REQUEST_NAVGAN, formData, {
- headers: {
- Authorization: `Bearer ${token}`,
- "Content-Type": "multipart/form-data",
- },
- })
- .then(function (response) {
- Notifications(t, response);
- })
- .catch(function (error) {
- Notifications(t, error.response);
- props.setSubmitting(false);
- });
+ await requestServer(SEND_LOAN_REQUEST_NAVGAN, "post", {
+ auth: true, notification: true, data: {
+ telephone_number: values.telephone_number,
+ vehicle_type: values.vehicle_type,
+ province_id: values.province_id,
+ city_id: values.city_id,
+ navgan_id: values.navgan_id,
+ national_id: values.national_id,
+ national_serial_number: values.national_serial_number,
+ postal_code: values.postal_code,
+ navgan_type: values.navgan_type,
+ plate_part1: values.plate_part1,
+ plate_part2: values.plate_part2,
+ plate_part3: values.plate_part3,
+ plate_part4: values.plate_part4,
+ address: values.address,
+ birthday: values.birthday.locale('en').format("YYYY-MM-DD"),
+ education_id: values.education_id,
+ occupation_id: values.occupation_id,
+ }
+ }).then(() => {
+ setFinishLoanRequest(true)
+ }).catch(() => {
+ }).finally(() => {
+ props.setSubmitting(false)
+ })
};
- // end submit
+
+ const formik = useFormik({
+ initialValues, validationSchema, onSubmit: handleSubmit
+ })
return (
-
- {(props) => (
-
-
-
+ {finishLoanRequest ?
+ (
+
+
+
+ {t("LoanRequest.finish_loan_request")}
+
+
+
+
+ ) : (
+ <>
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
- handleUploadChangeShenasname(e, props.setFieldValue)
- }
- setselectedImage={setSelectedImageShenasname}
- setFieldValue={props.setFieldValue}
- fieldname="shenasname_img"
- fileType={fileTypeShenasname}
- fileName={fileNameShenasname}
- imageAlt={t("app_name")}
- imageSize={[300 /*width*/, 150 /*height*/]}
- label={t("LoanRequest.file_field_shenasname_image")}
- />
-
- handleUploadChangeNationalCard(e, props.setFieldValue)
- }
- setselectedImage={setSelectedImageNationalCard}
- setFieldValue={props.setFieldValue}
- fieldname="national_card_img"
- fileType={fileTypeNationalCard}
- fileName={fileNameNationalCard}
- imageAlt={t("app_name")}
- imageSize={[300 /*width*/, 150 /*height*/]}
- label={t("LoanRequest.file_field_national_card_image")}
- />
-
+
+
+
+
+
+
+
+
+
+
+ {
+ 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}
+ />
+
+
+
+
+ {
+ formik.setFieldValue('navgan_type', event.target.value)
+ }}
+ setFieldTouched={formik.setFieldTouched}
+ error={formik.touched.navgan_type && Boolean(formik.errors.navgan_type)}
+ helperText={formik.touched.navgan_type && formik.errors.navgan_type}
+ onBlur={formik.handleBlur("navgan_type")}
+ />
+
+
+
+
+
+
+
+ {
+ formik.setFieldValue('province_id', event.target.value);
+ setProvinceID(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")}
+ />
+
+
+ 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")}
+ />
+
+
+
+
+ formik.setFieldValue('vehicle_type', event.target.value)}
+ error={formik.touched.vehicle_type && Boolean(formik.errors.vehicle_type)}
+ helperText={formik.touched.vehicle_type && formik.errors.vehicle_type}
+ onBlur={formik.handleBlur("vehicle_type")}
+ />
+
+
+
+
+
+
+
+ {
+ 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")}
+ />
+
+
+ {
+ 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")}
+ />
+
+
+
+
+
+
+
+
+
+ {
+ formik.setFieldValue("checkedBox", event.target.checked)
+ }}
+ />
+ }
+ label={`${t("LoanRequest.checkbox")}`}/>
+
+
+
{
>
-
-
- )}
-
+ >
+ )
+ }
+ >
);
};
diff --git a/src/components/dashboard/navgan/add-request-loan/index.jsx b/src/components/dashboard/navgan/add-request-loan/index.jsx
index cd9d359..395ede7 100644
--- a/src/components/dashboard/navgan/add-request-loan/index.jsx
+++ b/src/components/dashboard/navgan/add-request-loan/index.jsx
@@ -1,29 +1,21 @@
-import CenterLayout from "@/layouts/CenterLayout";
-import DashboardLayouts from "@/layouts/dashboardLayouts";
-import useUser from "@/lib/app/hooks/useUser";
import {Box, Chip, Divider} from "@mui/material";
import {useTranslations} from "next-intl";
import AddFormComponent from "@/components/dashboard/navgan/add-request-loan/forms/AddForm";
const LoanRequestComponent = () => {
const t = useTranslations();
- const {user} = useUser();
return (
-
-
-
+ <>
+
-
-
+ >
);
};
diff --git a/src/components/login/SendUserData.jsx b/src/components/login/SendUserData.jsx
index d791869..cc64ba3 100644
--- a/src/components/login/SendUserData.jsx
+++ b/src/components/login/SendUserData.jsx
@@ -95,6 +95,21 @@ const SendUserDataComponent = ({
flexDirection: {xs: "column-reverse", sm: "row"},
}}
>
+
+
+
+
+
+
+
diff --git a/src/components/register/RequestOtp.jsx b/src/components/register/RequestOtp.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/register/index.jsx b/src/components/register/index.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/register/navy/UserRegister.jsx b/src/components/register/navy/UserRegister.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/core/components/MuiDatePicker.jsx b/src/core/components/MuiDatePicker.jsx
new file mode 100644
index 0000000..accc7af
--- /dev/null
+++ b/src/core/components/MuiDatePicker.jsx
@@ -0,0 +1,87 @@
+import * as React from 'react';
+import {useState} from 'react';
+import Button from '@mui/material/Button';
+import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali";
+import {LocalizationProvider} from '@mui/x-date-pickers/LocalizationProvider';
+import {DatePicker} from '@mui/x-date-pickers/DatePicker';
+import {useTranslations} from "next-intl";
+import moment from "jalali-moment";
+import {FormControl, FormHelperText} from "@mui/material";
+
+function ButtonField(props) {
+ const t = useTranslations();
+ const {
+ setOpen,
+ label,
+ id,
+ disabled,
+ InputProps: {ref} = {},
+ inputProps: {'aria-label': ariaLabel} = {},
+ } = props;
+
+ return (
+
+ );
+}
+
+function ButtonDatePicker(props) {
+ const t = useTranslations();
+ const [open, setOpen] = useState(false);
+
+ return (
+ setOpen(false)}
+ onOpen={() => setOpen(true)}
+ />
+ );
+}
+
+export default function PickerWithButtonField({formik, disabled}) {
+ return (
+
+
+ {
+ formik.setFieldValue("birthday", moment(newValue))
+ }}
+
+ />
+
+ {formik.touched.birthday && formik.errors.birthday}
+
+ );
+}
\ No newline at end of file
diff --git a/src/core/components/PlateNumber.jsx b/src/core/components/PlateNumber.jsx
new file mode 100644
index 0000000..5d28fcb
--- /dev/null
+++ b/src/core/components/PlateNumber.jsx
@@ -0,0 +1,236 @@
+import {Box, Button, Drawer, FormHelperText, Stack, TextField} from "@mui/material";
+import {useTranslations} from "next-intl";
+import AccessibleIcon from '@mui/icons-material/Accessible';
+import {useState} from "react";
+
+const plate_words = [
+ {
+ id: 1,
+ value: "الف",
+ name: "الف"
+ },
+ {
+ id: 2,
+ value: "ب",
+ name: "ب"
+ },
+ {
+ id: 3,
+ value: "پ",
+ name: "پ"
+ },
+ {
+ id: 4,
+ value: "ت",
+ name: "ت"
+ },
+ {
+ id: 5,
+ value: "ث",
+ name: "ث"
+ },
+ {
+ id: 6,
+ value: "ج",
+ name: "ج"
+ },
+ {
+ id: 7,
+ value: "د",
+ name: "د"
+ },
+ {
+ id: 8,
+ value: "ز",
+ name: "ز"
+ },
+ {
+ id: 9,
+ value: "س",
+ name: "س"
+ },
+ {
+ id: 10,
+ value: "ش",
+ name: "ش"
+ },
+ {
+ id: 11,
+ value: "ص",
+ name: "ص"
+ },
+ {
+ id: 12,
+ value: "ط",
+ name: "ط"
+ },
+ {
+ id: 13,
+ value: "ع",
+ name: "ع"
+ },
+ {
+ id: 14,
+ value: "ف",
+ name: "ف"
+ },
+ {
+ id: 15,
+ value: "ق",
+ name: "ق"
+ },
+ {
+ id: 16,
+ value: "ک",
+ name: "گ"
+ },
+ {
+ id: 17,
+ value: "ل",
+ name: "ل"
+ },
+ {
+ id: 18,
+ value: "م",
+ name: "م"
+ },
+ {
+ id: 19,
+ value: "ن",
+ name: "ن"
+ },
+ {
+ id: 20,
+ value: "و",
+ name: "و"
+ },
+ {
+ id: 21,
+ value: "ه",
+ name: "ه"
+ },
+ {
+ id: 22,
+ value: "ی",
+ name: "ی"
+ },
+ {
+ id: 23,
+ value: "*",
+ name:
+ },
+]
+const PlateNumber = ({formik, disabled}) => {
+ const t = useTranslations();
+ const [plateDrawer, setPlateDrawer] = useState(false);
+ const isErrorPlate = Boolean(formik.errors.plate_part1 || formik.errors.plate_part3 || formik.errors.plate_part4)
+ const isTouched = (formik.touched.plate_part1 || formik.touched.plate_part3 || formik.touched.plate_part4)
+ return (
+ <>
+
+ event.target.value.length <= 2 ? formik.setFieldValue("plate_part4", event.target.value) : null}
+ onBlur={formik.handleBlur}
+ error={formik.touched.plate_part4 && Boolean(formik.errors.plate_part4)}
+ />
+ event.target.value.length <= 3 ? formik.setFieldValue("plate_part3", event.target.value) : null}
+ onBlur={formik.handleBlur}
+ error={formik.touched.plate_part3 && Boolean(formik.errors.plate_part3)}
+ />
+
+
+
+ setPlateDrawer(false)}
+ >
+
+ {plate_words.map((item) => (
+
+ ))}
+
+
+ event.target.value.length <= 2 ? formik.setFieldValue("plate_part1", event.target.value) : null}
+ onBlur={formik.handleBlur}
+ error={true}
+ />
+
+
+
+
+
+
+ {(isTouched && isErrorPlate) ? `${t("LoanRequest.error_message_plate_number")}` : null}
+ >
+
+ )
+}
+export default PlateNumber
\ No newline at end of file
diff --git a/src/core/components/SelectBox.jsx b/src/core/components/SelectBox.jsx
index a24484c..0ee7a47 100644
--- a/src/core/components/SelectBox.jsx
+++ b/src/core/components/SelectBox.jsx
@@ -1,48 +1,53 @@
import {FormControl, FormHelperText, InputLabel, MenuItem, Select,} from "@mui/material";
+import {useTranslations} from "next-intl";
function SelectBox({
select,
- selectType,
+ name,
selectors,
label,
- setFieldValue,
- setFieldTouched,
+ handleChange,
error,
+ onBlur,
+ schema,
+ disabled,
helperText,
+ isLoading,
+ errorEcured
}) {
+ const t = useTranslations();
- const selectId = String(select);
- const handleChange = (event) => {
- setFieldValue(selectType, event.target.value);
- };
- const handleBlur = () => {
- setFieldTouched(select, true);
- };
return (
- {label}
+ {label}
{helperText}
diff --git a/src/core/components/svgs/SvgDone.jsx b/src/core/components/svgs/SvgDone.jsx
new file mode 100644
index 0000000..9042c27
--- /dev/null
+++ b/src/core/components/svgs/SvgDone.jsx
@@ -0,0 +1,96 @@
+import {useTheme} from "@mui/material";
+
+const SvgDone = ({width, height}) => {
+ const theme = useTheme()
+ const fillColor = theme.palette.primary.main
+
+ return (
+
+ )
+}
+
+export default SvgDone
\ No newline at end of file
diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js
index cd90a05..49d5c4a 100644
--- a/src/core/data/apiRoutes.js
+++ b/src/core/data/apiRoutes.js
@@ -14,5 +14,8 @@ export const SEND_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/store";
export const UPDATE_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/update/";
export const DETAILS_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/details/";
export const GET_PROVINCE_LIST = BASE_URL + "/provinces";
+export const GET_CITIES_LIST = BASE_URL + "/cities";
+export const GET_EDUCATIONS_LIST = BASE_URL + "/education";
+export const GET_OCCUPATIONS_LIST = BASE_URL + "/occupations";
diff --git a/src/lib/app/hooks/useCities.jsx b/src/lib/app/hooks/useCities.jsx
new file mode 100644
index 0000000..bc01e0f
--- /dev/null
+++ b/src/lib/app/hooks/useCities.jsx
@@ -0,0 +1,38 @@
+import {useEffect, useState} from "react";
+import {useRequest} from "@witel/webapp-builder";
+import {useTranslations} from "next-intl";
+import {GET_CITIES_LIST} from "@/core/data/apiRoutes";
+
+const useCities = () => {
+ const t = useTranslations();
+ const [provinceID, setProvinceID] = useState(null)
+ const [cityList, setCityList] = useState([]);
+ const [cityTextField, setCityTextField] = useState(t("text_field_city_id"));
+ const [isLoadingCityList, setIsLoadingCityList] = useState(false)
+ const requestServer = useRequest({auth: true, notification: false})
+
+ useEffect(() => {
+ if (provinceID === null) return
+ setIsLoadingCityList(true)
+ setCityTextField(t("text_field_loading_cities_list"))
+ requestServer(`${GET_CITIES_LIST}?province_id=${provinceID}`, "get", {auth: true, notification: false})
+ .then(({data}) => {
+ const result = data.data;
+ const formattedData = result.map((city, index) => ({
+ id: index,
+ name: city.name,
+ value: city.id,
+ }));
+ setCityList(formattedData);
+ setIsLoadingCityList(false)
+ setCityTextField(t("text_field_city_id"))
+ }).catch(() => {
+ setIsLoadingCityList(false)
+ setCityTextField(t("text_field_error_fetching_cities"))
+ });
+ }, [provinceID])
+
+
+ return {cityTextField, cityList, setProvinceID, isLoadingCityList}
+}
+export default useCities
\ No newline at end of file
diff --git a/src/lib/app/hooks/useEducations.jsx b/src/lib/app/hooks/useEducations.jsx
new file mode 100644
index 0000000..16bcfe4
--- /dev/null
+++ b/src/lib/app/hooks/useEducations.jsx
@@ -0,0 +1,29 @@
+import {GET_EDUCATIONS_LIST} from "@/core/data/apiRoutes";
+import {useRequest} from "@witel/webapp-builder";
+import {useEffect, useState} from "react";
+
+const useEducations = () => {
+ const [isLoadingEducationsList, setIsLoadingEducationsList] = useState(false)
+ const [errorEducationsList, setErrorEducationsList] = useState(false)
+ const [educationsList, setEducationsList] = useState([])
+ const requestServer = useRequest({auth: true, notification: false})
+
+ useEffect(() => {
+ setIsLoadingEducationsList(true)
+ requestServer(GET_EDUCATIONS_LIST, 'get', {auth: true, notification: false}).then(({data}) => {
+ setIsLoadingEducationsList(false)
+ setEducationsList(data.data);
+ }).catch(() => {
+ setIsLoadingEducationsList(false)
+ setErrorEducationsList(true)
+ })
+ }, [])
+
+ return {
+ educationsList,
+ isLoadingEducationsList,
+ errorEducationsList
+ }
+};
+
+export default useEducations;
\ No newline at end of file
diff --git a/src/lib/app/hooks/useOccupations.jsx b/src/lib/app/hooks/useOccupations.jsx
new file mode 100644
index 0000000..4a2080a
--- /dev/null
+++ b/src/lib/app/hooks/useOccupations.jsx
@@ -0,0 +1,29 @@
+import {GET_OCCUPATIONS_LIST} from "@/core/data/apiRoutes";
+import {useRequest} from "@witel/webapp-builder";
+import {useEffect, useState} from "react";
+
+const useOccupations = () => {
+ const [isLoadingOccupationsList, setIsLoadingOccupationsList] = useState(false)
+ const [errorOccupationsList, setErrorOccupationsList] = useState(false)
+ const [occupationsList, setOccupationsList] = useState([])
+ const requestServer = useRequest({auth: true, notification: false})
+
+ useEffect(() => {
+ setIsLoadingOccupationsList(true)
+ requestServer(GET_OCCUPATIONS_LIST, 'get', {auth: true, notification: false}).then(({data}) => {
+ setIsLoadingOccupationsList(false)
+ setOccupationsList(data.data);
+ }).catch(() => {
+ setIsLoadingOccupationsList(false)
+ setErrorOccupationsList(true)
+ })
+ }, [])
+
+ return {
+ occupationsList,
+ isLoadingOccupationsList,
+ errorOccupationsList
+ }
+};
+
+export default useOccupations;
\ No newline at end of file
diff --git a/src/lib/app/hooks/useProvince.jsx b/src/lib/app/hooks/useProvince.jsx
index d0fbda0..add55f3 100644
--- a/src/lib/app/hooks/useProvince.jsx
+++ b/src/lib/app/hooks/useProvince.jsx
@@ -1,28 +1,33 @@
import {GET_PROVINCE_LIST} from "@/core/data/apiRoutes";
-import useRequest from "@/lib/app/hooks/useRequest";
-import useSWR from "swr";
+import {useRequest} from "@witel/webapp-builder";
+import {useEffect, useState} from "react";
const useProvince = () => {
+ const [isLoadingProvinceList, setIsLoadingProvinceList] = useState(false)
+ const [errorProvinceList, setErrorProvinceList] = useState(false)
+ const [provinceList, setProvinceList] = useState([])
const requestServer = useRequest({auth: true, notification: false})
- //swr config
- const fetcher = (...args) => {
- return requestServer(args, 'get').then(({data}) => {
- return data;
+ useEffect(()=> {
+ setIsLoadingProvinceList(true)
+ requestServer(GET_PROVINCE_LIST, 'get',{auth : true, notification : false}).then(({data}) => {
+ const formattedData = data.map((province, index) => ({
+ id: index,
+ name: province.name,
+ value: province.id,
+ }));
+ setIsLoadingProvinceList(false)
+ setProvinceList(formattedData);
}).catch(() => {
+ setIsLoadingProvinceList(false)
+ setErrorProvinceList(true)
})
- };
-
- const {data, isLoading} = useSWR(GET_PROVINCE_LIST, fetcher, {
- revalidateIfStale: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false
- });
+ },[])
return {
- provinceList: data,
- isLoadingProvinceList: isLoading,
- errorProvinceList: !data
+ provinceList,
+ isLoadingProvinceList,
+ errorProvinceList
}
};
diff --git a/src/pages/register/navy/index.jsx b/src/pages/register/navy/index.jsx
new file mode 100644
index 0000000..e69de29