diff --git a/example.env.local b/example.env.local index 65a9824..c547e86 100644 --- a/example.env.local +++ b/example.env.local @@ -1,5 +1,5 @@ NEXT_PUBLIC_API_NAME = "Loan Facilities Dashboard" -NEXT_PUBLIC_API_VERSION = "1.22.3" +NEXT_PUBLIC_API_VERSION = "1.25.2" NEXT_PUBLIC_DEFAULT_LANGUAGE = "fa" NEXT_PUBLIC_DEFAULT_DIRECTION = "rtl" diff --git a/package.json b/package.json index 9b8b7b0..35ba316 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,11 @@ "@mui/icons-material": "^5.11.16", "@mui/lab": "^5.0.0-alpha.152", "@mui/material": "^5.12.0", - "@witel/webapp-builder": "^1.0.6", + "@mui/x-date-pickers": "^6.18.5", + "@witel/webapp-builder": "^1.2.4", "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/config.json.example b/public/config.json.example index 59e8e23..bf732fa 100644 --- a/public/config.json.example +++ b/public/config.json.example @@ -1,36 +1,41 @@ { - "time_lines": { - "navgan_first_page": [ - { - "date": { - "from": "1402/09/01", - "to": "1402/09/10" - }, - "label": { - "primary": "ثبت نام متقاضی", - "secondary": "ثبت نام متقاضیان واجد شرایط" - } + "middlewares": {}, + "deadlines": { + "register": { + "date": { + "from": "1402/09/01", + "to": "1402/09/10" }, - { - "date": { - "from": "1402/09/15", - "to": "1402/11/10" - }, - "label": { - "primary": "صحت سنجی متقاضیان", - "secondary": "بررسی و کارشناسی درخواست ها" - } + "messages": { + "before": "ثبت نام هنوز شروع نشده", + "after": "زمان ثبت نام به اتمام رسید" }, - { - "date": { - "from": "1402/11/10", - "to": "1402/12/20" - }, - "label": { - "primary": "ارجاع به بانک", - "secondary": "فرآیند معرفی ضامن و پرداخت" - } + "timeline_label": { + "primary": "ثبت نام متقاضی", + "secondary": "ثبت نام متقاضیان واجد شرایط" } - ] + }, + "validation": { + "date": { + "from": "1402/09/15", + "to": "1402/11/10" + }, + "messages": {}, + "timeline_label": { + "primary": "صحت سنجی متقاضیان", + "secondary": "بررسی و کارشناسی درخواست ها" + } + }, + "done": { + "date": { + "from": "1402/11/10", + "to": "1402/12/20" + }, + "messages": {}, + "timeline_label": { + "primary": "ارجاع به بانک", + "secondary": "فرآیند معرفی ضامن و پرداخت" + } + } } } \ No newline at end of file diff --git a/public/images/bg-firstpage-bus.png b/public/images/bg-firstpage-bus.png new file mode 100644 index 0000000..276d67b Binary files /dev/null and b/public/images/bg-firstpage-bus.png differ diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 507c7e3..36ac7fb 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -1,10 +1,18 @@ { "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": "ورود", + "today": "امروز", "pending": "درحال اجرا...", "login_user_panel": "ورود به پنل کاربران", "register_navy": "ثبت نام اعضای ناوگان", @@ -19,6 +27,7 @@ "online_message": "شما به اینترنت وصل هستید", "offline_message": "اتصال شما به اینترنت قطع شده است", "routing_to": "در حال انتقال به صفحه", + "error_message_plate_number": "لطفا شماره پلاک خود را وارد کنید!", "header": { "open_profile": "پروفایل", "edit_profile": "ویرایش پروفایل", @@ -44,7 +53,7 @@ "button_back_dashboard": "بازگشت به صفحه اصلی" }, "Titles": { - "title_login_page": "صفحه ورود", + "title_login_page": "ورود به سامانه", "title_register_page": "صفحه ثبت نام", "title_login_navy_page": "ورود اعضای ناوگان", "title_login_welfare_services_page": "ورود اعضای خدمات رفاهی", @@ -123,51 +132,82 @@ "loan_request_correction": "اصلاح درخواست", "loan_request_detail": "مشاهده جزئیات", "request_number": "درخواست شماره", - "no_request_found": "درخواستی یافت نشد" + "no_request_found": "درخواستی یافت نشد", + "loan_unique_code": "کد یکتا", + "loan_date": "تاریخ درخواست", + "loan_status": "وضعیت", + "loan_bank_branch": "اطلاعات شعبه", + "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": "اکنون امکان ثبت درخواست جدید برای شما مقدور نیست" }, "showLoan": { 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/dashboard/navgan/followUp-loan/RequestCard.jsx b/src/components/dashboard/navgan/followUp-loan/RequestCard.jsx index 6e5dfd3..54695db 100644 --- a/src/components/dashboard/navgan/followUp-loan/RequestCard.jsx +++ b/src/components/dashboard/navgan/followUp-loan/RequestCard.jsx @@ -1,25 +1,50 @@ -import {Card, CardContent, CardHeader, Grid, Typography} from "@mui/material"; -import SellIcon from '@mui/icons-material/Sell'; +import {Box, Button, Card, CardContent, Grid, Typography} from "@mui/material"; import {useTranslations} from "next-intl"; - +import moment from "jalali-moment"; +import {LinkRouting} from "@witel/webapp-builder"; +import AccessTimeFilledIcon from '@mui/icons-material/AccessTimeFilled'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import CancelIcon from '@mui/icons-material/Cancel'; const RequestCard = ({item}) => { const t = useTranslations(); return ( - + - } - title={`${t("LoanFollowUp.request_number")}: (${item.id})`} - subheader={item.latest_history_created_at} - /> - - - {item.loan_state} + + + + {`${t("LoanFollowUp.loan_unique_code")}: ${item.id}`} + + + + {`${t("LoanFollowUp.loan_date")}: ${moment(item.created_at).locale("fa").format("HH:mm | YYYY/MM/DD")}`} + + {`${t("LoanFollowUp.loan_bank_branch")}: ${item.branch_info === null ? '-' : item.branch_info}`} + + + {`${t("LoanFollowUp.loan_status")}: `} + {item.loan_state} + {item.state_id >= 1 && item.state_id <= 6 && } + {item.state_id === 8 && } + {item.state_id === 7 && } + + diff --git a/src/components/dashboard/navgan/followUp-loan/index.jsx b/src/components/dashboard/navgan/followUp-loan/index.jsx index de3176c..aa031a6 100644 --- a/src/components/dashboard/navgan/followUp-loan/index.jsx +++ b/src/components/dashboard/navgan/followUp-loan/index.jsx @@ -1,59 +1,44 @@ -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import { - Grid, - Stack, -} from "@mui/material"; +import { Grid } from "@mui/material"; import {useEffect, useState} from "react"; import {SHOW_LOAN_REQUEST_NAVGAN} from "@/core/data/apiRoutes"; -import useLoading from "@/lib/app/hooks/useLoading"; -import useRequest from "@/lib/app/hooks/useRequest"; -import moment from "jalali-moment"; import RequestCard from "@/components/dashboard/navgan/followUp-loan/RequestCard"; +import {FullPageLayout , useRequest} from "@witel/webapp-builder"; const LoanFollowUpComponent = () => { const requestServer = useRequest(); - const {setLoadingPage} = useLoading(); + const [isLoading, setIsLoading] = useState(false) const [requestsList, setRequestsList] = useState([]); - // get form data useEffect(() => { - setLoadingPage(true) - requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", {auth: true, notification: false}) + setIsLoading(true) + requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", { + auth: true, + pending:false, + success:{notification:{show:false}} + }) .then(function ({data}) { const items = data.data; - const formattedData = items.map((item, index) => ({ - id: item.id, - latest_history_created_at: moment(item.latest_history_created_at).locale("fa").format("HH:mm | YYYY/MM/DD"), - state_id: item.state_id, - loan_state: item.loan_state, - })); - setRequestsList(formattedData); - setLoadingPage(false) + setRequestsList(items); + setIsLoading(false) }) .catch(function (error) { }) }, []); return ( - - + - - {requestsList.map((item, index) => ( - - ))} - - - + {requestsList.map((item) => ( + + ))} + + + + ); }; diff --git a/src/components/dashboard/refahi/add-request-loan/accessibility/index.jsx b/src/components/dashboard/refahi/add-request-loan/accessibility/index.jsx deleted file mode 100644 index 3618d0b..0000000 --- a/src/components/dashboard/refahi/add-request-loan/accessibility/index.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import {Button, Typography} from "@mui/material"; -import {useTranslations} from "next-intl"; -import CenterLayout from "@/layouts/CenterLayout"; -import {useRouter} from "next/router"; -import {NextLinkComposed} from "@/core/components/LinkRouting"; - -const AccessibilityComponent = () => { - const t = useTranslations(); - const router = useRouter(); - - return ( - - - {t("LoanRequest.add_loan_request_permission")} - - - - ); -}; - -export default AccessibilityComponent; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/AddForm.jsx b/src/components/dashboard/refahi/add-request-loan/forms/AddForm.jsx deleted file mode 100644 index 4051854..0000000 --- a/src/components/dashboard/refahi/add-request-loan/forms/AddForm.jsx +++ /dev/null @@ -1,439 +0,0 @@ -import StyledForm from "@/core/components/StyledForm"; -import UploadSystem from "@/core/components/UploadSystem"; -import {SEND_LOAN_REQUEST_WELFARE} from "@/core/data/apiRoutes"; -import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; -import { - Box, - Button, - Chip, - Divider, - FormControl, - FormHelperText, - InputLabel, - MenuItem, - Select, - Stack, - TextField -} from "@mui/material"; -import {Field, Formik} from "formik"; -import {useTranslations} from "next-intl"; -import * as Yup from "yup"; -import useRequest from "@/lib/app/hooks/useRequest"; -import useProvince from "@/lib/app/hooks/useProvince"; -import {useRouter} from "next/router"; - -const AddFormComponent = () => { - const t = useTranslations(); - const requestServer = useRequest() - const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); - const router = useRouter(); - - // initial values, validation and request action of form - const initialValues = { - name: "", - phone_number: "", - province_id: "", - national_id: "", - shenasname_id: "", - sherkat_naft_doc: null, - estate_doc: null, - agreement_doc: null, - national_card_image: null, - shenasname_image: null, - payan_khedmat_image: null, - }; - - 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") - ), - province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), - national_id: Yup.string().required( - t("LoanRequest.error_message_national_id") - ), - shenasname_id: Yup.string().required( - t("LoanRequest.error_message_shenasname_id") - ), - sherkat_naft_doc: Yup.mixed().required(t("LoanRequest.error_message_sherkat_naft_doc")), - estate_doc: Yup.mixed().required(t("LoanRequest.error_message_estate_doc")), - agreement_doc: Yup.mixed().required(t("LoanRequest.error_message_agreement_doc")), - national_card_image: Yup.mixed().required(t("LoanRequest.error_message_national_card_image")), - shenasname_image: Yup.mixed().required(t("LoanRequest.error_message_shenasname_image")), - payan_khedmat_image: Yup.mixed().required(t("LoanRequest.error_message_payan_khedmat_image")), - }); - const handleSubmit = (values, props) => { - const formData = new FormData(); - formData.append("name", values.name); - formData.append("phone_number", values.phone_number); - formData.append("province_id", values.province_id); - formData.append("national_id", values.national_id); - formData.append("shenasname_id", values.shenasname_id); - if (values.sherkat_naft_doc != null) - formData.append("sherkat_naft_doc", values.sherkat_naft_doc); - if (values.estate_doc != null) - formData.append("estate_doc", values.estate_doc); - if (values.agreement_doc != null) - formData.append("agreement_doc", values.agreement_doc); - if (values.shenasname_image != null) - formData.append("shenasname_image", values.shenasname_image); - if (values.national_card_image != null) - formData.append("national_card_image", values.national_card_image); - if (values.payan_khedmat_image != null) - formData.append("payan_khedmat_image", values.payan_khedmat_image); - requestServer(SEND_LOAN_REQUEST_WELFARE, "post", {auth: true, data: formData}) - .then(function (response) { - router.replace('/dashboard/refahi/followUp-loan'); - }) - .catch(function (error) { - }) - .finally(function () { - props.setSubmitting(false); - }); - }; - // end initial values, validation and request action of form - - return ( - - {(props) => ( - - - - - - - - - - - - - - - - - {t("LoanRequest.text_field_province_id")} - - - {props.touched.province_id && props.errors.province_id ? props.errors.province_id : ""} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - )} - - ); -}; - -export default AddFormComponent; \ No newline at end of file diff --git a/src/components/dashboard/refahi/add-request-loan/index.jsx b/src/components/dashboard/refahi/add-request-loan/index.jsx deleted file mode 100644 index bc82ac7..0000000 --- a/src/components/dashboard/refahi/add-request-loan/index.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import useUser from "@/lib/app/hooks/useUser"; -import {useTranslations} from "next-intl"; -import AddFormComponent from "@/components/dashboard/refahi/add-request-loan/forms/AddForm"; -import AccessibilityComponent from "@/components/dashboard/refahi/add-request-loan/accessibility"; - -const LoanRequestComponent = () => { - const t = useTranslations(); - const {user} = useUser(); - return ( - - {user.can_request_a_new_loan ? : } - - ); -}; - -export default LoanRequestComponent; diff --git a/src/components/dashboard/refahi/edit-request-loan/forms/EditForm.jsx b/src/components/dashboard/refahi/edit-request-loan/forms/EditForm.jsx deleted file mode 100644 index 36f5aa0..0000000 --- a/src/components/dashboard/refahi/edit-request-loan/forms/EditForm.jsx +++ /dev/null @@ -1,397 +0,0 @@ -import StyledForm from "@/core/components/StyledForm"; -import UploadSystem from "@/core/components/UploadSystem"; -import {UPDATE_LOAN_REQUEST_WELFARE} 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, Chip, Divider, Stack, TextField} from "@mui/material"; -import {Field, Formik} from "formik"; -import {useTranslations} from "next-intl"; -import * as Yup from "yup"; -import SelectBox from "@/core/components/SelectBox"; -import useRequest from "@/lib/app/hooks/useRequest"; -import {useRouter} from "next/router"; -import useLoading from "@/lib/app/hooks/useLoading"; - -const EditFormComponent = ({provinceList, initialValues}) => { - const t = useTranslations(); - const requestServer = useRequest(); - const router = useRouter(); - - - // validation and request action of form - 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") - ), - province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), - national_id: Yup.string().required(t("LoanRequest.error_message_national_id")), - shenasname_id: Yup.string().required(t("LoanRequest.error_message_shenasname_id")), - sherkat_naft_doc: Yup.mixed().required(t("LoanRequest.error_message_sherkat_naft_doc")), - estate_doc: Yup.mixed().required(t("LoanRequest.error_message_estate_doc")), - agreement_doc: Yup.mixed().required(t("LoanRequest.error_message_agreement_doc")), - national_card_image: Yup.mixed().required(t("LoanRequest.error_message_national_card_image")), - shenasname_image: Yup.mixed().required(t("LoanRequest.error_message_shenasname_image")), - payan_khedmat_image: Yup.mixed().required(t("LoanRequest.error_message_payan_khedmat_image")), - }); - - const handleSubmit = (values, props) => { - const formData = new FormData(); - formData.append("name", values.name); - formData.append("phone_number", values.phone_number); - formData.append("province_id", values.province_id); - formData.append("national_id", values.national_id); - formData.append("shenasname_id", values.shenasname_id); - if (values.sherkat_naft_doc != initialValues.sherkat_naft_doc) - formData.append("sherkat_naft_doc", values.sherkat_naft_doc); - if (values.estate_doc != initialValues.estate_doc) - formData.append("estate_doc", values.estate_doc); - if (values.agreement_doc != initialValues.agreement_doc) - formData.append("agreement_doc", values.agreement_doc); - if (values.shenasname_image != initialValues.shenasname_image) - formData.append("shenasname_image", values.shenasname_image); - if (values.national_card_image != initialValues.national_card_image) - formData.append("national_card_image", values.national_card_image); - if (values.payan_khedmat_image != initialValues.payan_khedmat_image) - formData.append("payan_khedmat_image", values.payan_khedmat_image); - - requestServer(UPDATE_LOAN_REQUEST_WELFARE + router.query.id, "post", {auth: true, data: formData}) - .then(function (response) { - }) - .catch(function (error) { - }) - .finally(function () { - props.setSubmitting(false); - }); - }; - if (!initialValues) return ""; - return ( - - {(props) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - )} - - ); -}; - -export default EditFormComponent; \ No newline at end of file diff --git a/src/components/dashboard/refahi/edit-request-loan/index.jsx b/src/components/dashboard/refahi/edit-request-loan/index.jsx deleted file mode 100644 index 89de937..0000000 --- a/src/components/dashboard/refahi/edit-request-loan/index.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import EditFormComponent from "@/components/dashboard/refahi/edit-request-loan/forms/EditForm"; -import {useEffect, useState} from "react"; -import {DETAILS_LOAN_REQUEST_WELFARE, GET_PROVINCE_LIST} from "@/core/data/apiRoutes"; -import useLoading from "@/lib/app/hooks/useLoading"; -import useRequest from "@/lib/app/hooks/useRequest"; -import {useRouter} from "next/router"; -import {log} from "next/dist/server/typescript/utils"; - -const LoanRequestComponent = () => { - const requestServer = useRequest(); - const {setLoadingPage} = useLoading(); - const router = useRouter(); - - const [provinceList, setProvinceList] = useState(null); - const [initialValues, setInitialValues] = useState(null); - - // get province list - useEffect(() => { - setLoadingPage(true); - requestServer(GET_PROVINCE_LIST, "get", {auth: true, notification: false}) - .then(function ({data}) { - const formattedData = data.map((province, index) => ({ - id: index, - name: province.name, - value: province.id, - })); - setProvinceList(formattedData); - }).catch(() => { - setLoadingPage(false); - }); - }, []); - - // get form data - useEffect(() => { - if (!provinceList) return; - setLoadingPage(true); - requestServer(DETAILS_LOAN_REQUEST_WELFARE + router.query.id, "get", {auth: true, notification: false}) - .then(function ({data}) { - const item = data.data; - const formattedData = { - name: item.name, - phone_number: item.phone_number, - province_id: item.province_id, - national_id: item.national_id, - shenasname_id: item.shenasname_id, - sherkat_naft_doc: item.sherkat_naft_doc, - estate_doc: item.estate_doc, - agreement_doc: item.agreement_doc, - national_card_image: item.national_card_image, - shenasname_image: item.shenasname_image, - payan_khedmat_image: item.payan_khedmat_image, - state_id: item.state_id - }; - setInitialValues(formattedData); - }) - .catch(() => { - setLoadingPage(false); - }); - }, [provinceList, router]); - - // Redirect to /dashboard/refahi/followUp-loan if state_id is not 7 - useEffect(() => { - if (!initialValues) return - if (initialValues.state_id === 7) return - - router.replace('/dashboard/refahi/followUp-loan'); - }, [initialValues]); - - return ( - <> - {initialValues && initialValues.state_id === 7 && ( - - - - )} - - ); -}; - -export default LoanRequestComponent; \ No newline at end of file diff --git a/src/components/dashboard/refahi/followUp-loan/RequestCard.jsx b/src/components/dashboard/refahi/followUp-loan/RequestCard.jsx deleted file mode 100644 index 799d296..0000000 --- a/src/components/dashboard/refahi/followUp-loan/RequestCard.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import { - Card, - CardContent, - CardHeader, - Grid, IconButton, Tooltip, - Typography, -} from "@mui/material"; -import SellIcon from '@mui/icons-material/Sell'; -import EditIcon from '@mui/icons-material/Edit'; -import {useTranslations} from "next-intl"; -import {NextLinkComposed} from "@/core/components/LinkRouting"; - - -const RequestCard = ({item}) => { - const t = useTranslations(); - return ( - - - } - title={`${t("LoanFollowUp.request_number")}: (${item.id})`} - subheader={item.latest_history_created_at} - action={ - item.state_id === 7 ? ( // Use the ternary operator or if/else inside curly braces - - - - - - ) : null - } - /> - - - {item.loan_state} - - - - - ); -}; - -export default RequestCard; \ No newline at end of file diff --git a/src/components/dashboard/refahi/followUp-loan/index.jsx b/src/components/dashboard/refahi/followUp-loan/index.jsx deleted file mode 100644 index 32b121d..0000000 --- a/src/components/dashboard/refahi/followUp-loan/index.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import {Grid, Stack, Typography,} from "@mui/material"; -import {useEffect, useState} from "react"; -import {SHOW_LOAN_REQUEST_WELFARE} from "@/core/data/apiRoutes"; -import useLoading from "@/lib/app/hooks/useLoading"; -import useRequest from "@/lib/app/hooks/useRequest"; -import moment from "jalali-moment"; -import RequestCard from "@/components/dashboard/refahi/followUp-loan/RequestCard"; -import {useTranslations} from "next-intl"; - -const LoanFollowUpComponent = () => { - const t = useTranslations() - const requestServer = useRequest(); - const {setLoadingPage} = useLoading(); - const [requestsList, setRequestsList] = useState(null); - // get form data - useEffect(() => { - setLoadingPage(true) - requestServer(SHOW_LOAN_REQUEST_WELFARE, "get", {auth: true, notification: false}) - .then(function ({data}) { - const items = data.data; - const formattedData = items.map((item, index) => ({ - id: item.id, - latest_history_created_at: moment(item.latest_history_created_at).locale("fa").format("HH:mm | YYYY/MM/DD"), - state_id: item.state_id, - loan_state: item.loan_state, - })); - setRequestsList(formattedData); - setLoadingPage(false) - }) - .catch(function (error) { - }) - }, []); - - return ( - - {requestsList == null ? '' : requestsList.length ? ( - {requestsList.map((item, index) => ())} - ) : ({t('LoanFollowUp.no_request_found')})} - - ); -}; - -export default LoanFollowUpComponent; diff --git a/src/components/first/LoanDescription/TimeLineDetails.jsx b/src/components/first/LoanDescription/TimeLineDetails.jsx index 02e2fed..ec274bf 100644 --- a/src/components/first/LoanDescription/TimeLineDetails.jsx +++ b/src/components/first/LoanDescription/TimeLineDetails.jsx @@ -1,74 +1,53 @@ -import {useTranslations} from "next-intl"; import {useEffect, useState} from "react"; -import {useRequest} from "@witel/webapp-builder"; import TimelineManager from "@/core/components/timelines/timelineManager"; import moment from "jalali-moment"; import {Timeline} from "@mui/lab"; -import {LinearProgress} from "@mui/material"; +import {useConfig} from "@witel/webapp-builder"; const TimeLineDetails = () => { - const t = useTranslations(); - const request = useRequest({notification: false, auth: false}) + const {config} = useConfig() const [timeLineList, setTimeLineList] = useState([]) - const [loading, setLoading] = useState(true) + + const deadlines = Object.keys(config.deadlines).map(key => ({ + type: key, + ...config.deadlines[key] + })); useEffect(() => { - setLoading(true) - request(process.env.NEXT_PUBLIC_CONFIG_APP_URL, 'get').then(res => { - let tempArr = [] - for (const timeLine of res.data.time_lines.navgan_first_page) { - let temp = {} - temp['label'] = timeLine.label - temp['date'] = moment(timeLine.date.from, 'jYYYY/jMM/jDD').locale('fa').format('jD jMMMM') - const fromDate = moment(timeLine.date.from, 'jYYYY/jMM/jDD') - const toDate = moment(timeLine.date.to, 'jYYYY/jMM/jDD') - const today = moment() - if (today.isBetween(fromDate, toDate, null, '[]')) { - temp['status'] = 'in progress' - } else if (today.isAfter(toDate, null)) { - temp['status'] = 'done' - } else if (today.isBefore(fromDate, null)) { - temp['status'] = 'open' - } - tempArr.push(temp) + let tempArr = [] + for (const timeLine of deadlines) { + let temp = {} + temp['label'] = timeLine.timeline_label + temp['date'] = moment(timeLine.date.from, 'jYYYY/jMM/jDD').locale('fa').format('jD jMMMM') + const fromDate = moment(timeLine.date.from, 'jYYYY/jMM/jDD') + const toDate = moment(timeLine.date.to, 'jYYYY/jMM/jDD') + const today = moment() + if (today.isBetween(fromDate, toDate, null, '[]')) { + temp['status'] = 'in progress' + } else if (today.isAfter(toDate, null)) { + temp['status'] = 'done' + } else if (today.isBefore(fromDate, null)) { + temp['status'] = 'open' } - setTimeLineList(tempArr) - setLoading(false) - }).catch(() => { - setLoading(false) - }) + tempArr.push(temp) + } + setTimeLineList(tempArr) }, []); return ( - <> - {loading ? ( - - ) : ( - - {timeLineList.map((timeLine, index) => ( - - )) - } - - )} - + + {timeLineList.map((timeLine, index) => ( + + )) + } + ) - // return ( - // - // - // - // - // - // ) } export default TimeLineDetails \ No newline at end of file diff --git a/src/components/first/LoanRegister.jsx b/src/components/first/LoanRegister.jsx index c665eb2..810c5da 100644 --- a/src/components/first/LoanRegister.jsx +++ b/src/components/first/LoanRegister.jsx @@ -5,16 +5,16 @@ import {LinkRouting} from "@witel/webapp-builder"; const LoanRegister = () => { const t = useTranslations(); return ( - + - + {t("app_name")} - + وام نوسازی ناوگان به هدف رشد و پیشرفت استان های کشور از طریق ارتقای بهره وری و توسعه اعطا میشود. برای استفاده از تسهیلات این سامانه و درخواست وام می بایست ابتدا وارد سامانه شوید. @@ -30,18 +30,6 @@ const LoanRegister = () => { padding: 1 }}> - - {t("firstPage.login_button")} - - - - - {t("firstPage.register_button")} diff --git a/src/components/login/SendUserData.jsx b/src/components/login/SendUserData.jsx index a4c598a..1f48025 100644 --- a/src/components/login/SendUserData.jsx +++ b/src/components/login/SendUserData.jsx @@ -1,7 +1,6 @@ import StyledForm from "@/core/components/StyledForm"; import {SEND_OTP_TOKEN} from "@/core/data/apiRoutes"; import FingerprintIcon from "@mui/icons-material/Fingerprint"; -import PersonAddIcon from "@mui/icons-material/PersonAdd"; import {Button, Container, Grid, Paper, Stack, TextField, Typography,} from "@mui/material"; import {Field, Formik} from "formik"; import {useTranslations} from "next-intl"; @@ -10,6 +9,7 @@ import * as Yup from "yup"; import SvgLogin from "@/core/components/svgs/SvgLogin"; import {CenterLayout, FullPageLayout, LinkRouting, useRequest} from "@witel/webapp-builder"; + const SendUserDataComponent = ({ setOtpToken, setPhoneNumber, @@ -94,32 +94,16 @@ const SendUserDataComponent = ({ flexDirection: {xs: "column-reverse", sm: "row"}, }} > - - - - - - - - + diff --git a/src/components/register/RequestOtp.jsx b/src/components/register/RequestOtp.jsx deleted file mode 100644 index a24aa4f..0000000 --- a/src/components/register/RequestOtp.jsx +++ /dev/null @@ -1,131 +0,0 @@ -import LinkRouting from "@/core/components/LinkRouting"; -import StyledForm from "@/core/components/StyledForm"; -import {SEND_OTP_TOKEN} from "@/core/data/apiRoutes"; -import CenterLayout from "@/layouts/CenterLayout"; -import FullPageLayout from "@/layouts/FullPageLayout"; -import FingerprintIcon from "@mui/icons-material/Fingerprint"; -import {Button, Container, Paper, Stack, TextField, Typography,} from "@mui/material"; -import {Field, Formik} from "formik"; -import {useTranslations} from "next-intl"; -import {useSearchParams} from "next/navigation"; -import * as Yup from "yup"; -import SvgLogin from "@/core/components/svgs/SvgLogin"; -import useRequest from "@/lib/app/hooks/useRequest"; - -const RequestOtpComponent = ({ - setOtpToken, - setPhoneNumber, - PhoneNumber, - setTimer, - initialTimerValue, - }) => { - const t = useTranslations(); - const requestServer = useRequest(); - - const searchParams = useSearchParams(); - const backUrlDecodedPath = searchParams.get("back_url"); - - const initialValues = { - phone_number: PhoneNumber, - }; - const validationSchema = Yup.object().shape({ - phone_number: Yup.string().required( - t("RegisterPage.error_message_phone_number") - ), - }); - - const handleSubmit = (values, props) => { - requestServer(SEND_OTP_TOKEN, "post", { - auth: false, data: { - phone_number: values.phone_number, - } - }) - .then(function (response) { - setPhoneNumber(values.phone_number); - setOtpToken(true); - setTimer(initialTimerValue); - }).catch(function (error) { - props.setSubmitting(false); - }); - }; - - return ( - - - - - - {(props) => ( - - - - - - {t("Titles.title_register_page")} - - - - - - - - - )} - - - - - - - {t("RegisterPage.link_routing_back_to")}{" "} - {backUrlDecodedPath - ? t("RegisterPage.link_routing_previuos_page") - : t("RegisterPage.link_routing_register")} - - - - ); -}; - -export default RequestOtpComponent; diff --git a/src/components/register/index.jsx b/src/components/register/index.jsx deleted file mode 100644 index eb11ad0..0000000 --- a/src/components/register/index.jsx +++ /dev/null @@ -1,90 +0,0 @@ -import LinkRouting, {NextLinkComposed} from "@/core/components/LinkRouting"; -import CenterLayout from "@/layouts/CenterLayout"; -import FullPageLayout from "@/layouts/FullPageLayout"; -import useUser from "@/lib/app/hooks/useUser"; -import {Box, Button, Grid, Stack} from "@mui/material"; -import {useTranslations} from "next-intl"; -import {useSearchParams} from "next/navigation"; -import SvgDashboard from "@/core/components/svgs/SvgDashboard"; - -const RegisterComponent = () => { - const t = useTranslations(); - const {isAuth} = useUser(); - - const searchParams = useSearchParams(); - const backUrlDecodedPath = searchParams.get("back_url"); - - return ( - - - - {isAuth ? ( - - ) : ( - - - - - - {/**/} - {/* */} - {/* {t("register_welfare_services")}*/} - {/* */} - {/**/} - - - )} - - - - {t("RegisterPage.link_routing_back_to")}{" "} - {backUrlDecodedPath - ? t("RegisterPage.link_routing_previuos_page") - : t("LoginPage.link_routing_main_page")} - - - - ); -}; - -export default RegisterComponent; diff --git a/src/components/register/navy/UserRegister.jsx b/src/components/register/navy/UserRegister.jsx deleted file mode 100644 index 9714636..0000000 --- a/src/components/register/navy/UserRegister.jsx +++ /dev/null @@ -1,176 +0,0 @@ -import StyledForm from "@/core/components/StyledForm"; -import {REGISTER} from "@/core/data/apiRoutes"; -import CenterLayout from "@/layouts/CenterLayout"; -import FullPageLayout from "@/layouts/FullPageLayout"; -import LoginIcon from "@mui/icons-material/Login"; -import ChangeCircleIcon from "@mui/icons-material/ChangeCircle"; -import {Box, Button, Chip, Container, Divider, Paper, Stack, TextField, Typography,} from "@mui/material"; -import {Field, Formik} from "formik"; -import {useTranslations} from "next-intl"; -import * as Yup from "yup"; -import ResendToken from "@/core/components/ResendToken"; -import useUser from "@/lib/app/hooks/useUser"; -import SvgRegister from "@/core/components/svgs/SvgRegister"; -import useRequest from "@/lib/app/hooks/useRequest"; -import AutoSubmit from "@/core/components/AutoSubmit"; - -const UserRegisterComponent = ({ - PhoneNumber, - setOtpToken, - initialTimerValue, - timer, - setTimer, - }) => { - const t = useTranslations(); - const {setToken} = useUser(); - const requestServer = useRequest(); - - const initialValues = { - type_id: "1", - verification_code: "", - phone_number: PhoneNumber, - national_id: "", - }; - - const validationSchema = Yup.object().shape({ - verification_code: Yup.string().required( - t("RegisterPage.error_message_verification_code") - ), - national_id: Yup.string().required( - t("RegisterPage.error_message_national_id") - ), - }); - - const handleSubmit = (values, props) => { - requestServer(REGISTER, "post", { - auth: false, data: { - type_id: values.type_id, - national_id: values.national_id, - phone_number: values.phone_number, - verification_code: values.verification_code, - } - }) - .then(function (response) { - setOtpToken(true); - setToken(response.data.token); - }).catch(function (error) { - props.setSubmitting(false); - }); - }; - - return ( - - - - - - {(props) => ( - - - - - - {t("register_navy")} - - - - - - {t("LoginPage.sent_token_to")}: {PhoneNumber} - - - - e.target.value.length <= 6 ? props.setFieldValue("verification_code", e.target.value) : ""} - /> - - - - - - - - - - - )} - - - - - - ); -}; - -export default UserRegisterComponent; diff --git a/src/components/register/navy/index.jsx b/src/components/register/navy/index.jsx deleted file mode 100644 index 9296f78..0000000 --- a/src/components/register/navy/index.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import {useState} from "react"; -import RequestOtpComponent from "../RequestOtp"; -import UserRegisterComponent from "./UserRegister"; - -const NavyComponent = () => { - const [otpToken, setOtpToken] = useState(false); - const [PhoneNumber, setPhoneNumber] = useState(""); - - // For Resend Token (read ResendToken Component Doc) - const initialTimerValue = 30; - const [timer, setTimer] = useState(initialTimerValue); - // End For Resend Token - - if (!otpToken) { - return ( - - ); - } else { - return ( - - ); - } -}; - -export default NavyComponent; diff --git a/src/components/register/welfare-services/UserRegister.jsx b/src/components/register/welfare-services/UserRegister.jsx deleted file mode 100644 index a043a53..0000000 --- a/src/components/register/welfare-services/UserRegister.jsx +++ /dev/null @@ -1,174 +0,0 @@ -import StyledForm from "@/core/components/StyledForm"; -import {REGISTER} from "@/core/data/apiRoutes"; -import CenterLayout from "@/layouts/CenterLayout"; -import FullPageLayout from "@/layouts/FullPageLayout"; -import LoginIcon from "@mui/icons-material/Login"; -import ChangeCircleIcon from "@mui/icons-material/ChangeCircle"; -import {Box, Button, Chip, Container, Divider, Paper, Stack, TextField, Typography,} from "@mui/material"; -import {Field, Formik} from "formik"; -import {useTranslations} from "next-intl"; -import * as Yup from "yup"; -import ResendToken from "@/core/components/ResendToken"; -import useUser from "@/lib/app/hooks/useUser"; -import SvgRegister from "@/core/components/svgs/SvgRegister"; -import useRequest from "@/lib/app/hooks/useRequest"; - -const UserRegisterComponent = ({ - PhoneNumber, - setOtpToken, - initialTimerValue, - timer, - setTimer, - }) => { - const t = useTranslations(); - const {setToken} = useUser(); - const requestServer = useRequest(); - - const initialValues = { - type_id: "2", - verification_code: "", - phone_number: PhoneNumber, - national_id: "", - }; - - const validationSchema = Yup.object().shape({ - verification_code: Yup.string().required( - t("RegisterPage.error_message_verification_code") - ), - national_id: Yup.string().required( - t("RegisterPage.error_message_national_id") - ), - }); - - const handleSubmit = (values, props) => { - requestServer(REGISTER, "post", { - auth: false, data: { - type_id: values.type_id, - national_id: values.national_id, - phone_number: values.phone_number, - verification_code: values.verification_code, - } - }) - .then(function (response) { - setOtpToken(true); - setToken(response.data.token); - }).catch(function (error) { - props.setSubmitting(false); - }); - }; - - return ( - - - - - - {(props) => ( - - - - - - {t("register_welfare_services")} - - - - - - {t("LoginPage.sent_token_to")}: {PhoneNumber} - - - - - - - - - - - - - - )} - - - - - - ); -}; - -export default UserRegisterComponent; diff --git a/src/components/register/welfare-services/index.jsx b/src/components/register/welfare-services/index.jsx deleted file mode 100644 index 322490f..0000000 --- a/src/components/register/welfare-services/index.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import {useState} from "react"; -import RequestOtpComponent from "../RequestOtp"; -import UserRegisterComponent from "./UserRegister"; - -const WelfareServicesComponent = () => { - const [otpToken, setOtpToken] = useState(false); - const [PhoneNumber, setPhoneNumber] = useState(""); - - // For Resend Token (read ResendToken Component Doc) - const initialTimerValue = 30; - const [timer, setTimer] = useState(initialTimerValue); - // End For Resend Token - - if (!otpToken) { - return ( - - ); - } else { - return ( - - ); - } -}; - -export default WelfareServicesComponent; diff --git a/src/core/components/GlobalHead.jsx b/src/core/components/GlobalHead.jsx index 9036b85..002199d 100644 --- a/src/core/components/GlobalHead.jsx +++ b/src/core/components/GlobalHead.jsx @@ -39,14 +39,6 @@ const GlobalHead = () => { /> - 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/ResendToken.jsx b/src/core/components/ResendToken.jsx index d564397..2216c99 100644 --- a/src/core/components/ResendToken.jsx +++ b/src/core/components/ResendToken.jsx @@ -1,7 +1,7 @@ import {Button} from "@mui/material"; import {useTranslations} from "next-intl"; import {useEffect} from "react"; -import {SEND_OTP_TOKEN} from "../data/apiRoutes"; +import {LOGIN, SEND_OTP_TOKEN} from "../data/apiRoutes"; import {useDirection, useRequest} from "@witel/webapp-builder"; const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber, disabled}) => { 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/components/svgs/SvgMaintenance.jsx b/src/core/components/svgs/SvgMaintenance.jsx new file mode 100644 index 0000000..47fcc0f --- /dev/null +++ b/src/core/components/svgs/SvgMaintenance.jsx @@ -0,0 +1,91 @@ +import {useTheme} from "@mui/material"; + +const SvgMaintenance = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + +} + +export default SvgMaintenance \ 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/core/data/sidebarMenu.js b/src/core/data/sidebarMenu.js index 5f24a93..ef2c7d8 100644 --- a/src/core/data/sidebarMenu.js +++ b/src/core/data/sidebarMenu.js @@ -20,7 +20,7 @@ const sidebarMenu = [ route: "/dashboard/navgan/add-request-loan", icon: , selected: false, - permission: "can_request_a_new_loan" + permission: "can_request_navgan_loan" }, { key: "sidebar.followUp-loan", diff --git a/src/core/utils/globalServerProps.js b/src/core/utils/globalServerProps.js new file mode 100644 index 0000000..dffb0f2 --- /dev/null +++ b/src/core/utils/globalServerProps.js @@ -0,0 +1,15 @@ +import {parse} from "next-useragent"; +import process from "next/dist/build/webpack/loaders/resolve-url-loader/lib/postcss"; + +export const globalServerProps = async ({req, locale}) => { + const {isBot} = parse(req.headers["user-agent"]); + + const responseConfig = await fetch(process.env.NEXT_PUBLIC_CONFIG_APP_URL); + + return { + config: await responseConfig.json(), + messages: (await import(`&/locales/${locale}/app.json`)).default, + isBot, + locale, + } +} \ No newline at end of file diff --git a/src/layouts/dashboard.jsx b/src/layouts/dashboard.jsx index 9b1a916..a814c9a 100644 --- a/src/layouts/dashboard.jsx +++ b/src/layouts/dashboard.jsx @@ -2,18 +2,24 @@ import {DashboardLayout as DashboardLayoutPure, useUser} from "@witel/webapp-bui import headerProfileItems from "@/core/data/headerProfileItems"; import sidebarMenu from "@/core/data/sidebarMenu"; import {GET_SIDEBAR_NOTIFICATION} from "@/core/data/apiRoutes"; +import UserInfo from "@/middlewares/UserInfo"; +import {useTranslations} from "next-intl"; +import moment from "jalali-moment"; const DashboardLayout = (props) => { const {user} = useUser() + const middlewaresProps = props.middlewaresProps || {} + const t = useTranslations() return ( <> 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/middlewares/Deadline.jsx b/src/middlewares/Deadline.jsx new file mode 100644 index 0000000..796ee54 --- /dev/null +++ b/src/middlewares/Deadline.jsx @@ -0,0 +1,41 @@ +import {CenterLayout, FullPageLayout, useConfig} from "@witel/webapp-builder"; +import moment from "jalali-moment"; +import SvgMaintenance from "@/core/components/svgs/SvgMaintenance"; +import {Typography} from "@mui/material"; + +const DeadlineMiddleware = ({children, type = '', withMessage = false}) => { + const {config} = useConfig() + const middleware = config.deadlines[type] + + if (!middleware) return children + + const fromDate = moment(middleware.date.from, 'jYYYY/jMM/jDD') + const toDate = moment(middleware.date.to, 'jYYYY/jMM/jDD') + const today = moment() + + if (today.isBetween(fromDate, toDate, null, '[]')) { + return children + } else if (today.isAfter(toDate, null)) { + if (!withMessage) return + return ( + + + + {middleware.messages.after || ''} + + + ) + } else if (today.isBefore(fromDate, null)) { + if (!withMessage) return + return ( + + + + {middleware.messages.before || ''} + + + ) + } +} + +export default DeadlineMiddleware \ No newline at end of file diff --git a/src/middlewares/UserInfo.jsx b/src/middlewares/UserInfo.jsx new file mode 100644 index 0000000..3f594c4 --- /dev/null +++ b/src/middlewares/UserInfo.jsx @@ -0,0 +1,9 @@ +import {useUser} from "@witel/webapp-builder"; + +const UserInfo = ({children}) => { + const {user} = useUser(); + const userAccess = user.profile_completed; + return userAccess ? <>{children} : ''; +}; + +export default UserInfo; diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index a3be1c7..848a35c 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -2,10 +2,12 @@ import "&/global.scss"; import "moment/locale/fa"; import { AppLayout, + ConfigProvider, LanguageProvider, LoadingProvider, MuiLayout, NetworkProvider, + PageMiddleware, ToastProvider, UserProvider } from "@witel/webapp-builder"; @@ -18,8 +20,8 @@ import GlobalHead from "@/core/components/GlobalHead"; import Layout from "@/layouts"; const App = ({Component, pageProps}) => { - return ( - <> + return (<> + data}> @@ -31,7 +33,9 @@ const App = ({Component, pageProps}) => { - + + + @@ -41,8 +45,8 @@ const App = ({Component, pageProps}) => { - - ); + + ); }; export default App; diff --git a/src/pages/dashboard/index.jsx b/src/pages/dashboard/index.jsx index 265c8ac..b946dbd 100644 --- a/src/pages/dashboard/index.jsx +++ b/src/pages/dashboard/index.jsx @@ -1,5 +1,5 @@ import FirstComponent from "@/components/dashboard/first"; -import {parse} from "next-useragent"; +import {globalServerProps} from "@/core/utils/globalServerProps"; export default function Dashboard() { return ( @@ -8,13 +8,10 @@ export default function Dashboard() { } export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); return { props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, + ...await globalServerProps({req, locale}), title: "Dashboard.dashboard_page", - isBot, - locale, layout: {name: 'DashboardLayout'} }, }; diff --git a/src/pages/dashboard/navgan/add-request-loan/index.jsx b/src/pages/dashboard/navgan/add-request-loan/index.jsx index 5af141c..71bcaf0 100644 --- a/src/pages/dashboard/navgan/add-request-loan/index.jsx +++ b/src/pages/dashboard/navgan/add-request-loan/index.jsx @@ -1,21 +1,21 @@ -import {parse} from "next-useragent"; import LoanRequestComponent from "@/components/dashboard/navgan/add-request-loan"; +import {globalServerProps} from "@/core/utils/globalServerProps"; +import DeadlineMiddleware from "@/middlewares/Deadline"; export default function AddLoanRequest() { return ( - + + + ); } export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); return { props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, + ...await globalServerProps({req, locale}), title: "LoanRequest.loan_request_page", - isBot, - locale, - layout: {name: 'DashboardLayout'} + layout: {name: 'DashboardLayout', permissions: ["can_request_navgan_loan"]} }, }; } diff --git a/src/pages/dashboard/navgan/followUp-loan/index.jsx b/src/pages/dashboard/navgan/followUp-loan/index.jsx index 1476d5a..68f4f73 100644 --- a/src/pages/dashboard/navgan/followUp-loan/index.jsx +++ b/src/pages/dashboard/navgan/followUp-loan/index.jsx @@ -1,5 +1,5 @@ -import {parse} from "next-useragent"; import LoanFollowUpComponent from "@/components/dashboard/navgan/followUp-loan"; +import {globalServerProps} from "@/core/utils/globalServerProps"; export default function FollowUpLoan() { return ( @@ -8,13 +8,10 @@ export default function FollowUpLoan() { } export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); return { props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, + ...await globalServerProps({req, locale}), title: "LoanRequest.loan_request_page", - isBot, - locale, layout: {name: 'DashboardLayout'} }, }; diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 2e146c6..6e47ba2 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -1,5 +1,5 @@ import FirstComponent from "@/components/first"; -import {parse} from "next-useragent"; +import {globalServerProps} from "@/core/utils/globalServerProps"; export default function Home() { return ( @@ -10,12 +10,10 @@ export default function Home() { } export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); return { props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, + ...await globalServerProps({req, locale}), title: "first_page", - isBot, }, }; } diff --git a/src/pages/login.jsx b/src/pages/login.jsx index 63e88c7..6f7b288 100644 --- a/src/pages/login.jsx +++ b/src/pages/login.jsx @@ -1,22 +1,20 @@ import LoginComponent from "@/components/login"; -import {parse} from "next-useragent"; import {WithoutAuthMiddleware} from "@witel/webapp-builder"; +import {globalServerProps} from "@/core/utils/globalServerProps"; export default function Login() { return ( - + ); } export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); return { props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, + ...await globalServerProps({req, locale}), title: "Titles.title_login_page", - isBot, }, }; } diff --git a/src/pages/register/index.jsx b/src/pages/register/index.jsx deleted file mode 100644 index 3f078d7..0000000 --- a/src/pages/register/index.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import RegisterComponent from "@/components/register"; -import {parse} from "next-useragent"; -import {WithoutAuthMiddleware} from "@witel/webapp-builder"; - -export default function Register() { - return ( - - - - ); -} - -export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); - return { - props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, - title: "Titles.title_register_page", - isBot, - }, - }; -} diff --git a/src/pages/register/navy/index.jsx b/src/pages/register/navy/index.jsx deleted file mode 100644 index 2272d57..0000000 --- a/src/pages/register/navy/index.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import NavyComponent from "@/components/register/navy"; -import WithoutAuthMiddleware from "@/middlewares/WithoutAuth"; -import {parse} from "next-useragent"; - -export default function Register() { - return ( - - - - ); -} - -export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); - return { - props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, - title: "Titles.title_register_navy_page", - isBot, - }, - }; -} diff --git a/src/pages/register/welfare-services/index.jsx b/src/pages/register/welfare-services/index.jsx deleted file mode 100644 index ce05a4f..0000000 --- a/src/pages/register/welfare-services/index.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import WithoutAuthMiddleware from "@/middlewares/WithoutAuth"; -import {parse} from "next-useragent"; - -export default function Register() { - return ( - - {/**/} - - ); -} - -export async function getServerSideProps({req, locale}) { - const {isBot} = parse(req.headers["user-agent"]); - return { - props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, - title: "Titles.title_register_welfare_services_page", - isBot, - }, - }; -}