diff --git a/.env.local.example b/.env.local.example index 06753ea..2d453b8 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1,5 +1,5 @@ NEXT_PUBLIC_API_NAME = "Loan Facilities Dashboard" -NEXT_PUBLIC_API_VERSION = "2.4.2" +NEXT_PUBLIC_API_VERSION = "2.5.0" NEXT_PUBLIC_DEFAULT_LANGUAGE = "fa" NEXT_PUBLIC_DEFAULT_DIRECTION = "rtl" diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 72e8739..2d9274b 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -76,11 +76,19 @@ }, "sidebar": { "dashboard": "داشبورد", - "add-request-loan": "درخواست وام", + "add-request-navgan-loan": "درخواست تسهیلات", + "add-request-loan": "درخواست تسهیلات", + "add-request-refahi-loan": "درخواست تسهیلات", + "refahi": "رفاهی", + "navgan": "ناوگان", "followUp-loan": "پیگیری درخواست", "edit-request-loan": "ویرایش درخواست وام", "show": "نمایش" }, + "secondary": { + "navgan": "ناوگان", + "refahi": "رفاهی" + }, "Authorization": { "typography_your_login_is_valid_and_you_do_not_need_to_login_again": "شما دسترسی لازم به این صفحه را دارید نیاز به ورود مجدد نیست.", "typography_your_access_to_this_page_has_expired_Please_login_again": "دسترسی شما منقضی شده است لطفا دوباره ورود نمایید.", @@ -137,10 +145,18 @@ "Dashboard": { "dashboard_page": "داشبورد", "go_to_add_request_loan": "درخواست تسهیلات نوسازی ناوگان", + "request_navgan_loan": "درخواست تسهیلات ناوگان", + "request_refahi_loan": "درخواست تسهیلات رفاهی", + "navgan_loan_description": "درخواست تسهیلات جهت ناوگان سازمان راه", + "refahi_loan_description": "درخواست تسهیلات رفاهی سازمان راه", + "navgan_loan_request_page": "ثبت درخواست تسهیلات ناوگان", + "refahi_loan_request_page": "ثبت درخواست تسهیلات رفاهی", "go_to_followUp-loan": "پیگیری وضعیت تسهیلات نوسازی ناوگان" }, "LoanFollowUp": { "loan_follow_up_page": "پیگیری درخواست", + "loan_follow_up_navgan": "پیگیری درخواست تسهیلات ناوگان", + "loan_follow_up_refahi": "پیگیری درخواست تسهیلات رفاهی", "loan_request_correction": "اصلاح درخواست", "loan_request_detail": "مشاهده جزئیات", "request_number": "درخواست شماره", @@ -158,20 +174,74 @@ "loan_edit_info": "نیاز به ویرایش اطلاعات", "loan_description": "توضیحات" }, + "RefahiLoanRequest": { + "restore_facilities": "تسهیلات مرمت و بازسازی مجتمع رفاهی", + "building_facilities": "تسهیلات ساخت مجتمع رفاهی", + "restore_facilities_description": "درخواست تسهیلات مرمت و بازسازی مجتمع رفاهی", + "building_facilities_description": "درخواست تسهیلات ساخت مجتمع رفاهی", + "restore_facilities_request": "درخواست تسهیلات مرمت و بازسازی مجتمع رفاهی", + "building_facilities_request": "درخواست تسهیلات ساخت مجتمع رفاهی", + "upload_principle_agreement_img": "تصویر آخرین تمدیدی موافقت اصولی", + "upload_refresh_date_img": "تصویر اخرین تمدیدی بهره برداری", + "upload_operating_license_img": "تصویر پروانه بهره برداری", + "upload_principle_agreement_img_required": "بارگذاری تصویر آخرین تمدیدی موافقت اصولی الزامیست", + "upload_operating_license_img_required": "بارگذاری تصویر پروانه بهره برداری الزامیست", + "upload_refresh_date_img_required": "بارگذاری تصویر اخرین تمدیدی بهره برداری الزامیست", + "upload_principle_agreement_img_unit": "فایل بارگذاری شده باید حداکثر 2Mb باشد", + "upload_operating_license_img_unit": "فایل بارگذاری شده باید حداکثر 2Mb باشد", + "upload_refresh_date_img_unit": "فایل بارگذاری شده باید حداکثر 2Mb باشد", + "upload_principle_agreement_img_format": "فرمت قابل قبول : png,jpg", + "upload_refresh_date_img_format": "فرمت قابل قبول : png,jpg", + "upload_operating_license_img_format": "فرمت قابل قبول : png,jpg", + "back-button": "بازگشت", + "next-button": "تایید و مرحله بعد", + "submit-button": "تایید و ثبت درخواست", + "step_personal_info": "مشخصات متقاضی", + "step_project_info": "مشخصات محل اجرا پروژه", + "step_contact_info": "جزییات درخواست تسهیلات" + }, + "UploadSystem": { + "upload_file": "فایل خود را بارگذاری کنید", + "optional": " (اختیاری)", + "upload_file_unit": "حداکثر 2Mb", + "upload_file_format": "فرمت قابل قبول : png,jpg,pdf", + "delete": "پاک کردن", + "phone_number": "شماره تلفن", + "national_id": "کد ملی", + "navgan_id": "کد ناوگان", + "type_id": "نوع کاربر", + "uploadfile_error": "حجم فایل بیشتر از 2 مگابایت می باشد" + }, "LoanRequest": { "finish_loan_request": "درخواست شما با موفقیت ثبت شد", "accept_all_rules": "با شرایط فوق موافق هستم", + "operation_date": "تاریخ بهره برداری", + "refresh_date": "تاریخ اخرین تمدیدی پروانه بهره برداری", + "basic_approval_renewal_date": "تاریخ اخرین تمدیدی موافقت اصولی", + "enter_operation_date": "تاریخ بهره برداری", + "enter_refresh_date": "تاریخ اخرین تمدیدی پروانه بهره برداری", + "enter_basic_approval_renewal_date": "تاریخ اخرین تمدیدی موافقت اصولی", + "error_message_operation_date": "لطفا تاریخ بهره برداری را انتخاب کنید!", + "error_message_refresh_date": "لطفا تاریخ تمدیدی پروانه بهره برداری را انتخاب کنید!", + "error_message_basic_approval_renewal_date": "لطفا تاریخ تمدیدی موافقت اصولی را انتخاب کنید!", + "error_message_money_investment": "لطفا میزان سرمایه گذاری انجام شده را انتخاب کنید!", "button_while_submit": "درحال بارگذاری ...", "max_amount": "حداکثر مبلغ تسهیلات مورد تقاضا {value} ریال می باشد", "checkbox": "بدینوسیله صحت کلیه اطلاعات مندرج در این فرم را تایید و گواهی میدهم .", "back_to_dashboard": "پیگیری درخواست ها", "accept_rules_title": "شرایط عمومی و اختصاصی دریافت تسهیلات", "submit_rules": "پذیرش شرایط", + "principle_agreement_number": "شماره موافقت اصولی", + "text_field_phone_number": "تلفن همراه", + "text_field_money_investment": "میزان سرمایه گذاری انجام شده(ریال)", + "text_field_enter_your_money_investment": "لطفا میزان سرمایه گذاری انجام شده را وارد کنید!", + "text_field_enter_your_phone_number": "تلفن همراه خود را واردکنید!", "cityList_empty": "ابتدا استان را وارد کنید", "cityList_loading": "درحال دریافت لیست شهر ها ...", "history_facilities": "دارای سابقه استفاده از تسهیلات تکلیفی می باشم .", - "loan_request_page": "ثبت درخواست وام", + "loan_request_page": "ثبت درخواست تسهیلات", "personal_info": "اطلاعات شخصی", + "checkbox_required": "پر کردن این قسمت ضروریست!", "real_person": "شخص حقیقی", "legal_person": "شخص حقوقی", "enter_province": "ابتدا استان را انتخاب کنید", @@ -183,6 +253,11 @@ "text_field_requested_facilities" : "تسهیلات مورد تقاضا(ریال)", "text_field_investment" : "ارزش ناوگان(ریال)", "text_field_applicant_payment" : "آورده متقاضی(ریال)", + "text_field_progress_percentage" : "درصد پیشرفت پروژه", + "text_field_mehvar" : "محور", + "text_field_kilometer" : "کیلومتر", + "text_field_samt" : "سمت", + "text_field_execution_address" : "ادرس محل اجرا", "national_code_number": "کد ملی می بایست شامل اعداد باشد", "boss_national_code_number": "کد ملی مدیر عامل می بایست شامل اعداد باشد", "national_number_number": "شناسه ملی شرکت می بایست شامل اعداد باشد", @@ -196,6 +271,7 @@ "shenasname_serial_max": "سریال پشت کارت ملی می بایست شامل 10 بخش باشد", "postal_code_max": "کد پستی می بایست 10 رقم باشد", "tel_number_max": "شماره ثابت می بایست 11 رقم باشد", + "phone_number_max": "شماره ثابت می بایست 11 رقم باشد", "company_tel_number_max": "شماره ثابت شرکت می بایست 11 رقم باشد", "national_code_positive": "کد ملی می بایست مثبت باشد", "boss_national_code_positive": "کد ملی مدیر عامل می بایست مثبت باشد", @@ -212,6 +288,15 @@ "error_message_last_name": "لطفا نام خانوادگی خود را وارد کنید!", "error_message_boss_last_name": "لطفا نام خانوادگی مدیر عامل را وارد کنید!", "error_message_gender": "لطفا جنسیت خود را وارد کنید!", + "error_message_degree": "لطفا درجه مجتمع خود را وارد کنید!", + "error_message_execution_address": "لطفا ادرس محل اجرا خود را وارد کنید!", + "error_message_mehvar": "لطفا محور خود را وارد کنید!", + "error_message_samt": "لطفا سمت خود را وارد کنید!", + "error_message_principle_agreement_number": "لطفا شماره موافقت اصولی خود را وارد کنید!", + "error_message_progress_percentage": "لطفا درصد پیشرفت پروژه خود را وارد کنید!", + "error_message_progress_min_40": "حداقل درصد پیشرفت پروژه 40 درصد می باشد!", + "error_message_progress_max_100": "حداکثر درصد پیشرفت پروژه 100 درصد می باشد!", + "error_message_kilometer": "لطفا کیلومتر خود را وارد کنید!", "error_message_boss_gender": "لطفا جنسیت مدیر عامل را وارد کنید!", "error_message_father_name": "لطفا نام پدر خود را وارد کنید!", "error_message_boss_father_name": "لطفا نام پدر مدیر عامل را وارد کنید!", @@ -221,10 +306,12 @@ "error_message_company_postal_code": "لطفا کد پستی شرکت را وارد کنید!", "error_message_education_id": "لطفا مدرک تحصیلی را به درستی وارد کنید!", "error_message_tel_number": "لطفا شماره ثابت (با پیش شماره استان) خود را وارد کنید!", + "error_message_phone_number": "لطفا تلفن همراه خود را وارد کنید!", "error_message_company_tel_number": "لطفا شماره ثابت شرکت (با پیش شماره استان) خود را وارد کنید!", "error_message_vehicle_type": "لطفا نوع وسیله نقلیه خود را وارد کنید!", "error_message_navgan_id": "لطفا کد هوشمند ناوگان خود را وارد کنید!", "error_message_province_id": "لطفا استان خود را وارد کنید!", + "error_message_project_province_id": "لطفا استان محل پروژه را وارد کنید!", "error_message_national_id": "لطفا کد ملی خود را وارد کنید!", "error_message_boss_national_id": "لطفا کد ملی مدیر عامل را وارد کنید!", "error_message_national_number": "لطفا شناسه ملی شرکت خود را وارد کنید!", @@ -236,6 +323,7 @@ "error_message_tracking_code": "لطفا کد رهگیری کارت ملی خود را وارد کنید!", "error_message_boss_national_card_tracking_code": "لطفا کد رهگیری کارت ملی مدیر عامل را وارد کنید!", "error_message_postal_code": "لطفا کد پستی خود را وارد کنید!", + "error_message_company_date": "لطفا تاریخ ثبت شرکت را وارد کنید!", "error_message_national_code": "لطفا کد ملی خود را وارد کنید!", "error_message_checkedBox": "لطفا کد صحت اطلاعات خود را تایید کنید!", "error_message_navgan_type": "لطفا نوع ناوگان خود را وارد کنید!", @@ -258,6 +346,7 @@ "text_field_last_name": "نام خانوادگی", "text_field_boss_last_name": "نام خانوادگی مدیر عامل", "text_field_gender": "جنسیت", + "text_field_degree": "درجه مجتمع", "text_field_activity_type": "نوع فعالیت", "text_field_priority_list": "اولویت فعالیت", "text_field_boss_gender": "جنسیت مدیر عامل", @@ -276,6 +365,10 @@ "text_field_enter_your_plate_part3": "بخش سوم پلاک را وارد کنید", "text_field_enter_your_plate_part4": "بخش چهارم پلاک راوارد کنید", "text_field_enter_your_first_name": "نام خود راوارد کنید", + "text_field_enter_your_execution_address": "ادرس محل اجرا خود راوارد کنید", + "text_field_enter_your_samt": "سمت خود راوارد کنید", + "text_field_enter_your_kilometer": "کیلومتر خود راوارد کنید", + "text_field_enter_your_mehvar": "محور خود راوارد کنید", "text_field_enter_your_boss_first_name": "نام مدیر عامل راوارد کنید", "text_field_enter_your_company_name": "نام شرکت خود راوارد کنید", "text_field_enter_your_last_name": "نام خانوادگی خود راوارد کنید", @@ -291,6 +384,10 @@ "text_field_vehicle_type": "نوع وسیله نقلیه", "text_field_enter_your_vehicle_type": "نوع وسیله نقلیه خود را وارد کنید", "text_field_province_id": "استان", + "project_city_id": "شهر محل پروژه", + "enter_project_province_id": "ابتدااستان محل پروژه را انتخاب کنید", + "project_cityList_empty": "خطا در دریافت اطلاعات!", + "text_field_project_province_id": "استان محل پروژه", "text_field_loading_provinces_list": "درحال دریافت استان ها ...", "text_field_error_fetching_provinces": "خطا در دریافت استان ها", "text_field_enter_your_national_code": "کد ملی خود را وارد کنید", @@ -316,6 +413,7 @@ "text_field_enter_your_plate_number": "شماره پلاک خود را وارد کنید", "button_submit": "ثبت درخواست", "error_message_city_id": "لطفا شهر خود را وارد کنید!", + "error_message_project_city_id": "لطفا شهر محل پروژه را وارد کنید!", "add_loan_request_permission": "اکنون امکان ثبت درخواست جدید برای شما مقدور نیست" }, "ShowLoan": { @@ -356,6 +454,7 @@ "text_field_birthday": "تاریخ تولد", "text_field_navgan_id": "کد ناوگان", "text_field_province_id": "استان", + "text_field_project_province_id": "استان محل پروژه", "text_field_boss_father_name": "نام پدر مدیر عامل", "text_field_education_id": "تحصیلات", "text_field_national_tracking_code": "کد رهگیری کارت ملی", @@ -410,6 +509,7 @@ "error_message_vehicle_type": "لطفا نوع وسیله را وارد کنید!", "error_message_company_name": "لطفا نام شرکت خود را وارد کنید!", "error_message_gender": "لطفا جنسیت خود را وارد کنید!", + "error_message_degree": "لطفا درجه مجتمع خود را وارد کنید!", "error_message_last_name": "لطفا نام خانوادگی خود را وارد کنید!", "error_message_fixed_number": "لطفا تلفن ثابت را وارد کنید!", "error_message_tel_number": "لطفا شماره ثابت (با پیش شماره استان) خود را وارد کنید!", diff --git a/src/components/dashboard/first/index.jsx b/src/components/dashboard/first/index.jsx index 9d39d5e..8e40fe8 100644 --- a/src/components/dashboard/first/index.jsx +++ b/src/components/dashboard/first/index.jsx @@ -1,6 +1,8 @@ import { CenterLayout, FullPageLayout, NextLinkComposed, useUser } from "@witel/webapp-builder"; -import { Button, Typography } from "@mui/material"; +import { Button, Card, CardActions, CardContent, Stack, Typography } from "@mui/material"; import { useTranslations } from "next-intl"; +import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism"; +import DirectionsCarIcon from "@mui/icons-material/DirectionsCar"; const FirstComponent = () => { const { user } = useUser(); @@ -9,23 +11,86 @@ const FirstComponent = () => { {user.permissions.includes("can_request_navgan_loan") ? ( - <> - {t("Dashboard.go_to_add_request_loan")} - - + + + + {t("Dashboard.request_navgan_loan")} + + + {t("Dashboard.navgan_loan_description")} + + + + + + + + + + + {t("Dashboard.request_refahi_loan")} + + + {t("Dashboard.refahi_loan_description")} + + + + + + + ) : ( <> {t("Dashboard.go_to_followUp-loan")} diff --git a/src/components/dashboard/navgan/add-request-loan/forms/CheckRules.jsx b/src/components/dashboard/navgan/add-request-loan/forms/CheckRules.jsx index f361675..d6669c2 100644 --- a/src/components/dashboard/navgan/add-request-loan/forms/CheckRules.jsx +++ b/src/components/dashboard/navgan/add-request-loan/forms/CheckRules.jsx @@ -121,21 +121,21 @@ const CheckRules = ({ setRulesChecked }) => { }, ]; - const renderRuleContent = (content) => { + const renderRuleContent = (content, index) => { if (typeof content === "string") { return ( - + {content} ); } return ( - + {content.title} - {content.subtitles.map((sub, index) => renderRuleContent(sub, index))} + {content.subtitles.map((sub, subIndex) => renderRuleContent(sub, subIndex))} ); diff --git a/src/components/dashboard/navgan/add-request-loan/forms/LegalPersonForm.jsx b/src/components/dashboard/navgan/add-request-loan/forms/LegalPersonForm.jsx index 8269556..a60f2f8 100644 --- a/src/components/dashboard/navgan/add-request-loan/forms/LegalPersonForm.jsx +++ b/src/components/dashboard/navgan/add-request-loan/forms/LegalPersonForm.jsx @@ -78,7 +78,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => { plate_part3: "", plate_part4: "", address: "", - company_date: "", + company_register_date: "", education_id: "", occupation_id: "", checkedBox: false, @@ -114,7 +114,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => { occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")), education_id: Yup.string().required(t("LoanRequest.error_message_education_id")), address: Yup.string().required(t("LoanRequest.error_message_address")), - company_date: Yup.string().required(t("LoanRequest.error_message_date_of_birth")), + company_register_date: Yup.string().required(t("LoanRequest.error_message_date_of_birth")), company_postal_code: Yup.mixed() .test("max", `${t("LoanRequest.company_postal_code_max")}`, (value) => value.toString().length === 10) .required(t("LoanRequest.error_message_company_postal_code")), @@ -227,7 +227,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => { plate_part3: values.plate_part3, plate_part4: values.plate_part4, address: values.address, - company_register_date: values.company_date.locale("en").format("YYYY-MM-DD"), + company_register_date: values.company_register_date.locale("en").format("YYYY-MM-DD"), birthday: values.birthday.locale("en").format("YYYY-MM-DD"), education_id: values.education_id, occupation_id: values.occupation_id, @@ -243,7 +243,7 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => { data: _data, }) .then(() => { - router.replace("/dashboard/navgan/followUp-loan"); + router.replace("/dashboard/followUp-loan"); getUser((data) => { changeUser(data); }); @@ -453,9 +453,9 @@ const LegalPersonForm = ({ setFinishLoanRequest }) => { diff --git a/src/components/dashboard/navgan/add-request-loan/forms/RealPersonForm.jsx b/src/components/dashboard/navgan/add-request-loan/forms/RealPersonForm.jsx index e6395d9..b243090 100644 --- a/src/components/dashboard/navgan/add-request-loan/forms/RealPersonForm.jsx +++ b/src/components/dashboard/navgan/add-request-loan/forms/RealPersonForm.jsx @@ -211,7 +211,7 @@ const RealPersonForm = ({ setFinishLoanRequest }) => { data: _data, }) .then(() => { - router.replace("/dashboard/navgan/followUp-loan"); + router.replace("/dashboard/followUp-loan"); getUser((data) => { changeUser(data); }); diff --git a/src/components/dashboard/navgan/followUp-loan/index.jsx b/src/components/dashboard/navgan/followUp-loan/index.jsx deleted file mode 100644 index 4494e20..0000000 --- a/src/components/dashboard/navgan/followUp-loan/index.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import { Grid } from "@mui/material"; -import { useEffect, useState } from "react"; -import { SHOW_LOAN_REQUEST_NAVGAN } from "@/core/data/apiRoutes"; -import RequestCard from "@/components/dashboard/navgan/followUp-loan/RequestCard"; -import { FullPageLayout, LoadingHardPage, useRequest } from "@witel/webapp-builder"; -import sidebarMenu from "@/core/data/sidebarMenu"; -import BookmarkAddedIcon from "@mui/icons-material/BookmarkAdded"; - -const LoanFollowUpComponent = () => { - const requestServer = useRequest(); - const [isLoading, setIsLoading] = useState(false); - const [requestsList, setRequestsList] = useState([]); - useEffect(() => { - setIsLoading(true); - requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", { - auth: true, - pending: false, - success: { notification: { show: false } }, - }) - .then(function ({ data }) { - const items = data.data; - setRequestsList(items); - setIsLoading(false); - }) - .catch(function (error) {}); - }, []); - - return ( - - - } - > - - {requestsList.map((item) => ( - - ))} - - - - - ); -}; - -export default LoanFollowUpComponent; diff --git a/src/components/dashboard/navgan/show/form/UpdateFormLegal.jsx b/src/components/dashboard/navgan/show/form/UpdateFormLegal.jsx index fe90a6e..74284cc 100644 --- a/src/components/dashboard/navgan/show/form/UpdateFormLegal.jsx +++ b/src/components/dashboard/navgan/show/form/UpdateFormLegal.jsx @@ -49,7 +49,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => { user_committed_employment: LoanDetails.user_committed_employment || "", applicant_payment: LoanDetails.person_share || "", register_number: LoanDetails.register_number || "", - company_date: LoanDetails.company_register_date ? moment(LoanDetails.company_register_date) : "", + company_register_date: LoanDetails.company_register_date ? moment(LoanDetails.company_register_date) : "", birthday: LoanDetails.birthday ? moment(LoanDetails.birthday) : "", navgan_id: LoanDetails.navgan_id || "", province_id: LoanDetails.province_id || "", @@ -104,7 +104,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => { }) .required(t("ShowLoan.error_message_tel_number")), occupation_id: Yup.string().required(t("ShowLoan.error_message_occupation_id")), - company_date: Yup.string().required(t("ShowLoan.error_message_company_date")), + company_register_date: Yup.string().required(t("ShowLoan.error_message_company_date")), company_name: Yup.string().required(t("ShowLoan.error_message_company_name")), register_number: Yup.string().required(t("ShowLoan.error_message_register_number")), boss_first_name: Yup.string().required(t("ShowLoan.error_message_boss_first_name")), @@ -197,7 +197,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => { formData.append("occupation_id", values.occupation_id); formData.append("address", values.address); formData.append("company_name", values.company_name); - formData.append("company_register_date", values.company_date.locale("en").format("YYYY-MM-DD")); + formData.append("company_register_date", values.company_register_date.locale("en").format("YYYY-MM-DD")); formData.append("register_number", values.register_number); await requestServer(UPDATE_LOAN + LoanId, "post", { @@ -206,7 +206,7 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => { data: formData, }) .then(() => { - router.push("/dashboard/navgan/followUp-loan"); + router.push("/dashboard/followUp-loan"); }) .catch(() => {}) .finally(() => { @@ -372,9 +372,9 @@ const UpdateFormLegal = ({ LoanDetails, LoanId }) => { diff --git a/src/components/dashboard/navgan/show/form/UpdateFormReal.jsx b/src/components/dashboard/navgan/show/form/UpdateFormReal.jsx index 037d7ff..ad584af 100644 --- a/src/components/dashboard/navgan/show/form/UpdateFormReal.jsx +++ b/src/components/dashboard/navgan/show/form/UpdateFormReal.jsx @@ -168,7 +168,7 @@ const UpdateFormReal = ({ LoanDetails, LoanId }) => { data: formData, }) .then(() => { - router.push("/dashboard/navgan/followUp-loan"); + router.push("/dashboard/followUp-loan"); }) .catch(() => {}) .finally(() => { diff --git a/src/components/dashboard/refahi/add-request-loan/RefahiLoanType.jsx b/src/components/dashboard/refahi/add-request-loan/RefahiLoanType.jsx new file mode 100644 index 0000000..8c1de45 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/RefahiLoanType.jsx @@ -0,0 +1,86 @@ +import { Button, Card, CardActions, CardContent, Stack, Typography } from "@mui/material"; +import DirectionsCarIcon from "@mui/icons-material/DirectionsCar"; +import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism"; +import BuildIcon from "@mui/icons-material/Build"; +import MapsHomeWorkIcon from "@mui/icons-material/MapsHomeWork"; +import { useTranslations } from "next-intl"; +import { CenterLayout, FullPageLayout } from "@witel/webapp-builder"; + +const RefahiLoanType = ({ setRefahiLoanType }) => { + const t = useTranslations(); + return ( + + + + + + + + {t("RefahiLoanRequest.restore_facilities")} + + + {t("RefahiLoanRequest.restore_facilities_description")} + + + + + + + + + + + {t("RefahiLoanRequest.building_facilities")} + + + {t("RefahiLoanRequest.building_facilities_description")} + + + + + + + + + + ); +}; +export default RefahiLoanType; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildLegalPersonalInfo.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildLegalPersonalInfo.jsx new file mode 100644 index 0000000..7a792ec --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildLegalPersonalInfo.jsx @@ -0,0 +1,710 @@ +import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import SelectBox from "@/core/components/SelectBox"; +import * as React from "react"; +import useActivityType from "@/lib/app/hooks/useActivityType"; +import { useTranslations } from "next-intl"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import UseEducations from "@/lib/app/hooks/useEducations"; +import useOccupations from "@/lib/app/hooks/useOccupations"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import { useEffect } from "react"; +import useCities from "@/lib/app/hooks/useCities"; +import LegalPersonDatePicker from "@/core/components/LegalPersonDatePicker"; + +const BuildLegalPersonalInfo = ({ + state, + handleNext, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + const { activityType, isLoadingActivityType, errorActivityType } = useActivityType(); + const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations(); + const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations(); + const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities(); + + const initialValues = { + person_type: state.person_type, + father_name: state.father_name, + province_id: state.province_id, + city_id: state.city_id, + telephone_number: state.telephone_number, + activity_type_id: state.activity_type_id, + refahi_type: state.refahi_type, + gender: state.gender, + welfare_complex_degree: state.welfare_complex_degree, + first_name: state.first_name, + last_name: state.last_name, + education_id: state.education_id, + occupation_id: state.occupation_id, + national_id: state.national_id, + national_serial_number: state.national_serial_number, + national_card_tracking_code: state.national_card_tracking_code, + national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code, + postal_code: state.postal_code, + address: state.address, + birthday: state.birthday, + company_register_date: state.company_register_date, + shenase_meli: state.shenase_meli, + register_number: state.register_number, + company_name: state.company_name, + }; + + const validationSchema = Yup.object().shape({ + province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), + city_id: Yup.string().required(t("LoanRequest.error_message_city_id")), + telephone_number: Yup.mixed() + .test("max", `${t("LoanRequest.company_tel_number_max")}`, (value) => { + const stringValue = String(value); + return stringValue.length === 11; + }) + .required(t("LoanRequest.error_message_company_tel_number")), + activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")), + gender: Yup.string().required(t("LoanRequest.error_message_boss_gender")), + welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")), + first_name: Yup.string().required(t("LoanRequest.error_message_boss_first_name")), + last_name: Yup.string().required(t("LoanRequest.error_message_boss_last_name")), + occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")), + education_id: Yup.string().required(t("LoanRequest.error_message_education_id")), + national_id: Yup.mixed() + .test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value)) + .test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0) + .test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_boss_national_id")), + national_serial_number: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_serial_number" + ? schema + .test( + "max", + `${t("LoanRequest.national_serial_number_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_boss_shenasname_serial")) + : schema; + } + ), + national_card_tracking_code: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_card_tracking_code" + ? schema + .test( + "max", + `${t("LoanRequest.national_tracking_code_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_boss_national_card_tracking_code")) + : schema; + } + ), + address: Yup.string().required(t("LoanRequest.error_message_address")), + birthday: Yup.string().required(t("LoanRequest.error_message_boss_date_of_birth")), + postal_code: Yup.mixed() + .test("max", `${t("LoanRequest.company_postal_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_company_postal_code")), + father_name: Yup.string().required(t("LoanRequest.error_message_boss_father_name")), + shenase_meli: Yup.mixed().when("person_type", ([person_type], schema) => { + return person_type === "legal" + ? schema + .test("is-number", `${t("LoanRequest.national_number_number")}`, (value) => !isNaN(value)) + .test("positive", `${t("LoanRequest.national_number_positive")}`, (value) => value >= 0) + .test( + "max", + `${t("LoanRequest.national_number_max")}`, + (value) => value && value.toString().length === 11 + ) + .required(t("LoanRequest.error_message_national_number")) + : schema; + }), + company_register_date: Yup.string().required(t("LoanRequest.error_message_company_date")), + register_number: Yup.string().required(t("LoanRequest.error_message_register_number")), + company_name: Yup.string().required(t("LoanRequest.error_message_company_name")), + }); + const handleSubmit = async (values) => { + dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values }); + handleNext(); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + useEffect(() => { + if (formik.values.province_id === "") return; + setProvinceID(formik.values.province_id); + }, [formik.values.province_id]); + return ( + <> + + + + + + { + formik.setFieldValue("activity_type_id", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)} + helperText={formik.touched.activity_type_id && formik.errors.activity_type_id} + onBlur={formik.handleBlur("activity_type_id")} + /> + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "shenase_meli", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_national_number")} + placeholder={t("LoanRequest.text_field_enter_your_national_number")} + onBlur={formik.handleBlur("shenase_meli")} + error={formik.touched.shenase_meli && Boolean(formik.errors.shenase_meli)} + helperText={formik.touched.shenase_meli && formik.errors.shenase_meli} + fullWidth + /> + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "register_number", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_register_number")} + placeholder={t("LoanRequest.text_field_enter_your_register_number")} + onBlur={formik.handleBlur("register_number")} + error={formik.touched.register_number && Boolean(formik.errors.register_number)} + helperText={formik.touched.register_number && formik.errors.register_number} + fullWidth + /> + + + + + { + if (value === null) return; + formik.handleChange({ + target: { + name: "national_serial_number_or_tracking_code", + value: value, + }, + }); + }} + > + + {t("LoanRequest.text_field_shenasname_serial")} + + + {t("LoanRequest.text_field_national_trackin_code")} + + + + {formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? ( + + { + const inputValue = e.target.value; + const regex = /^[A-Za-z0-9]*$/; + if (regex.test(inputValue)) { + formik.setFieldValue("national_serial_number", inputValue); + } + }} + onBlur={formik.handleBlur("national_serial_number")} + error={ + formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number) + } + helperText={formik.touched.national_serial_number && formik.errors.national_serial_number} + /> + + ) : ( + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_card_tracking_code", + value: inputValue, + }, + }); + }} + onBlur={formik.handleBlur("national_card_tracking_code")} + error={ + formik.touched.national_card_tracking_code && + Boolean(formik.errors.national_card_tracking_code) + } + helperText={ + formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code + } + /> + + )} + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_id", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_boss_national_code")} + placeholder={t("LoanRequest.text_field_enter_your_boss_national_code")} + onBlur={formik.handleBlur("national_id")} + error={formik.touched.national_id && Boolean(formik.errors.national_id)} + helperText={formik.touched.national_id && formik.errors.national_id} + fullWidth + /> + + + + + + + + + + + + + { + formik.setFieldValue("province_id", event.target.value); + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", ""); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.province_id && Boolean(formik.errors.province_id)} + helperText={formik.touched.province_id && formik.errors.province_id} + onBlur={formik.handleBlur("province_id")} + /> + + + 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("gender", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.gender && Boolean(formik.errors.gender)} + helperText={formik.touched.gender && formik.errors.gender} + onBlur={formik.handleBlur("gender")} + /> + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "postal_code", + value: inputValue, + }, + }); + }} + size="small" + label={t("LoanRequest.text_field_company_postal_code")} + placeholder={t("LoanRequest.text_field_enter_your_company_postal_code")} + fullWidth + onBlur={formik.handleBlur("postal_code")} + error={formik.touched.postal_code && Boolean(formik.errors.postal_code)} + helperText={formik.touched.postal_code && formik.errors.postal_code} + /> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "telephone_number", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_company_tel_number")} + placeholder={t("LoanRequest.text_field_enter_your_company_tel_number")} + fullWidth + onBlur={formik.handleBlur("telephone_number")} + error={formik.touched.telephone_number && Boolean(formik.errors.telephone_number)} + helperText={formik.touched.telephone_number && formik.errors.telephone_number} + /> + + + + + + + + { + 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("welfare_complex_degree", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)} + helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree} + onBlur={formik.handleBlur("welfare_complex_degree")} + /> + + + + + + + + + + + + + ); +}; +export default BuildLegalPersonalInfo; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildProjectInfo.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildProjectInfo.jsx new file mode 100644 index 0000000..26cdb36 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildProjectInfo.jsx @@ -0,0 +1,232 @@ +import { Button, Grid, Stack, TextField } from "@mui/material"; +import SelectBox from "@/core/components/SelectBox"; +import * as React from "react"; +import { useTranslations } from "next-intl"; +import useLimitedProvince from "@/lib/app/hooks/useLimitedProvince"; +import useCities from "@/lib/app/hooks/useCities"; +import * as Yup from "yup"; +import { useFormik } from "formik"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import { useEffect } from "react"; + +const BuildProjectInfo = ({ + state, + handleNext, + handleBack, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const { cityList, setProvinceID, isLoadingCityList } = useCities(); + const t = useTranslations(); + const initialValues = { + project_province_id: state.project_province_id, + project_city_id: state.project_city_id, + project_axis: state.project_axis, + project_kilometer_marker: state.project_kilometer_marker, + project_direction: state.project_direction, + project_address: state.project_address, + }; + const validationSchema = Yup.object().shape({ + project_province_id: Yup.string().required(t("LoanRequest.error_message_project_province_id")), + project_city_id: Yup.string().required(t("LoanRequest.error_message_project_city_id")), + project_address: Yup.string().required(t("LoanRequest.error_message_execution_address")), + project_axis: Yup.string().required(t("LoanRequest.error_message_mehvar")), + project_kilometer_marker: Yup.string().required(t("LoanRequest.error_message_kilometer")), + project_direction: Yup.string().required(t("LoanRequest.error_message_samt")), + }); + const handleSubmit = async (values) => { + dispatch({ type: "SET_PROJECT_INFO", projectInfo: values }); + handleNext(); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + + useEffect(() => { + if (formik.values.project_province_id === "") return; + setProvinceID(formik.values.project_province_id); + }, [formik.values.project_province_id]); + + return ( + <> + + + { + formik.setFieldValue("project_province_id", event.target.value); + formik.setFieldTouched("project_city_id", false, false); + formik.setFieldValue("project_city_id", ""); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.project_province_id && Boolean(formik.errors.project_province_id)} + helperText={formik.touched.project_province_id && formik.errors.project_province_id} + onBlur={formik.handleBlur("project_province_id")} + /> + + + formik.setFieldValue("project_city_id", event.target.value)} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.project_city_id && Boolean(formik.errors.project_city_id)} + helperText={formik.touched.project_city_id && formik.errors.project_city_id} + onBlur={formik.handleBlur("project_city_id")} + /> + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "project_kilometer_marker", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_kilometer")} + placeholder={t("LoanRequest.text_field_enter_your_kilometer")} + onBlur={formik.handleBlur("project_kilometer_marker")} + error={ + formik.touched.project_kilometer_marker && Boolean(formik.errors.project_kilometer_marker) + } + helperText={formik.touched.project_kilometer_marker && formik.errors.project_kilometer_marker} + fullWidth + /> + + + { + formik.setFieldValue("project_direction", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.project_direction && Boolean(formik.errors.project_direction)} + helperText={formik.touched.project_direction && formik.errors.project_direction} + onBlur={formik.handleBlur("project_direction")} + /> + + + + + + + + + + + + + ); +}; +export default BuildProjectInfo; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildRealPersonalInfo.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildRealPersonalInfo.jsx new file mode 100644 index 0000000..fd9941c --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildRealPersonalInfo.jsx @@ -0,0 +1,605 @@ +import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import SelectBox from "@/core/components/SelectBox"; +import * as React from "react"; +import useActivityType from "@/lib/app/hooks/useActivityType"; +import { useTranslations } from "next-intl"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import UseEducations from "@/lib/app/hooks/useEducations"; +import useOccupations from "@/lib/app/hooks/useOccupations"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import { useEffect } from "react"; +import useCities from "@/lib/app/hooks/useCities"; + +const BuildRealPersonalInfo = ({ + state, + handleNext, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + const { activityType, isLoadingActivityType, errorActivityType } = useActivityType(); + const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations(); + const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations(); + const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities(); + + const initialValues = { + person_type: state.person_type, + province_id: state.province_id, + city_id: state.city_id, + father_name: state.father_name, + telephone_number: state.telephone_number, + activity_type_id: state.activity_type_id, + refahi_type: state.refahi_type, + gender: state.gender, + welfare_complex_degree: state.welfare_complex_degree, + first_name: state.first_name, + last_name: state.last_name, + education_id: state.education_id, + occupation_id: state.occupation_id, + national_id: state.national_id, + national_serial_number: state.national_serial_number, + national_card_tracking_code: state.national_card_tracking_code, + national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code, + postal_code: state.postal_code, + address: state.address, + birthday: state.birthday, + }; + + const validationSchema = Yup.object().shape({ + province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), + city_id: Yup.string().required(t("LoanRequest.error_message_city_id")), + telephone_number: Yup.mixed() + .test("max", `${t("LoanRequest.tel_number_max")}`, (value) => { + const stringValue = String(value); + return stringValue.length === 11; + }) + .required(t("LoanRequest.error_message_tel_number")), + activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")), + gender: Yup.string().required(t("LoanRequest.error_message_gender")), + welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")), + first_name: Yup.string().required(t("LoanRequest.error_message_first_name")), + last_name: Yup.string().required(t("LoanRequest.error_message_last_name")), + occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")), + education_id: Yup.string().required(t("LoanRequest.error_message_education_id")), + national_id: Yup.mixed() + .test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value)) + .test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0) + .test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_national_id")), + national_serial_number: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_serial_number" + ? schema + .test( + "max", + `${t("LoanRequest.national_serial_number_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_shenasname_serial")) + : schema; + } + ), + national_card_tracking_code: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_card_tracking_code" + ? schema + .test( + "max", + `${t("LoanRequest.national_tracking_code_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_tracking_code")) + : schema; + } + ), + address: Yup.string().required(t("LoanRequest.error_message_address")), + birthday: Yup.string().required(t("LoanRequest.error_message_date_of_birth")), + postal_code: Yup.mixed() + .test("max", `${t("LoanRequest.postal_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_postal_code")), + father_name: Yup.string().required(t("LoanRequest.error_message_father_name")), + }); + const handleSubmit = async (values) => { + dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values }); + handleNext(); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + useEffect(() => { + if (formik.values.province_id === "") return; + setProvinceID(formik.values.province_id); + }, [formik.values.province_id]); + return ( + <> + + + + + + { + formik.setFieldValue("activity_type_id", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)} + helperText={formik.touched.activity_type_id && formik.errors.activity_type_id} + onBlur={formik.handleBlur("activity_type_id")} + /> + + + + + { + if (value === null) return; + formik.handleChange({ + target: { + name: "national_serial_number_or_tracking_code", + value: value, + }, + }); + }} + > + + {t("LoanRequest.text_field_shenasname_serial")} + + + {t("LoanRequest.text_field_national_trackin_code")} + + + + {formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? ( + + { + const inputValue = e.target.value; + const regex = /^[A-Za-z0-9]*$/; + if (regex.test(inputValue)) { + formik.setFieldValue("national_serial_number", inputValue); + } + }} + onBlur={formik.handleBlur("national_serial_number")} + error={ + formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number) + } + helperText={formik.touched.national_serial_number && formik.errors.national_serial_number} + /> + + ) : ( + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_card_tracking_code", + value: inputValue, + }, + }); + }} + onBlur={formik.handleBlur("national_card_tracking_code")} + error={ + formik.touched.national_card_tracking_code && + Boolean(formik.errors.national_card_tracking_code) + } + helperText={ + formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code + } + /> + + )} + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_id", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_national_code")} + placeholder={t("LoanRequest.text_field_enter_your_national_code")} + onBlur={formik.handleBlur("national_id")} + error={formik.touched.national_id && Boolean(formik.errors.national_id)} + helperText={formik.touched.national_id && formik.errors.national_id} + fullWidth + /> + + + + + + + + + + + + + { + formik.setFieldValue("province_id", event.target.value); + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", ""); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.province_id && Boolean(formik.errors.province_id)} + helperText={formik.touched.province_id && formik.errors.province_id} + onBlur={formik.handleBlur("province_id")} + /> + + + 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("gender", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.gender && Boolean(formik.errors.gender)} + helperText={formik.touched.gender && formik.errors.gender} + onBlur={formik.handleBlur("gender")} + /> + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "postal_code", + value: inputValue, + }, + }); + }} + size="small" + label={t("LoanRequest.text_field_postal_code")} + placeholder={t("LoanRequest.text_field_enter_your_postal_code")} + fullWidth + onBlur={formik.handleBlur("postal_code")} + error={formik.touched.postal_code && Boolean(formik.errors.postal_code)} + helperText={formik.touched.postal_code && formik.errors.postal_code} + /> + + + { + 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("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("welfare_complex_degree", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)} + helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree} + onBlur={formik.handleBlur("welfare_complex_degree")} + /> + + + + + + + + + + + + + ); +}; +export default BuildRealPersonalInfo; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildRequestDetail.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildRequestDetail.jsx new file mode 100644 index 0000000..443a105 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildRequestDetail.jsx @@ -0,0 +1,464 @@ +import { Button, Checkbox, FormControlLabel, FormHelperText, Grid, Stack, TextField, Typography } from "@mui/material"; +import PriceField from "@/core/components/PriceField"; +import * as React from "react"; +import { useTranslations } from "next-intl"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import * as Yup from "yup"; +import { useFormik } from "formik"; +import PickerWithDynamicField from "@/core/components/EditedDatePicker"; +import UploadImage from "./UploadImage"; +import { useRequest, useUser } from "@witel/webapp-builder"; +import { SEND_LOAN_REQUEST_REFAHI } from "@/core/data/apiRoutes"; +import { useState } from "react"; +import { useRouter } from "next/router"; + +const BuildRequestDetail = ({ state, handleBack, setFinishRefahiLoanRequest, dispatch }) => { + const t = useTranslations(); + const [submitting, setSubmitting] = useState(false); + const requestServer = useRequest(); + const { getUser, changeUser } = useUser(); + const router = useRouter(); + + const initialValues = { + requested_facility_amount: state.requested_facility_amount, + person_share: state.person_share, + investment_amount: state.investment_amount, + basic_approval_renewal_date: state.basic_approval_renewal_date, + basic_approval_number: state.basic_approval_number, + basic_approval_renewal_image: state.basic_approval_renewal_image, + user_committed_employment: state.user_committed_employment, + user_existing_employment: state.user_existing_employment, + basic_approval_image: state.basic_approval_image, + project_physical_progress: state.project_physical_progress, + checkedBox: state.checkedBox, + facility_usage_history: state.facility_usage_history, + }; + + const validationSchema = Yup.object().shape({ + requested_facility_amount: Yup.string().required(t("LoanRequest.error_message_requested_facilities")), + person_share: Yup.string().required(t("LoanRequest.error_message_applicant_payment")), + investment_amount: Yup.string().required(t("LoanRequest.error_message_money_investment")), + basic_approval_number: Yup.string().required(t("LoanRequest.error_message_principle_agreement_number")), + basic_approval_renewal_date: Yup.string().required(t("LoanRequest.error_message_basic_approval_renewal_date")), + project_physical_progress: Yup.number() + .min(40, t("LoanRequest.error_message_progress_min_40")) + .max(100, t("LoanRequest.error_message_progress_max_100")) + .required(t("LoanRequest.error_message_progress_percentage")), + user_committed_employment: Yup.string().required(t("LoanRequest.error_message_user_committed_employment")), + user_existing_employment: Yup.string().required(t("LoanRequest.error_message_user_existing_employment")), + basic_approval_renewal_image: Yup.mixed() + .required(t("RefahiLoanRequest.upload_principle_agreement_img_required")) + .test("fileSize", `${t("RefahiLoanRequest.upload_principle_agreement_img_unit")}`, (value) => { + return value.size <= 2 * 1024 * 1024; + }) + .test("fileType", `${t("RefahiLoanRequest.upload_principle_agreement_img_format")}`, (value) => { + const allowedTypes = ["image/jpg", "image/jpeg", "image/png"]; + return allowedTypes.includes(value.type); + }), + basic_approval_image: Yup.mixed() + .required(t("RefahiLoanRequest.upload_refresh_date_img_required")) + .test("fileSize", `${t("RefahiLoanRequest.upload_principle_agreement_img_unit")}`, (value) => { + return value.size <= 2 * 1024 * 1024; + }) + .test("fileType", `${t("RefahiLoanRequest.upload_principle_agreement_img_format")}`, (value) => { + const allowedTypes = ["image/jpg", "image/jpeg", "image/png"]; + return allowedTypes.includes(value.type); + }), + checkedBox: Yup.boolean() + .oneOf([true], t("LoanRequest.checkbox_required")) + .required(t("LoanRequest.checkbox_required")), + }); + + const handleSubmit = async (values) => { + let updatedState = { ...state, ...values }; + dispatch({ type: "SET_REQUEST_INFO", requestInfo: values }); + const formData = new FormData(); + const is_legal_person = updatedState.person_type === "real" ? 0 : 1; + delete updatedState.person_type; + if (updatedState.national_serial_number_or_tracking_code === "national_serial_number") { + formData.append("national_serial_number", updatedState.national_serial_number); + delete updatedState.national_card_tracking_code; + } else { + formData.append("national_tracking_code", updatedState.national_card_tracking_code); + delete updatedState.national_serial_number; + } + delete updatedState.national_serial_number_or_tracking_code; + delete updatedState.checkedBox; + formData.append("is_legal_person", is_legal_person); + + updatedState = { + ...updatedState, + birthday: updatedState.birthday.locale("en").format("YYYY-MM-DD"), + basic_approval_renewal_date: updatedState.basic_approval_renewal_date.locale("en").format("YYYY-MM-DD"), + company_register_date: updatedState.company_register_date + ? updatedState.company_register_date.locale("en").format("YYYY-MM-DD") + : "", + facility_usage_history: updatedState.facility_usage_history ? 1 : 0, + }; + + Object.keys(updatedState).forEach((key) => { + if (updatedState[key] !== null && updatedState[key] !== undefined) { + formData.append(key, updatedState[key]); + } + }); + if (!is_legal_person) { + formData.delete("company_register_date"); + formData.delete("shenase_meli"); + formData.delete("register_number"); + formData.delete("company_name"); + } + + try { + setSubmitting(true); + await requestServer(SEND_LOAN_REQUEST_REFAHI, "post", { + auth: true, + notification: true, + data: formData, + }); + // setFinishRefahiLoanRequest(true); + router.replace("/dashboard/followUp-loan"); + getUser((data) => { + changeUser(data); + }); + } catch (error) { + console.error("Error submitting request:", error); + } finally { + setSubmitting(false); + } + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + + const handleAmountChange = (event) => { + if (!isNaN(event.target.value)) { + formik.setFieldValue("requested_facility_amount", event.target.value).then(() => { + formik.setFieldTouched("person_share", false, false); + formik.setFieldValue("person_share", Math.floor(event.target.value * 0.2)); + }); + } else { + formik.setFieldValue("requested_facility_amount", formik.values.requested_facilities); + } + }; + return ( + <> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "investment_amount", + value: inputValue, + }, + }); + }} + onBlur={formik.handleBlur("investment_amount")} + error={formik.touched.investment_amount && Boolean(formik.errors.investment_amount)} + helperText={formik.touched.investment_amount && formik.errors.investment_amount} + fullWidth + /> + + + + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "user_committed_employment", + value: inputValue, + }, + }); + }} + fullWidth + helperText={ + formik.touched.user_committed_employment ? formik.errors.user_committed_employment : null + } + onBlur={formik.handleBlur("user_committed_employment")} + /> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "user_existing_employment", + value: inputValue, + }, + }); + }} + fullWidth + helperText={ + formik.touched.user_existing_employment ? formik.errors.user_existing_employment : null + } + onBlur={formik.handleBlur("user_existing_employment")} + /> + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "project_physical_progress", + value: inputValue, + }, + }); + }} + fullWidth + helperText={ + formik.touched.project_physical_progress ? formik.errors.project_physical_progress : null + } + onBlur={formik.handleBlur("project_physical_progress")} + /> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "basic_approval_number", + value: inputValue, + }, + }); + }} + fullWidth + helperText={formik.touched.basic_approval_number ? formik.errors.basic_approval_number : null} + onBlur={formik.handleBlur("basic_approval_number")} + /> + + + + + + + + + + {t("RefahiLoanRequest.upload_principle_agreement_img")} + + + + + + + + {t("RefahiLoanRequest.upload_refresh_date_img")} + + + + + + + + { + formik.setFieldValue("facility_usage_history", event.target.checked); + }} + /> + } + label={`${t("LoanRequest.history_facilities")}`} + /> + + + + + { + formik.setFieldValue("checkedBox", event.target.checked); + }} + onBlur={formik.handleBlur("checkedBox")} + /> + } + label={`${t("LoanRequest.checkbox")}`} + /> + + {formik.touched.checkedBox && formik.errors.checkedBox ? formik.errors.checkedBox : null} + + + + + + + + + ); +}; +export default BuildRequestDetail; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildToggleRealLegal.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildToggleRealLegal.jsx new file mode 100644 index 0000000..457f46d --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/BuildToggleRealLegal.jsx @@ -0,0 +1,54 @@ +import { useState } from "react"; +import { Stack, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import { useTranslations } from "next-intl"; +import BuildLegalPersonalInfo from "./BuildLegalPersonalInfo"; +import BuildRealPersonalInfo from "./BuildRealPersonalInfo"; + +const BuldToggleRealLegal = ({ + state, + handleNext, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + return ( + <> + + { + if (value === null) return; + dispatch({ type: "SET_PERSON_TYPE", person_type: value }); + }} + > + {t("LoanRequest.real_person")} + {t("LoanRequest.legal_person")} + + + {state.person_type === "real" ? ( + + ) : ( + + )} + + ); +}; +export default BuldToggleRealLegal; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/UploadImage.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/UploadImage.jsx new file mode 100644 index 0000000..9a4c2e8 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/UploadImage.jsx @@ -0,0 +1,51 @@ +import UploadSystem from "@/core/components/UploadSystem"; +import * as React from "react"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import { useState } from "react"; +import { useTranslations } from "next-intl"; +import { FormHelperText, Stack } from "@mui/material"; + +const UploadImage = ({ formik, fieldName }) => { + const t = useTranslations(); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setFileType] = useState(null); + const [fileName, setFileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(t); + event.target.value = ""; + return; + } + + const fileType = event.target?.files?.[0].type; + const fileName = event.target?.files?.[0].name; + setSelectedImage(URL.createObjectURL(uploadedFile)); + setFileType(fileType); + setFileName(fileName); + formik.setFieldValue(fieldName, uploadedFile); + setShowAddIcon(false); + } + }; + return ( + <> + + + {formik.touched[fieldName] && formik.errors[fieldName]} + + + ); +}; +export default UploadImage; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/index.jsx b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/index.jsx new file mode 100644 index 0000000..5ff93c7 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/BuildForm/index.jsx @@ -0,0 +1,123 @@ +import { useReducer, useState } from "react"; +import { useTranslations } from "next-intl"; +import * as React from "react"; +import { Stack, Step, StepLabel, Stepper } from "@mui/material"; +import BuldToggleRealLegal from "./BuildToggleRealLegal"; +import BuildProjectInfo from "./BuildProjectInfo"; +import BuildRequestDetail from "./BuildRequestDetail"; +import useLimitedProvince from "@/lib/app/hooks/useLimitedProvince"; + +const _data = { + person_type: "real", + telephone_number: "", + activity_type_id: "", + refahi_type: 1, + requested_facility_amount: "", + person_share: "", + user_existing_employment: "", + user_committed_employment: "", + father_name: "", + gender: "", + welfare_complex_degree: "", + first_name: "", + last_name: "", + city_id: "", + project_city_id: "", + province_id: "", + project_province_id: "", + education_id: "", + occupation_id: "", + national_id: "", + national_serial_number: "", + national_card_tracking_code: "", + national_serial_number_or_tracking_code: "national_serial_number", + postal_code: "", + address: "", + birthday: "", + investment_amount: "", + basic_approval_renewal_date: "", + project_axis: "", + project_physical_progress: "", + project_kilometer_marker: "", + project_direction: "", + project_address: "", + basic_approval_number: "", + basic_approval_renewal_image: null, + basic_approval_image: null, + checkedBox: false, + facility_usage_history: false, + company_register_date: "", + shenase_meli: "", + register_number: "", + company_name: "", +}; + +const reducer = (state, action) => { + switch (action.type) { + case "SET_PERSONAL_INFO": + return { ...state, ...action.personalInfo }; + case "SET_PROJECT_INFO": + return { ...state, ...action.projectInfo }; + case "SET_REQUEST_INFO": + return { ...state, ...action.requestInfo }; + case "SET_PERSON_TYPE": + return { ...state, person_type: action.person_type }; + default: + return state; + } +}; + +const BuildForm = ({ setFinishRefahiLoanRequest }) => { + const t = useTranslations(); + const [activeStep, setActiveStep] = useState(0); + const [state, dispatch] = useReducer(reducer, _data); + const { provinceList, isLoadingProvinceList, errorProvinceList } = useLimitedProvince(); + const steps = [ + t("RefahiLoanRequest.step_personal_info"), + t("RefahiLoanRequest.step_project_info"), + t("RefahiLoanRequest.step_contact_info"), + ]; + const handleNext = () => setActiveStep((prev) => prev + 1); + const handleBack = () => setActiveStep((prev) => prev - 1); + return ( + + + {steps.map((label, index) => ( + + {label} + + ))} + + {activeStep === 0 && ( + + )} + {activeStep === 1 && ( + + )} + {activeStep === 2 && ( + + )} + + ); +}; +export default BuildForm; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/CheckRules.jsx b/src/components/dashboard/refahi/add-request-loan/forms/CheckRules.jsx new file mode 100644 index 0000000..1753adc --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/CheckRules.jsx @@ -0,0 +1,243 @@ +import { Box, Button, Checkbox, FormControlLabel, FormGroup, Link, Stack, Typography } from "@mui/material"; +import { CenterLayout } from "@witel/webapp-builder"; +import { useTranslations } from "next-intl"; +import { useState } from "react"; +import DownloadIcon from "@mui/icons-material/Download"; + +const CheckRules = ({ setRulesChecked }) => { + const t = useTranslations(); + const [rulesAccepted, setRulesAccepted] = useState(false); + + const rules = [ + { + title: "ضوابط و اسناد بالادستی", + subtitles: [ + "قرارداد عاملیت سه جانبه فیمابین وزارت امور اقتصادی و دارائی، وزارت راه و شهرسازی وصندوق کارآفرینی امید ودستورالعمل اجرائی بند (الف)تبصره 18 قانون بودجه سال 1402", + ], + }, + { + title: "شرح خدمات تفاهم نامه", + subtitles: [ + "اعطای تسهيلات تلفیقی،کمک های فنی و اعتباری و یارانه سود به اشخاص حقیقی وحقوقی، بخش های خصوصي غیردولتی و تعاونی های واجد شرایط در زمينه بازسازی ناوگان حمل و نقل مسافر واحداث و مرمت مجتمع های خدماتی و رفاهی", + ], + }, + { + title: "حوزه جغرافیایی", + subtitles: ["کل کشور"], + }, + { + title: "نحوه فراخوان", + subtitles: [ + "فراخوان متقاضيان مي بايست بصورت مستند (نظير چاپ در روزنامه رسمي و غيره )كه قابل ارايه به نهادهاي نظارتي باشد صورت پذيرد.", + ], + }, + { + title: "نحوه شناسایی و پذیرش متقاضیان", + subtitles: ["ثبت نام در سامانه مديريت درخواست تسهیلات به آدرس t18.rmto.ir و تایید کارگروه استانی"], + }, + { + title: "بررسی مقدماتی اهلیت متقاضیان", + subtitles: [ + "عدم دریافت تسهیلات از محل تبصره (18) قانون بودجه سنوات قبل", + "صرفاٌ به صورت آنلاین و از طریق سامانه مديريت درخواست تسهیلات به آدرس t18.rmto.ir و سامانه اسمارت صندوق کارآفرینی امید.", + "شرایط سنی: 18 تا 70 سال (با احتساب دوره باز پرداخت اقساط تسهیلات اعطایی) در خصوص متقاضیان بیش از 70 تا 80 سال ،منوط به رعایت ضوابط جاری صندوق و اخذ موافقت کتبی از مدیریت اعتبارات صندوق.", + "نداشتن بدهی غیر جاری (استعلام سامانه سمات)در شبکه بانکی و صندوق کارآفرینی امید و چک برگشتی در شبکه بانکی.", + ], + }, + { + title: "شرایط اختصاصی", + subtitles: [ + { + title: "در حال احداث", + subtitles: [ + "موافقت اصولی دارای اعتبار", + "پیشرفت فیزیکی بیش از 40 درصد ( اولویت با طرح هایی است که با دریافت تسهیلات، طرح قابل بهره برداری و افتتاح باشد.)", + "تقاضاي كتبي مالك براي استفاده از تسهيلات تبصره 18 به منظور احداث و یا مرمت مجتمع (لازم بذكر است چنانچه مالك بيش از يكنفر باشد ، رضايت محضري مابقي سهامداران براي استفاده از تسهيلات ضروري مي باشد)", + " داراي موافقت اصولي وتمديدي معتبر وداشتن پيشرفت فيزيكي بالاي 40درصد ", + "سرمایه گذاران مجتمع های خدماتی رفاهی و تیرپارکها از تاریخ شروع عملیات اجرایی نسبت به احداث اقدام می نمایند و ارائه تسهیلات پس از پیشرفت فیزیکی 40 درصد به ازای هر پروژه صورت خواهد پذیرفت که 40 درصد مبلغ تسهیلات در نظر گرفته شده همزمان با 40 درصد پیشرفت فیزیکی و مابقی در سه مرحله و به ازای افزایش 20 درصدی نسبت به پیشرفت فیزیکی قبلی پرداخت خواهد شد.", + "مبلغ تسهیلات برای احداث حداکثر 50میلیارد ریال می باشد.", + ], + }, + { + title: "مرمت و بازسازی", + subtitles: [ + "جهت پرداخت تسهیلات در این زمینه، میبایست تاریخ بهره برداری آنها قبل از 1390/1/1 باشد.)", + "تسهیلات با اولویت بهسازی و مرمت نمازخانه ها و سرویس های بهداشتی واقع در مجتمع های خدماتی رفاهی صورت می پذیرد.", + "با توجه به اینکه مجتمع های خدماتی رفاهی و تیرپارکها در حال بهره برداری می باشند از تاریخ پرداخت تسهیلات نسبت به انجام مرمت ، بازسازی ، بهسازی و یا توسعه آن اقدام خواهد گردید.", + "مبلغ تسهیلات برای بهسازی و مرمت حداکثر10 میلیارد ریال می باشد.", + ], + }, + ], + }, + { + title: "تکمیل پرونده", + subtitles: [ + "اعلام مدارک مورد نیاز به متقاضیان توسط موسسه عامل و تکمیل مدارک و مستندات مذکور توسط متقاضی ظرف 15 روز کاری.", + "بررسی توجیه اقتصادی و مالی طرح و تصویب در کمیته اعتباری و اعلام پذیرش یا رد ظرف 15 روز کاری.", + "انعقاد قرارداد با متقاضی و پرداخت تسهیلات منوط به تامین وثیقه و آورده از سوی متقاضی ظرف 15 روز کاری.", + "اخذ تعهد اشتغال از متقاضیان جهت امکان برخورد قانونی با متقاضی درصورت عدم ایفای تعهد.", + ], + }, + { + title: "وصایق و تضامین", + subtitles: ["مطابق با آخرین ضوابط و مقررات جاری صندوق ."], + }, + { + title: "سهم آورنده", + subtitles: [ + "سهم آورده متقاضیان مشمول و واجد شرایط بهره مندی از تسهیلات ماده (7) وفق ضوابط و مقررات جاری صندوق، دستورالعمل ها و بخشنامه های بانک مرکزی جمهوری اسلامی به میزان حداقل بیست درصد (20%) تعيين می گردد.", + ], + }, + { + title: "نرخ سود", + subtitles: [ + { + title: "نرخ سود تسهیلات اعطایی مطابق ماده 10 این قرارداد 15.3٪ می باشد.", + subtitles: [ + "اشتغال ثابت: مناطق غیر برخوردار و مرزی :13درصد و مناطق برخوردار: 15درصد", + "سرمایه در گردش: مناطق غیر برخوردار و مرزی : 18 درصد و مناطق بر خوردار: 20درصد", + ], + }, + ], + }, + { + title: "هزینه ها", + subtitles: [ + "کلیه هزینه‌های مرتب بر تنظیم و عقد قراردادها (اعم از خرید سفته، هزینه عقد قرارداد در دفاتر رسمی و چه به‌صورت رسمی و چه به‌صورت تنظیمی داخلی و عادی) به عهده متقاضی است.", + ], + }, + { + title: "بازپرداخت", + subtitles: ["دوره مشارکت حداکثر 6 ماهه ، تنفس حداکثر 4 ماهه و دوره بازپرداخت تسهیلات سرمایه 5 سال است."], + }, + { + title: "واریز تسهیلات", + subtitles: [ + "واريز مبلغ تسهيلات توسط بانك و ثبت در سامانه به صورت مرحله ای و با توجه به پیشرفت پروژه خواهد بود", + ], + }, + { + title: "نظارت", + subtitles: [ + "مطابق ماده 24 قرارداد عاملیت، نظارت و تایید تحقق اهداف موضوع اعطای تسهیلات و اعلام آن به «صندوق» حداکثر تا شش ماه پس از اتمام طرح (بابت اخذ تسهیلات از محل این قرارداد) بر عهده «واگذارنده اعتبار» (کمیته استانی نظارت) می‌باشد. در صورت اعلام «واگذارنده اعتبار» مبنی بر عدم تایید مراتب به «صندوق»، یارانه سود و تخفیفات مربوطه مشمول طرح نگردیده و متقاضی ملزم به پرداخت مابه‌التفاوت نرخ سود سهم «واگذارنده اعتبار» و نرخ سود تسهیلات مصوب شورای پول و اعتبار و وجه التزام مربوطه خواهد بود.", + ], + }, + { + title: "پیگیری بازپرداخت اصل ‌و فرع", + subtitles: [ + "مطابق مواد 26 و 27 قرارداد عاملیت مسئولیت پیگیری بازپرداخت اصل ‌و فرع مجموع تسهیلات موضوع این قرارداد و انجام اقدامات قانونی برای وصول مانده مطالبات معوق تا پایان تسویه‌ حساب نهایی به عهده «صندوق» است. همچنین پرداخت هزینه های اجرایی و خسارات دادرسی (شامل: هزینه دادرسی، حق‌الوکاله وکیل و غیره) در صورت تعویق اقساط تسهیلات پرداختی، بر عهده متقاضی تسهیلات است.", + ], + }, + ]; + + const renderRuleContent = (content, index) => { + if (typeof content === "string") { + return ( + + {content} + + ); + } + return ( + + + {content.title} + + + {content.subtitles.map((sub, subIndex) => renderRuleContent(sub, subIndex))} + + + ); + }; + + return ( + + + + {t("LoanRequest.accept_rules_title")} + + + {rules.map((rule, index) => ( + + + {rule.title} + +
    + {rule.subtitles.map((sub, index) => renderRuleContent(sub, index))} +
+
+ ))} +
+ + + مستندات + + + + + + + setRulesAccepted(e.target.checked)} + /> + } + label={t("LoanRequest.accept_all_rules")} + sx={{ + textAlign: "center", + "& .MuiTypography-root": { + fontSize: "1rem", // Adjust font size + fontWeight: 500, // Adjust font weight (e.g., 400 for normal, 700 for bold) + }, + }} + /> + + + + + +
+
+ ); +}; +export default CheckRules; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreLegalPersonalInfo.jsx b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreLegalPersonalInfo.jsx new file mode 100644 index 0000000..12d1c54 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreLegalPersonalInfo.jsx @@ -0,0 +1,710 @@ +import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import SelectBox from "@/core/components/SelectBox"; +import * as React from "react"; +import useActivityType from "@/lib/app/hooks/useActivityType"; +import { useTranslations } from "next-intl"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import UseEducations from "@/lib/app/hooks/useEducations"; +import useOccupations from "@/lib/app/hooks/useOccupations"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import { useEffect } from "react"; +import useCities from "@/lib/app/hooks/useCities"; +import LegalPersonDatePicker from "@/core/components/LegalPersonDatePicker"; + +const RestoreLegalPersonalInfo = ({ + state, + handleNext, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + const { activityType, isLoadingActivityType, errorActivityType } = useActivityType(); + const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations(); + const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations(); + const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities(); + + const initialValues = { + person_type: state.person_type, + province_id: state.province_id, + city_id: state.city_id, + father_name: state.father_name, + telephone_number: state.telephone_number, + activity_type_id: state.activity_type_id, + refahi_type: state.refahi_type, + gender: state.gender, + welfare_complex_degree: state.welfare_complex_degree, + first_name: state.first_name, + last_name: state.last_name, + education_id: state.education_id, + occupation_id: state.occupation_id, + national_id: state.national_id, + national_serial_number: state.national_serial_number, + national_card_tracking_code: state.national_card_tracking_code, + national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code, + postal_code: state.postal_code, + address: state.address, + birthday: state.birthday, + company_register_date: state.company_register_date, + shenase_meli: state.shenase_meli, + register_number: state.register_number, + company_name: state.company_name, + }; + + const validationSchema = Yup.object().shape({ + province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), + city_id: Yup.string().required(t("LoanRequest.error_message_city_id")), + telephone_number: Yup.mixed() + .test("max", `${t("LoanRequest.company_tel_number_max")}`, (value) => { + const stringValue = String(value); + return stringValue.length === 11; + }) + .required(t("LoanRequest.error_message_company_tel_number")), + activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")), + gender: Yup.string().required(t("LoanRequest.error_message_boss_gender")), + welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")), + first_name: Yup.string().required(t("LoanRequest.error_message_boss_first_name")), + last_name: Yup.string().required(t("LoanRequest.error_message_boss_last_name")), + occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")), + education_id: Yup.string().required(t("LoanRequest.error_message_education_id")), + national_id: Yup.mixed() + .test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value)) + .test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0) + .test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_boss_national_id")), + national_serial_number: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_serial_number" + ? schema + .test( + "max", + `${t("LoanRequest.national_serial_number_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_boss_shenasname_serial")) + : schema; + } + ), + national_card_tracking_code: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_card_tracking_code" + ? schema + .test( + "max", + `${t("LoanRequest.national_tracking_code_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_boss_national_card_tracking_code")) + : schema; + } + ), + address: Yup.string().required(t("LoanRequest.error_message_address")), + birthday: Yup.string().required(t("LoanRequest.error_message_boss_date_of_birth")), + postal_code: Yup.mixed() + .test("max", `${t("LoanRequest.company_postal_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_company_postal_code")), + father_name: Yup.string().required(t("LoanRequest.error_message_boss_father_name")), + shenase_meli: Yup.mixed().when("person_type", ([person_type], schema) => { + return person_type === "legal" + ? schema + .test("is-number", `${t("LoanRequest.national_number_number")}`, (value) => !isNaN(value)) + .test("positive", `${t("LoanRequest.national_number_positive")}`, (value) => value >= 0) + .test( + "max", + `${t("LoanRequest.national_number_max")}`, + (value) => value && value.toString().length === 11 + ) + .required(t("LoanRequest.error_message_national_number")) + : schema; + }), + company_register_date: Yup.string().required(t("LoanRequest.error_message_company_date")), + register_number: Yup.string().required(t("LoanRequest.error_message_register_number")), + company_name: Yup.string().required(t("LoanRequest.error_message_company_name")), + }); + const handleSubmit = async (values) => { + dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values }); + handleNext(); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + useEffect(() => { + if (formik.values.province_id === "") return; + setProvinceID(formik.values.province_id); + }, [formik.values.province_id]); + return ( + <> + + + + + + { + formik.setFieldValue("activity_type_id", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)} + helperText={formik.touched.activity_type_id && formik.errors.activity_type_id} + onBlur={formik.handleBlur("activity_type_id")} + /> + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "shenase_meli", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_national_number")} + placeholder={t("LoanRequest.text_field_enter_your_national_number")} + onBlur={formik.handleBlur("shenase_meli")} + error={formik.touched.shenase_meli && Boolean(formik.errors.shenase_meli)} + helperText={formik.touched.shenase_meli && formik.errors.shenase_meli} + fullWidth + /> + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "register_number", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_register_number")} + placeholder={t("LoanRequest.text_field_enter_your_register_number")} + onBlur={formik.handleBlur("register_number")} + error={formik.touched.register_number && Boolean(formik.errors.register_number)} + helperText={formik.touched.register_number && formik.errors.register_number} + fullWidth + /> + + + + + { + if (value === null) return; + formik.handleChange({ + target: { + name: "national_serial_number_or_tracking_code", + value: value, + }, + }); + }} + > + + {t("LoanRequest.text_field_shenasname_serial")} + + + {t("LoanRequest.text_field_national_trackin_code")} + + + + {formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? ( + + { + const inputValue = e.target.value; + const regex = /^[A-Za-z0-9]*$/; + if (regex.test(inputValue)) { + formik.setFieldValue("national_serial_number", inputValue); + } + }} + onBlur={formik.handleBlur("national_serial_number")} + error={ + formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number) + } + helperText={formik.touched.national_serial_number && formik.errors.national_serial_number} + /> + + ) : ( + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_card_tracking_code", + value: inputValue, + }, + }); + }} + onBlur={formik.handleBlur("national_card_tracking_code")} + error={ + formik.touched.national_card_tracking_code && + Boolean(formik.errors.national_card_tracking_code) + } + helperText={ + formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code + } + /> + + )} + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_id", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_boss_national_code")} + placeholder={t("LoanRequest.text_field_enter_your_boss_national_code")} + onBlur={formik.handleBlur("national_id")} + error={formik.touched.national_id && Boolean(formik.errors.national_id)} + helperText={formik.touched.national_id && formik.errors.national_id} + fullWidth + /> + + + + + + + + + + + + + { + formik.setFieldValue("province_id", event.target.value); + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", ""); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.province_id && Boolean(formik.errors.province_id)} + helperText={formik.touched.province_id && formik.errors.province_id} + onBlur={formik.handleBlur("province_id")} + /> + + + 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("gender", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.gender && Boolean(formik.errors.gender)} + helperText={formik.touched.gender && formik.errors.gender} + onBlur={formik.handleBlur("gender")} + /> + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "postal_code", + value: inputValue, + }, + }); + }} + size="small" + label={t("LoanRequest.text_field_company_postal_code")} + placeholder={t("LoanRequest.text_field_enter_your_company_postal_code")} + fullWidth + onBlur={formik.handleBlur("postal_code")} + error={formik.touched.postal_code && Boolean(formik.errors.postal_code)} + helperText={formik.touched.postal_code && formik.errors.postal_code} + /> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "telephone_number", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_company_tel_number")} + placeholder={t("LoanRequest.text_field_enter_your_company_tel_number")} + fullWidth + onBlur={formik.handleBlur("telephone_number")} + error={formik.touched.telephone_number && Boolean(formik.errors.telephone_number)} + helperText={formik.touched.telephone_number && formik.errors.telephone_number} + /> + + + + + + + + { + 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("welfare_complex_degree", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)} + helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree} + onBlur={formik.handleBlur("welfare_complex_degree")} + /> + + + + + + + + + + + + + ); +}; +export default RestoreLegalPersonalInfo; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreProjectInfo.jsx b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreProjectInfo.jsx new file mode 100644 index 0000000..978912f --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreProjectInfo.jsx @@ -0,0 +1,232 @@ +import { Button, Grid, Stack, TextField } from "@mui/material"; +import SelectBox from "@/core/components/SelectBox"; +import * as React from "react"; +import { useTranslations } from "next-intl"; +import * as Yup from "yup"; +import { useFormik } from "formik"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import { useEffect } from "react"; +import useCities from "@/lib/app/hooks/useCities"; + +const RestoreProjectInfo = ({ + state, + handleNext, + handleBack, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + const { cityList, setProvinceID, isLoadingCityList } = useCities(); + + const initialValues = { + project_province_id: state.project_province_id, + project_city_id: state.project_city_id, + project_axis: state.project_axis, + project_kilometer_marker: state.project_kilometer_marker, + project_direction: state.project_direction, + project_address: state.project_address, + }; + const validationSchema = Yup.object().shape({ + project_province_id: Yup.string().required(t("LoanRequest.error_message_project_province_id")), + project_city_id: Yup.string().required(t("LoanRequest.error_message_project_city_id")), + project_address: Yup.string().required(t("LoanRequest.error_message_execution_address")), + project_axis: Yup.string().required(t("LoanRequest.error_message_mehvar")), + project_kilometer_marker: Yup.string().required(t("LoanRequest.error_message_kilometer")), + project_direction: Yup.string().required(t("LoanRequest.error_message_samt")), + }); + const handleSubmit = async (values) => { + dispatch({ type: "SET_PROJECT_INFO", projectInfo: values }); + handleNext(); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + + useEffect(() => { + if (formik.values.project_province_id === "") return; + setProvinceID(formik.values.project_province_id); + }, [formik.values.project_province_id]); + + return ( + <> + + + { + formik.setFieldValue("project_province_id", event.target.value); + formik.setFieldTouched("project_city_id", false, false); + formik.setFieldValue("project_city_id", ""); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.project_province_id && Boolean(formik.errors.project_province_id)} + helperText={formik.touched.project_province_id && formik.errors.project_province_id} + onBlur={formik.handleBlur("project_province_id")} + /> + + + formik.setFieldValue("project_city_id", event.target.value)} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.project_city_id && Boolean(formik.errors.project_city_id)} + helperText={formik.touched.project_city_id && formik.errors.project_city_id} + onBlur={formik.handleBlur("project_city_id")} + /> + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "project_kilometer_marker", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_kilometer")} + placeholder={t("LoanRequest.text_field_enter_your_kilometer")} + onBlur={formik.handleBlur("project_kilometer_marker")} + error={ + formik.touched.project_kilometer_marker && Boolean(formik.errors.project_kilometer_marker) + } + helperText={formik.touched.project_kilometer_marker && formik.errors.project_kilometer_marker} + fullWidth + /> + + + { + formik.setFieldValue("project_direction", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.project_direction && Boolean(formik.errors.project_direction)} + helperText={formik.touched.project_direction && formik.errors.project_direction} + onBlur={formik.handleBlur("project_direction")} + /> + + + + + + + + + + + + + ); +}; +export default RestoreProjectInfo; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreRealPersonalInfo.jsx b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreRealPersonalInfo.jsx new file mode 100644 index 0000000..43bde48 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreRealPersonalInfo.jsx @@ -0,0 +1,605 @@ +import { Button, Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import SelectBox from "@/core/components/SelectBox"; +import * as React from "react"; +import useActivityType from "@/lib/app/hooks/useActivityType"; +import { useTranslations } from "next-intl"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import UseEducations from "@/lib/app/hooks/useEducations"; +import useOccupations from "@/lib/app/hooks/useOccupations"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import { useEffect } from "react"; +import useCities from "@/lib/app/hooks/useCities"; + +const RestoreRealPersonalInfo = ({ + state, + handleNext, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + const { activityType, isLoadingActivityType, errorActivityType } = useActivityType(); + const { educationsList, isLoadingEducationsList, errorEducationsList } = UseEducations(); + const { occupationsList, isLoadingOccupationsList, errorOccupationsList } = useOccupations(); + const { cityTextField, cityList, setProvinceID, isLoadingCityList } = useCities(); + + const initialValues = { + person_type: state.person_type, + father_name: state.father_name, + province_id: state.province_id, + city_id: state.city_id, + telephone_number: state.telephone_number, + activity_type_id: state.activity_type_id, + refahi_type: state.refahi_type, + gender: state.gender, + welfare_complex_degree: state.welfare_complex_degree, + first_name: state.first_name, + last_name: state.last_name, + education_id: state.education_id, + occupation_id: state.occupation_id, + national_id: state.national_id, + national_serial_number: state.national_serial_number, + national_card_tracking_code: state.national_card_tracking_code, + national_serial_number_or_tracking_code: state.national_serial_number_or_tracking_code, + postal_code: state.postal_code, + address: state.address, + birthday: state.birthday, + }; + + const validationSchema = Yup.object().shape({ + province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), + city_id: Yup.string().required(t("LoanRequest.error_message_city_id")), + telephone_number: Yup.mixed() + .test("max", `${t("LoanRequest.tel_number_max")}`, (value) => { + const stringValue = String(value); + return stringValue.length === 11; + }) + .required(t("LoanRequest.error_message_tel_number")), + activity_type_id: Yup.string().required(t("LoanRequest.error_message_activity_type")), + gender: Yup.string().required(t("LoanRequest.error_message_gender")), + welfare_complex_degree: Yup.string().required(t("LoanRequest.error_message_degree")), + first_name: Yup.string().required(t("LoanRequest.error_message_first_name")), + last_name: Yup.string().required(t("LoanRequest.error_message_last_name")), + occupation_id: Yup.string().required(t("LoanRequest.error_message_occupation_id")), + education_id: Yup.string().required(t("LoanRequest.error_message_education_id")), + national_id: Yup.mixed() + .test("is-number", `${t("LoanRequest.national_code_number")}`, (value) => !isNaN(value)) + .test("positive", `${t("LoanRequest.national_code_positive")}`, (value) => value >= 0) + .test("max", `${t("LoanRequest.national_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_national_id")), + national_serial_number: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_serial_number" + ? schema + .test( + "max", + `${t("LoanRequest.national_serial_number_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_shenasname_serial")) + : schema; + } + ), + national_card_tracking_code: Yup.string().when( + "national_serial_number_or_tracking_code", + ([national_serial_number_or_tracking_code], schema) => { + return national_serial_number_or_tracking_code === "national_card_tracking_code" + ? schema + .test( + "max", + `${t("LoanRequest.national_tracking_code_max")}`, + (value) => value && value.toString().length === 10 + ) + .required(t("LoanRequest.error_message_tracking_code")) + : schema; + } + ), + address: Yup.string().required(t("LoanRequest.error_message_address")), + birthday: Yup.string().required(t("LoanRequest.error_message_date_of_birth")), + postal_code: Yup.mixed() + .test("max", `${t("LoanRequest.postal_code_max")}`, (value) => value.toString().length === 10) + .required(t("LoanRequest.error_message_postal_code")), + father_name: Yup.string().required(t("LoanRequest.error_message_father_name")), + }); + const handleSubmit = async (values) => { + dispatch({ type: "SET_PERSONAL_INFO", personalInfo: values }); + handleNext(); + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + useEffect(() => { + if (formik.values.province_id === "") return; + setProvinceID(formik.values.province_id); + }, [formik.values.province_id]); + return ( + <> + + + + + + { + formik.setFieldValue("activity_type_id", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.activity_type_id && Boolean(formik.errors.activity_type_id)} + helperText={formik.touched.activity_type_id && formik.errors.activity_type_id} + onBlur={formik.handleBlur("activity_type_id")} + /> + + + + + { + if (value === null) return; + formik.handleChange({ + target: { + name: "national_serial_number_or_tracking_code", + value: value, + }, + }); + }} + > + + {t("LoanRequest.text_field_shenasname_serial")} + + + {t("LoanRequest.text_field_national_trackin_code")} + + + + {formik.values.national_serial_number_or_tracking_code === "national_serial_number" ? ( + + { + const inputValue = e.target.value; + const regex = /^[A-Za-z0-9]*$/; + if (regex.test(inputValue)) { + formik.setFieldValue("national_serial_number", inputValue); + } + }} + onBlur={formik.handleBlur("national_serial_number")} + error={ + formik.touched.national_serial_number && Boolean(formik.errors.national_serial_number) + } + helperText={formik.touched.national_serial_number && formik.errors.national_serial_number} + /> + + ) : ( + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_card_tracking_code", + value: inputValue, + }, + }); + }} + onBlur={formik.handleBlur("national_card_tracking_code")} + error={ + formik.touched.national_card_tracking_code && + Boolean(formik.errors.national_card_tracking_code) + } + helperText={ + formik.touched.national_card_tracking_code && formik.errors.national_card_tracking_code + } + /> + + )} + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "national_id", + value: inputValue, + }, + }); + }} + label={t("LoanRequest.text_field_national_code")} + placeholder={t("LoanRequest.text_field_enter_your_national_code")} + onBlur={formik.handleBlur("national_id")} + error={formik.touched.national_id && Boolean(formik.errors.national_id)} + helperText={formik.touched.national_id && formik.errors.national_id} + fullWidth + /> + + + + + + + + + + + + + { + formik.setFieldValue("province_id", event.target.value); + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", ""); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.province_id && Boolean(formik.errors.province_id)} + helperText={formik.touched.province_id && formik.errors.province_id} + onBlur={formik.handleBlur("province_id")} + /> + + + 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("gender", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.gender && Boolean(formik.errors.gender)} + helperText={formik.touched.gender && formik.errors.gender} + onBlur={formik.handleBlur("gender")} + /> + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "postal_code", + value: inputValue, + }, + }); + }} + size="small" + label={t("LoanRequest.text_field_postal_code")} + placeholder={t("LoanRequest.text_field_enter_your_postal_code")} + fullWidth + onBlur={formik.handleBlur("postal_code")} + error={formik.touched.postal_code && Boolean(formik.errors.postal_code)} + helperText={formik.touched.postal_code && formik.errors.postal_code} + /> + + + { + 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("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("welfare_complex_degree", event.target.value); + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.welfare_complex_degree && Boolean(formik.errors.welfare_complex_degree)} + helperText={formik.touched.welfare_complex_degree && formik.errors.welfare_complex_degree} + onBlur={formik.handleBlur("welfare_complex_degree")} + /> + + + + + + + + + + + + + ); +}; +export default RestoreRealPersonalInfo; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreRequestDetail.jsx b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreRequestDetail.jsx new file mode 100644 index 0000000..10115c6 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreRequestDetail.jsx @@ -0,0 +1,413 @@ +import { Button, Checkbox, FormControlLabel, FormHelperText, Grid, Stack, TextField, Typography } from "@mui/material"; +import PriceField from "@/core/components/PriceField"; +import * as React from "react"; +import { useTranslations } from "next-intl"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import * as Yup from "yup"; +import { useFormik } from "formik"; +import PickerWithDynamicField from "@/core/components/EditedDatePicker"; +import UploadImage from "@/components/dashboard/refahi/add-request-loan/forms/BuildForm/UploadImage"; +import { SEND_LOAN_REQUEST_REFAHI } from "@/core/data/apiRoutes"; +import { useState } from "react"; +import { useRequest, useUser } from "@witel/webapp-builder"; +import { useRouter } from "next/router"; + +const RestoreRequestDetail = ({ state, handleBack, dispatch, setFinishRefahiLoanRequest }) => { + const t = useTranslations(); + const [submitting, setSubmitting] = useState(false); + const requestServer = useRequest(); + const { getUser, changeUser } = useUser(); + const router = useRouter(); + + const initialValues = { + requested_facility_amount: state.requested_facility_amount, + person_share: state.person_share, + investment_amount: state.investment_amount, + exploitation_date: state.exploitation_date, + exploitation_license_renewal_date: state.exploitation_license_renewal_date, + user_committed_employment: state.user_committed_employment, + user_existing_employment: state.user_existing_employment, + exploitation_license_image: state.exploitation_license_image, + exploitation_license_renewal_image: state.exploitation_license_renewal_image, + checkedBox: state.checkedBox, + facility_usage_history: state.facility_usage_history, + }; + + const validationSchema = Yup.object().shape({ + requested_facility_amount: Yup.string().required(t("LoanRequest.error_message_requested_facilities")), + person_share: Yup.string().required(t("LoanRequest.error_message_applicant_payment")), + investment_amount: Yup.string().required(t("LoanRequest.error_message_money_investment")), + exploitation_date: Yup.string().required(t("LoanRequest.error_message_operation_date")), + exploitation_license_renewal_date: Yup.string().required(t("LoanRequest.error_message_refresh_date")), + user_committed_employment: Yup.string().required(t("LoanRequest.error_message_user_committed_employment")), + user_existing_employment: Yup.string().required(t("LoanRequest.error_message_user_existing_employment")), + exploitation_license_image: Yup.mixed() + .required(t("RefahiLoanRequest.upload_operating_license_img_required")) + .test("fileSize", `${t("RefahiLoanRequest.upload_operating_license_img_unit")}`, (value) => { + return value.size <= 2 * 1024 * 1024; + }) + .test("fileType", `${t("RefahiLoanRequest.upload_operating_license_img_format")}`, (value) => { + const allowedTypes = ["image/jpg", "image/jpeg", "image/png"]; + return allowedTypes.includes(value.type); + }), + exploitation_license_renewal_image: Yup.mixed() + .required(t("RefahiLoanRequest.upload_refresh_date_img_required")) + .test("fileSize", `${t("RefahiLoanRequest.upload_refresh_date_img_unit")}`, (value) => { + return value.size <= 2 * 1024 * 1024; + }) + .test("fileType", `${t("RefahiLoanRequest.upload_refresh_date_img_format")}`, (value) => { + const allowedTypes = ["image/jpg", "image/jpeg", "image/png"]; + return allowedTypes.includes(value.type); + }), + checkedBox: Yup.boolean() + .oneOf([true], t("LoanRequest.checkbox_required")) + .required(t("LoanRequest.checkbox_required")), + }); + const handleSubmit = async (values, props) => { + let updatedState = { ...state, ...values }; + dispatch({ type: "SET_REQUEST_INFO", requestInfo: values }); + const formData = new FormData(); + const is_legal_person = updatedState.person_type === "real" ? 0 : 1; + delete updatedState.person_type; + if (updatedState.national_serial_number_or_tracking_code === "national_serial_number") { + formData.append("national_serial_number", updatedState.national_serial_number); + delete updatedState.national_card_tracking_code; + } else { + formData.append("national_tracking_code", updatedState.national_card_tracking_code); + delete updatedState.national_serial_number; + } + delete updatedState.national_serial_number_or_tracking_code; + delete updatedState.checkedBox; + formData.append("is_legal_person", is_legal_person); + + updatedState = { + ...updatedState, + birthday: updatedState.birthday.locale("en").format("YYYY-MM-DD"), + exploitation_license_renewal_date: updatedState.exploitation_license_renewal_date + .locale("en") + .format("YYYY-MM-DD"), + exploitation_date: updatedState.exploitation_date.locale("en").format("YYYY-MM-DD"), + company_register_date: updatedState.company_register_date + ? updatedState.company_register_date.locale("en").format("YYYY-MM-DD") + : "", + facility_usage_history: updatedState.facility_usage_history ? 1 : 0, + }; + + Object.keys(updatedState).forEach((key) => { + if (updatedState[key] !== null && updatedState[key] !== undefined) { + formData.append(key, updatedState[key]); + } + }); + if (!is_legal_person) { + formData.delete("company_register_date"); + formData.delete("shenase_meli"); + formData.delete("register_number"); + formData.delete("company_name"); + } + + try { + setSubmitting(true); + await requestServer(SEND_LOAN_REQUEST_REFAHI, "post", { + auth: true, + notification: true, + data: formData, + }); + // setFinishRefahiLoanRequest(true); + router.replace("/dashboard/followUp-loan"); + getUser((data) => { + changeUser(data); + }); + } catch (error) { + console.error("Error submitting request:", error); + } finally { + setSubmitting(false); + } + }; + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: handleSubmit, + }); + + const handleAmountChange = (event) => { + if (!isNaN(event.target.value)) { + formik.setFieldValue("requested_facility_amount", event.target.value).then(() => { + formik.setFieldTouched("person_share", false, false); + formik.setFieldValue("person_share", Math.floor(event.target.value * 0.2)); + }); + } else { + formik.setFieldValue("requested_facility_amount", formik.values.requested_facilities); + } + }; + return ( + <> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "investment_amount", + value: inputValue, + }, + }); + }} + onBlur={formik.handleBlur("investment_amount")} + error={formik.touched.investment_amount && Boolean(formik.errors.investment_amount)} + helperText={formik.touched.investment_amount && formik.errors.investment_amount} + fullWidth + /> + + + + + + + + + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "user_committed_employment", + value: inputValue, + }, + }); + }} + fullWidth + helperText={ + formik.touched.user_committed_employment ? formik.errors.user_committed_employment : null + } + onBlur={formik.handleBlur("user_committed_employment")} + /> + + + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + formik.handleChange({ + target: { + name: "user_existing_employment", + value: inputValue, + }, + }); + }} + fullWidth + helperText={ + formik.touched.user_existing_employment ? formik.errors.user_existing_employment : null + } + onBlur={formik.handleBlur("user_existing_employment")} + /> + + + + + + + + + + + + + + + {t("RefahiLoanRequest.upload_operating_license_img")} + + + + + + + + {t("RefahiLoanRequest.upload_refresh_date_img")} + + + + + + + + { + formik.setFieldValue("facility_usage_history", event.target.checked); + }} + /> + } + label={`${t("LoanRequest.history_facilities")}`} + /> + + + + + { + formik.setFieldValue("checkedBox", event.target.checked); + }} + onBlur={formik.handleBlur("checkedBox")} + /> + } + label={`${t("LoanRequest.checkbox")}`} + /> + + {formik.touched.checkedBox && formik.errors.checkedBox ? formik.errors.checkedBox : null} + + + + + + + + + ); +}; +export default RestoreRequestDetail; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreToggleRealLegal.jsx b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreToggleRealLegal.jsx new file mode 100644 index 0000000..3bc1dbe --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/RestoreToggleRealLegal.jsx @@ -0,0 +1,54 @@ +import { useState } from "react"; +import { Stack, ToggleButton, ToggleButtonGroup } from "@mui/material"; +import RestoreRealPersonalInfo from "./RestoreRealPersonalInfo"; +import RestoreLegalPersonalInfo from "./RestoreLegalPersonalInfo"; +import { useTranslations } from "next-intl"; + +const RestoreToggleRealLegal = ({ + state, + handleNext, + dispatch, + isLoadingProvinceList, + errorProvinceList, + provinceList, +}) => { + const t = useTranslations(); + return ( + <> + + { + if (value === null) return; + dispatch({ type: "SET_PERSON_TYPE", person_type: value }); + }} + > + {t("LoanRequest.real_person")} + {t("LoanRequest.legal_person")} + + + {state.person_type === "real" ? ( + + ) : ( + + )} + + ); +}; +export default RestoreToggleRealLegal; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/index.jsx b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/index.jsx new file mode 100644 index 0000000..abb95c8 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/RestoreForm/index.jsx @@ -0,0 +1,122 @@ +import { useReducer, useState } from "react"; +import { useTranslations } from "next-intl"; +import * as React from "react"; +import { Stack, Step, StepLabel, Stepper } from "@mui/material"; +import RestoreProjectInfo from "./RestoreProjectInfo"; +import RestoreRequestDetail from "./RestoreRequestDetail"; +import RestoreToggleRealLegal from "./RestoreToggleRealLegal"; +import useLimitedProvince from "@/lib/app/hooks/useLimitedProvince"; + +const _data = { + person_type: "real", + telephone_number: "", + activity_type_id: "", + refahi_type: 2, + requested_facility_amount: "", + person_share: "", + user_existing_employment: "", + user_committed_employment: "", + father_name: "", + gender: "", + welfare_complex_degree: "", + first_name: "", + last_name: "", + city_id: "", + project_city_id: "", + province_id: "", + project_province_id: "", + education_id: "", + occupation_id: "", + national_id: "", + national_serial_number: "", + national_card_tracking_code: "", + national_serial_number_or_tracking_code: "national_serial_number", + postal_code: "", + address: "", + birthday: "", + investment_amount: "", + exploitation_date: "", + exploitation_license_renewal_date: "", + project_axis: "", + project_kilometer_marker: "", + project_direction: "", + project_address: "", + exploitation_license_image: null, + exploitation_license_renewal_image: null, + checkedBox: false, + facility_usage_history: false, + company_register_date: "", + shenase_meli: "", + register_number: "", + company_name: "", +}; + +const reducer = (state, action) => { + switch (action.type) { + case "SET_PERSONAL_INFO": + return { ...state, ...action.personalInfo }; + case "SET_PROJECT_INFO": + return { ...state, ...action.projectInfo }; + case "SET_REQUEST_INFO": + return { ...state, ...action.requestInfo }; + case "SET_PERSON_TYPE": + return { ...state, person_type: action.person_type }; + default: + return state; + } +}; + +const RestoreForm = ({ setFinishRefahiLoanRequest }) => { + const t = useTranslations(); + const [activeStep, setActiveStep] = useState(0); + const { provinceList, isLoadingProvinceList, errorProvinceList } = useLimitedProvince(); + const [state, dispatch] = useReducer(reducer, _data); + const steps = [ + t("RefahiLoanRequest.step_personal_info"), + t("RefahiLoanRequest.step_project_info"), + t("RefahiLoanRequest.step_contact_info"), + ]; + const handleNext = () => setActiveStep((prev) => prev + 1); + const handleBack = () => setActiveStep((prev) => prev - 1); + return ( + + + {steps.map((label, index) => ( + + {label} + + ))} + + {activeStep === 0 && ( + + )} + {activeStep === 1 && ( + + )} + {activeStep === 2 && ( + + )} + + ); +}; +export default RestoreForm; diff --git a/src/components/dashboard/refahi/add-request-loan/index.jsx b/src/components/dashboard/refahi/add-request-loan/index.jsx new file mode 100644 index 0000000..00a7d6d --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/index.jsx @@ -0,0 +1,46 @@ +import { Button, Stack, Typography } from "@mui/material"; +import { useTranslations } from "next-intl"; +import { CenterLayout } from "@witel/webapp-builder"; +import { useState } from "react"; +import DoneIcon from "@mui/icons-material/Done"; +import { NextLinkComposed } from "@witel/webapp-builder/dist/utils/linkRouting"; +import SvgDone from "@/core/components/svgs/SvgDone"; +import CheckRules from "./forms/CheckRules"; +import RefahiLoanType from "./RefahiLoanType"; +import RestoreForm from "./forms/RestoreForm"; +import BuildForm from "./forms/BuildForm"; + +const AddRequestLoan = () => { + const t = useTranslations(); + const [finishRefahiLoanRequest, setFinishRefahiLoanRequest] = useState(false); + const [rulesChecked, setRulesChecked] = useState(false); + const [refahiLoanType, setRefahiLoanType] = useState(null); + + return ( + <> + {finishRefahiLoanRequest ? ( + + + + + {t("LoanRequest.finish_loan_request")} + + + + + + ) : !rulesChecked ? ( + + ) : refahiLoanType === null ? ( + + ) : refahiLoanType === 0 ? ( + + ) : ( + + )} + + ); +}; +export default AddRequestLoan; diff --git a/src/core/components/EditedDatePicker.jsx b/src/core/components/EditedDatePicker.jsx new file mode 100644 index 0000000..0765edb --- /dev/null +++ b/src/core/components/EditedDatePicker.jsx @@ -0,0 +1,138 @@ +import { FormControl, FormHelperText } from "@mui/material"; +import Button from "@mui/material/Button"; +import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { faIR } from "@mui/x-date-pickers/locales"; +import moment from "jalali-moment"; +import { useState, useMemo } from "react"; + +function DynamicButtonField(props) { + const { + label, + id, + disabled, + InputProps: { ref } = {}, + inputProps: { "aria-label": ariaLabel } = {}, + error, + selectedDate, + buttonLabel, + onClick, + } = props; + + return ( + + ); +} + +function DynamicDatePicker({ + formik, + fieldName, + label, + disabled, + minDate, + maxDate, + errorText, + helperText, + buttonLabel, + onChange, +}) { + const [open, setOpen] = useState(false); + + const computedMinMaxDates = useMemo(() => { + const today = moment(); + const min = minDate ? moment(minDate, "jYYYY-jMM-jDD").toDate() : null; + const max = maxDate ? moment(maxDate, "jYYYY-jMM-jDD").toDate() : null; + return { min, max }; + }, [minDate, maxDate]); + + const selectedDate = useMemo(() => { + if (formik.values[fieldName]) { + return moment(formik.values[fieldName]).locale("fa").format("YYYY/MM/DD"); + } + return null; + }, [formik.values, fieldName]); + + return ( + setOpen((prev) => !prev), + }, + }} + label={label} + disabled={disabled} + disableFuture + open={open} + minDate={computedMinMaxDates.min} + maxDate={computedMinMaxDates.max} + value={formik.values[fieldName] ? formik.values[fieldName].toDate() : null} + onChange={(newValue) => { + const formattedValue = moment(newValue); + formik.setFieldValue(fieldName, formattedValue); + onChange?.(formattedValue); + }} + onClose={() => setOpen(false)} + onOpen={() => setOpen(true)} + /> + ); +} + +export default function PickerWithDynamicField({ + formik, + fieldName, + label, + disabled = false, + minDate, + maxDate, + buttonLabel, + errorText, + helperText, +}) { + return ( + + + { + formik.setFieldValue(fieldName, moment(newValue)); + }} + formik={formik} + fieldName={fieldName} + label={label} + disabled={disabled} + minDate={minDate} + maxDate={maxDate} + buttonLabel={buttonLabel} + errorText={errorText} + helperText={helperText} + /> + + + {formik.touched[fieldName] && formik.errors[fieldName]} + + + ); +} diff --git a/src/core/components/LegalPersonDatePicker.jsx b/src/core/components/LegalPersonDatePicker.jsx index 7e6381e..d23f88f 100644 --- a/src/core/components/LegalPersonDatePicker.jsx +++ b/src/core/components/LegalPersonDatePicker.jsx @@ -24,7 +24,8 @@ function ButtonField(props) { sx={{ width: "100%", padding: 0.8 }} variant="outlined" color={ - props.slotProps.formik.touched.company_date && Boolean(props.slotProps.formik.errors.company_date) + props.slotProps.formik.touched.company_register_date && + Boolean(props.slotProps.formik.errors.company_register_date) ? "error" : "primary" } @@ -50,7 +51,7 @@ function ButtonDatePicker(props) { formik: props.formik, field: { setOpen }, textField: { - helperText: props.formik.errors.company_date ? `${t("company_date")}` : null, + helperText: props.formik.errors.company_register_date ? `${t("company_date")}` : null, }, }} {...props} @@ -74,18 +75,24 @@ const LegalPersonDatePicker = ({ formik, disabled }) => { > { - formik.setFieldValue("company_date", moment(newValue)); + formik.setFieldValue("company_register_date", moment(newValue)); }} /> - {formik.touched.company_date && formik.errors.company_date} + + {formik.touched.company_register_date && formik.errors.company_register_date} + ); }; diff --git a/src/core/components/UploadSystem.jsx b/src/core/components/UploadSystem.jsx index 28770a1..071f1d7 100644 --- a/src/core/components/UploadSystem.jsx +++ b/src/core/components/UploadSystem.jsx @@ -1,156 +1,95 @@ -import { Box, Button, FormHelperText, TextField, Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; -import Image from "next/image"; +import { Box, Button, Paper, Typography } from "@mui/material"; +import AddIcon from "@mui/icons-material/Add"; import DeleteForeverIcon from "@mui/icons-material/DeleteForever"; -import { useRef, useState } from "react"; +import { useRef } from "react"; -const UploadSystem = ({ - fieldName, - default_image, - helperText, - error, - setFieldValue, - imageAlt, - label, - enableDelete, -}) => { - const t = useTranslations(); +const UploadSystem = ({ selectedImage, handleUploadChange, imageSize, fileType, showAddIcon }) => { const fileInputRef = useRef(null); - const [selectedImage, setSelectedImage] = useState(default_image || "/images/upload-image.svg"); - const [fileType, setFileType] = useState(null); - const [fileName, setFileName] = useState(""); - - // upload files - const handleUploadChange = (event) => { - const uploadedFile = event.target?.files?.[0]; - if (uploadedFile) { - setSelectedImage(URL.createObjectURL(uploadedFile)); - setFileType(uploadedFile.type); - setFileName(uploadedFile.name); - setFieldValue(fieldName, uploadedFile); - } - }; - // end upload files - - const uploadBoxStyle = error - ? { - cursor: "pointer", - objectFit: "contain", - border: "1px dashed #d32f2f", - borderRadius: "5px", - padding: "5px", - } - : { - cursor: "pointer", - objectFit: "contain", - border: "1px dashed #e1e1e1", - borderRadius: "5px", - padding: "5px", - }; const handleClick = () => { fileInputRef.current.click(); }; - const handleDeleteImage = () => { - setselectedImage("/images/upload-image.svg"); - setFieldValue(fieldname, null); - }; return ( - - - {label} - - - {selectedImage === "/images/upload-image.svg" || selectedImage === default_image ? ( - {imageAlt} - ) : fileType && fileType.startsWith("image/") ? ( - {imageAlt} - ) : ( + + {showAddIcon ? ( + - {fileName} + فرمت قابل قبول : png, jpg +
+ حداکثر 2Mb
+ ) : ( + <> + {fileType && fileType.startsWith("image/") && ( + + + + )} + )} - - handleUploadChange(e)} - inputRef={fileInputRef} + onChange={handleUploadChange} + ref={fileInputRef} /> - {enableDelete ? ( - - ) : ( - "" - )} - {helperText}
); }; - export default UploadSystem; diff --git a/src/core/components/notifications/UploadFileNotification.jsx b/src/core/components/notifications/UploadFileNotification.jsx new file mode 100644 index 0000000..cd23ab2 --- /dev/null +++ b/src/core/components/notifications/UploadFileNotification.jsx @@ -0,0 +1,40 @@ +import DangerousIcon from "@mui/icons-material/Dangerous"; +import { Box, Typography } from "@mui/material"; +import { toast } from "react-toastify"; + +const UploadFileNotification = (t) => { + toast( + ({ closeToast }) => ( + <> + + + + + + {t("UploadSystem.uploadfile_error")} + + + + + + ), + { + containerId: "validation", + toastId: "upload", + autoClose: 3000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); +}; + +export default UploadFileNotification; diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index cedf028..d78e4fb 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -27,3 +27,4 @@ export const UPDATE_LOAN = BASE_URL + "/navgan/loan/update/"; export const GET_PROJECT_TITLE = BASE_URL + "/navgan_plans"; export const GET_ACTIVITY_LIST = BASE_URL + "/activity_types"; export const GET_PRIORITY_LIST = BASE_URL + "/activity_priorities"; +export const SEND_LOAN_REQUEST_REFAHI = BASE_URL + "/refahi/loan/store"; diff --git a/src/core/data/sidebarMenu.js b/src/core/data/sidebarMenu.js index d8ce00d..54c4dca 100644 --- a/src/core/data/sidebarMenu.js +++ b/src/core/data/sidebarMenu.js @@ -1,6 +1,7 @@ import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard"; import BookmarkAddedIcon from "@mui/icons-material/BookmarkAdded"; -import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; +import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism"; +import DirectionsCarIcon from "@mui/icons-material/DirectionsCar"; const sidebarMenu = [ [ @@ -14,19 +15,30 @@ const sidebarMenu = [ permission: "all", }, { - key: "sidebar.add-request-loan", - name: "sidebar.add-request-loan", + key: "sidebar.add-request-navgan-loan", + name: "sidebar.add-request-navgan-loan", + secondary: "secondary.navgan", type: "page", route: "/dashboard/navgan/add-request-loan", - icon: , + icon: , selected: false, permission: "can_request_navgan_loan", }, + { + key: "sidebar.add-request-refahi-loan", + name: "sidebar.add-request-refahi-loan", + secondary: "secondary.refahi", + type: "page", + route: "/dashboard/refahi/add-request-loan", + icon: , + selected: false, + permission: "can_request_refahi_loan", + }, { key: "sidebar.followUp-loan", name: "sidebar.followUp-loan", type: "page", - route: "/dashboard/navgan/followUp-loan", + route: "/dashboard/followUp-loan", icon: , selected: false, permission: "all", diff --git a/src/lib/app/hooks/useLimitedProvince.jsx b/src/lib/app/hooks/useLimitedProvince.jsx index b1992bc..be6b9b1 100644 --- a/src/lib/app/hooks/useLimitedProvince.jsx +++ b/src/lib/app/hooks/useLimitedProvince.jsx @@ -3,7 +3,7 @@ import { useRequest } from "@witel/webapp-builder"; import { useEffect, useState } from "react"; const useLimitedProvince = () => { - const [isLoadingProvinceList, setIsLoadingProvinceList] = useState(false); + const [isLoadingProvinceList, setIsLoadingProvinceList] = useState(true); const [errorProvinceList, setErrorProvinceList] = useState(false); const [provinceList, setProvinceList] = useState([]); const requestServer = useRequest({ auth: true, notification: false }); diff --git a/src/middlewares/RegisterDeadline.jsx b/src/middlewares/RegisterDeadline.jsx index c165913..1abccbb 100644 --- a/src/middlewares/RegisterDeadline.jsx +++ b/src/middlewares/RegisterDeadline.jsx @@ -1,18 +1,23 @@ -import { CenterLayout, FullPageLayout, useConfig } from "@witel/webapp-builder"; +import { CenterLayout, FullPageLayout } from "@witel/webapp-builder"; import moment from "jalali-moment"; import SvgMaintenance from "@/core/components/svgs/SvgMaintenance"; import { Typography } from "@mui/material"; import { useTranslations } from "next-intl"; -const RegisterDeadlineMiddleware = ({ children, serverToday }) => { - const { config } = useConfig(); +const RegisterDeadlineMiddleware = ({ + children, + serverToday, + registration_start_date, + registration_end_date, + registration_status, +}) => { const t = useTranslations(); - const fromDate = moment(config.navgan_registration_start_date, "YYYY/MM/DD HH:mm:ss"); - const toDate = moment(config.navgan_registration_end_date, "YYYY/MM/DD HH:mm:ss"); + const fromDate = moment(registration_start_date, "YYYY/MM/DD HH:mm:ss"); + const toDate = moment(registration_end_date, "YYYY/MM/DD HH:mm:ss"); const today = moment(serverToday); - if (config.navgan_registration_status) { + if (registration_status) { if (today.isBetween(fromDate, toDate, null, "[]")) { return children; } else if (today.isAfter(toDate, null)) { diff --git a/src/pages/dashboard/navgan/followUp-loan/index.jsx b/src/pages/dashboard/followUp-loan/index.jsx similarity index 73% rename from src/pages/dashboard/navgan/followUp-loan/index.jsx rename to src/pages/dashboard/followUp-loan/index.jsx index f4c8d73..e8d9112 100644 --- a/src/pages/dashboard/navgan/followUp-loan/index.jsx +++ b/src/pages/dashboard/followUp-loan/index.jsx @@ -1,4 +1,4 @@ -import LoanFollowUpComponent from "@/components/dashboard/navgan/followUp-loan"; +import LoanFollowUpComponent from "src/components/dashboard/followUp-loan"; import { globalServerProps } from "@/core/utils/globalServerProps"; export default function FollowUpLoan() { @@ -9,7 +9,7 @@ export async function getServerSideProps({ req, locale }) { return { props: { ...(await globalServerProps({ req, locale })), - title: "LoanRequest.loan_request_page", + title: "LoanFollowUp.loan_follow_up_page", layout: { name: "DashboardLayout" }, }, }; diff --git a/src/pages/dashboard/navgan/add-request-loan/index.jsx b/src/pages/dashboard/navgan/add-request-loan/index.jsx index 16dfaf2..f25d1bc 100644 --- a/src/pages/dashboard/navgan/add-request-loan/index.jsx +++ b/src/pages/dashboard/navgan/add-request-loan/index.jsx @@ -1,10 +1,17 @@ import LoanRequestComponent from "@/components/dashboard/navgan/add-request-loan"; import { globalServerProps } from "@/core/utils/globalServerProps"; import RegisterDeadlineMiddleware from "@/middlewares/RegisterDeadline"; +import { useConfig } from "@witel/webapp-builder"; export default function AddLoanRequest(props) { + const { config } = useConfig(); return ( - + ); diff --git a/src/pages/dashboard/refahi/add-request-loan/index.jsx b/src/pages/dashboard/refahi/add-request-loan/index.jsx new file mode 100644 index 0000000..8896b36 --- /dev/null +++ b/src/pages/dashboard/refahi/add-request-loan/index.jsx @@ -0,0 +1,28 @@ +import LoanRequestComponent from "@/components/dashboard/refahi/add-request-loan"; +import { globalServerProps } from "@/core/utils/globalServerProps"; +import RegisterDeadlineMiddleware from "@/middlewares/RegisterDeadline"; +import { useConfig } from "@witel/webapp-builder"; + +export default function AddLoanRequest(props) { + const { config } = useConfig(); + return ( + + + + ); +} + +export async function getServerSideProps({ req, locale }) { + return { + props: { + ...(await globalServerProps({ req, locale })), + title: "LoanRequest.loan_request_page", + layout: { name: "DashboardLayout", props: { permissions: ["can_request_refahi_loan"] } }, + }, + }; +}