diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 9a33968..228b3c2 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -126,39 +126,54 @@ "no_request_found": "درخواستی یافت نشد" }, "LoanRequest": { + "city_id": "شهر", "loan_request_page": "ثبت درخواست وام", "personal_info": "اطلاعات شخصی", + "national_code_number": "کد ملی می بایست شامل اعداد باشد", + "national_code_max": "کد ملی می بایست 10 رقم باشد", + "tel_number_max": "شماره ثابت می بایست 11 رقم باشد", + "national_code_positive": "کد ملی می بایست مثبت باشد", "uploading_documents": "اسناد", "error_message_name": "لطفا نام خود را وارد کنید!", - "error_message_phone_number": "لطفا شماره تلفن خود را وارد کنید!", + "error_message_tel_number": "لطفا شماره ثابت (با پیش شماره استان) خود را وارد کنید!", "error_message_vehicle_type": "لطفا نوع وسیله نقلیه خود را وارد کنید!", "error_message_plate_number": "لطفا شماره پلاک خود را وارد کنید!", - "error_message_navgan_id": "لطفا کد ناوگان خود را وارد کنید!", + "error_message_navgan_id": "لطفا کد هوشمند خود را وارد کنید!", "error_message_province_id": "لطفا استان خود را وارد کنید!", "error_message_national_id": "لطفا کد ملی خود را وارد کنید!", "error_message_shenasname_id": "لطفا شماره شناسنامه خود را وارد کنید!", "error_message_national_code": "لطفا کد ملی خود را وارد کنید!", - "text_field_phone_number": "شماره تلفن", - "text_field_enter_your_phone_number": "شماره تلفن خود را وارد کنید", + "text_field_tel_number": "شماره ثابت (با پیش شماره استان)", + "text_field_enter_your_tel_number": "شماره ثابت (با پیش شماره استان) خود را وارد کنید", "text_field_name": "نام", + "text_field_plate_part4": "بخش چهارم", + "text_field_plate_part3": "بخش سوم", + "text_field_plate_part2": "بخش دوم", + "text_field_plate_part1": "بخش اول", + "text_field_enter_your_plate_part1": "بخش اول پلاک را وارد کنید", + "text_field_enter_your_plate_part2": "بخش دوم پلاک را وارد کنید", + "text_field_enter_your_plate_part3": "بخش سوم پلاک را وارد کنید", + "text_field_enter_your_plate_part4": "بخش چهارم پلاک راوارد کنید", + "text_field_loading_cities_list": "درحال دریافت اطلاعات شهر ها...", "text_field_city_id": "شهر", "text_field_enter_your_name": "نام خود را وارد کنید", - "text_field_vehicle_type": "نام وسیله نقلیه", - "text_field_enter_your_vehicle_type": "نام وسیله نقلیه خود را وارد کنید", + "text_field_vehicle_type": "نوع وسیله نقلیه", + "text_field_enter_your_vehicle_type": "نوع وسیله نقلیه خود را وارد کنید", "text_field_province_id": "استان", - "text_field_loading_provinces_list": "درحال دریافت استان ها", + "text_field_loading_provinces_list": "درحال دریافت استان ها ...", "text_field_error_fetching_provinces": "خطا در دریافت استان ها", "text_field_enter_your_national_code": "کد ملی خود را وارد کنید", "text_field_enter_your_province_id": "استان خود را وارد کنید", "text_field_enter_your_city_id": "شهر خود را وارد کنید", - "text_field_navgan_id": "شماره ناوگان", - "text_field_enter_your_navgan_id": "شماره ناوگان خود را وارد کنید", + "text_field_navgan_id": "کد هوشمند ناوگان", + "text_field_enter_your_navgan_id": "کد هوشمند ناوگان خود را وارد کنید", "text_field_national_code": "کد ملی", "text_field_enter_your_national_id": "کد ملی خود را وارد کنید", "text_field_shenasname_id": "شماره شناسنامه", "text_field_enter_your_shenasname_id": "شماره شناسنامه خود را وارد کنید", "text_field_plate_number": "شماره پلاک", "text_field_enter_your_plate_number": "شماره پلاک خود را وارد کنید", + "text_field_error_fetching_cities": "شهر خود را وارد کنید!", "button_submit": "ثبت درخواست", "error_message_city_id": "لطفا شهر خود را وارد کنید!", "add_loan_request_permission": "اکنون امکان ثبت درخواست جدید برای شما مقدور نیست" diff --git a/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx b/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx index f5ab007..f5417f7 100644 --- a/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx +++ b/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx @@ -1,33 +1,24 @@ import SelectBox from "@/core/components/SelectBox"; -import {GET_PROVINCE_LIST, SEND_LOAN_REQUEST_NAVGAN,} from "@/core/data/apiRoutes"; +import {SEND_LOAN_REQUEST_NAVGAN} from "@/core/data/apiRoutes"; import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; -import {Box, Button, Grid, TextField} from "@mui/material"; -import axios from "axios"; +import {Box, Button, FormControl, Grid, Stack, TextField} from "@mui/material"; import {useFormik} from "formik"; import {useTranslations} from "next-intl"; -import {useEffect, useState} from "react"; import * as Yup from "yup"; import {useRequest, useUser} from "@witel/webapp-builder"; +import useProvince from "@/lib/app/hooks/useProvince"; +import useCities from "@/lib/app/hooks/useCities"; +import PlateNumber from "@/core/components/PlateNumber"; const AddFormComponent = () => { const t = useTranslations(); const {token} = useUser(); - const [provinceList, setProvinceList] = useState([]); const requestServer = useRequest() - useEffect(() => { - requestServer(GET_PROVINCE_LIST, "get", {auth : true, notification : false}).then(({data}) => { - const formattedData = data.map((province, index) => ({ - id: index, - name: province.name, - value: province.id, - })); - setProvinceList(formattedData); - }).catch(() => {}); - }, []); - + const{provinceList, isLoadingProvinceList, errorProvinceList} = useProvince() + const{cityTextField, cityList, setProvinceID}=useCities() const initialValues = { - phone_number: "", + tel_number: "", vehicle_type: "", plate_number: "", province_id: "", @@ -35,33 +26,68 @@ const AddFormComponent = () => { navgan_id: "", national_code: "", shenasname_id: "", - national_card_img: null, - shenasname_img: null, + postal_code: "", + navgan_type: "", + plate_part1 : "", + plate_part2 : "", + plate_part3 : "", + plate_part4 : "", }; const validationSchema = Yup.object().shape({ - phone_number: Yup.string().required( - t("LoanRequest.error_message_phone_number") - ), + tel_number: Yup.mixed() + .test("max", `${t("LoanRequest.tel_number_max")}`, (value) => value.toString().length === 11) + .required(t("LoanRequest.error_message_tel_number")), vehicle_type: Yup.string().required( t("LoanRequest.error_message_vehicle_type") ), - plate_number: Yup.string().required( - t("LoanRequest.error_message_plate_number") + navgan_type: Yup.string().required( + t("LoanRequest.error_message_navgan_type") ), - navgan_id: Yup.string().required(t("LoanRequest.error_message_navgan_id")), + postal_code : Yup.mixed() + .test("max", `${t("LoanRequest.postal_code_max")}`, (value) => value.toString().length === 10) + .required( + t("LoanRequest.error_message_postal_code") + ), + plate_part1: Yup.mixed() + .test("max", `${t("LoanRequest.plate_part1_max")}`, (value) => value.toString().length === 2) + .required( + t("LoanRequest.error_message_plate_part1") + ), + plate_part2: Yup.mixed() + .required( + t("LoanRequest.error_message_plate_part2") + ), + plate_part3: Yup.mixed() + .test("max", `${t("LoanRequest.plate_part3_max")}`, (value) => value.toString().length === 2) + .required( + t("LoanRequest.error_message_plate_part3") + ), + plate_part4: Yup.mixed() + .test("max", `${t("LoanRequest.plate_part3_max")}`, (value) => value.toString().length === 2) + .required( + t("LoanRequest.error_message_plate_part3") + ), + navgan_id: Yup.mixed().required(t("LoanRequest.error_message_navgan_id")), province_id: Yup.string().required(t("LoanRequest.error_message_province_id")), city_id: Yup.string().required(t("LoanRequest.error_message_city_id")), - national_code: Yup.string().required( - t("LoanRequest.error_message_national_code") - ), + national_code: 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")), shenasname_id: Yup.string().required( t("LoanRequest.error_message_shenasname_id") ), }); + + const handleSubmit = async (values, props) => { const formData = new FormData(); - formData.append("phone_number", values.phone_number); + formData.append("tel_number", values.tel_number); + formData.append("navgan_type", values.navgan_type); + formData.append("postal_code", values.postal_code); formData.append("vehicle_type", values.vehicle_type); formData.append("plate_number", values.plate_number); formData.append("province_id", values.province_id); @@ -69,10 +95,6 @@ const AddFormComponent = () => { formData.append("navgan_id", values.navgan_id); formData.append("national_code", values.national_code); formData.append("shenasname_id", values.shenasname_id); - if (values.shenasname_img != null) - formData.append("shenasname_image", values.shenasname_img); - if (values.national_card_img != null) - formData.append("national_card_image", values.national_card_img); requestServer(SEND_LOAN_REQUEST_NAVGAN, "post", {auth : true, notification : true}).then().catch(() => { props.setSubmitting(false) @@ -82,9 +104,7 @@ const AddFormComponent = () => { const formik = useFormik({ initialValues, validationSchema, onSubmit: handleSubmit }) - return ( - <> @@ -95,6 +115,8 @@ const AddFormComponent = () => { name="national_code" variant="outlined" size="small" + type={"number"} + onChange={formik.handleChange} label={t("LoanRequest.text_field_national_code")} placeholder={t( "LoanRequest.text_field_enter_your_national_code" @@ -109,96 +131,45 @@ const AddFormComponent = () => { > - - - - - - - - - - - - - - - - - - { helperText={formik.touched.navgan_id && formik.errors.navgan_id} /> + + + + + + + {formik.setFieldValue('navgan_type', event.target.value)}} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.navgan_type && Boolean(formik.errors.navgan_type)} + helperText={formik.touched.navgan_type && formik.errors.navgan_type} + onBlur={formik.handleBlur("navgan_type")} + /> + + + + + {formik.setFieldValue('province_id', event.target.value); setProvinceID(event.target.value) + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", "") + }} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.province_id && Boolean(formik.errors.province_id)} + helperText={formik.touched.province_id && formik.errors.province_id} + onBlur={formik.handleBlur("province_id")} + /> + + + formik.setFieldValue('city_id', event.target.value)} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.city_id && Boolean(formik.errors.city_id)} + helperText={formik.touched.city_id && formik.errors.city_id} + onBlur={formik.handleBlur("city_id")} + /> + + + { helperText={formik.touched.shenasname_id && formik.errors.shenasname_id} /> + + + + + + + + }, +] +const PlateNumber = ({formik}) => { + const t = useTranslations(); + return( + + + + + + + + + + formik.setFieldValue('plate_part2', event.target.value)} + setFieldTouched={formik.setFieldTouched} + error={formik.touched.plate_part2 && Boolean(formik.errors.plate_part2)} + helperText={formik.touched.plate_part2 && formik.errors.plate_part2} + onBlur={formik.handleBlur("plate_part2")} + /> + + + + + + + + ) +} +export default PlateNumber \ No newline at end of file diff --git a/src/core/components/SelectBox.jsx b/src/core/components/SelectBox.jsx index 5c81f5a..a1c35c7 100644 --- a/src/core/components/SelectBox.jsx +++ b/src/core/components/SelectBox.jsx @@ -1,46 +1,54 @@ import {FormControl, FormHelperText, InputLabel, MenuItem, Select,} from "@mui/material"; +import {useTranslations} from "next-intl"; function SelectBox({ select, - selectType, + name, selectors, label, - setFieldValue, - setFieldTouched, + handleChange, error, onBlur, + disabled, helperText, + isLoading, + errorEcured }) { + const t = useTranslations(); - const selectId = String(select); - const handleChange = (event) => { - setFieldValue(selectType, event.target.value); - }; return ( - {label} + {label} {helperText} diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index cd90a05..57bafba 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -14,5 +14,6 @@ export const SEND_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/store"; export const UPDATE_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/update/"; export const DETAILS_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/details/"; export const GET_PROVINCE_LIST = BASE_URL + "/provinces"; +export const GET_CITIES_LIST = BASE_URL + "/cities"; diff --git a/src/lib/app/hooks/useCities.jsx b/src/lib/app/hooks/useCities.jsx new file mode 100644 index 0000000..fba621b --- /dev/null +++ b/src/lib/app/hooks/useCities.jsx @@ -0,0 +1,33 @@ +import {useEffect, useState} from "react"; +import {useRequest} from "@witel/webapp-builder"; +import {useTranslations} from "next-intl"; +import {GET_CITIES_LIST} from "@/core/data/apiRoutes"; +const useCities = () => { + const t = useTranslations(); + const [provinceID, setProvinceID] = useState(null) + const [cityList, setCityList] = useState([]); + const [cityTextField, setCityTextField] = useState(t("LoanRequest.city_id")); + const requestServer = useRequest({auth: true, notification: false}) + + useEffect(()=>{ + if(provinceID === null) return + setCityTextField(t("LoanRequest.text_field_loading_cities_list")) + requestServer(`${GET_CITIES_LIST}?province_id=${provinceID}`, "get", {auth: true, notification: false}) + .then(({data}) => { + const result = data.data; + const formattedData = result.map((city, index) => ({ + id: index, + name: city.name, + value: city.id, + })); + setCityList(formattedData); + setCityTextField(t("LoanRequest.text_field_city_id")) + }).catch(() => { + setCityTextField(t("LoanRequest.text_field_error_fetching_cities")) + }); + },[provinceID]) + + + return{cityTextField, cityList, setProvinceID} +} +export default useCities \ No newline at end of file diff --git a/src/lib/app/hooks/useProvince.jsx b/src/lib/app/hooks/useProvince.jsx index d0fbda0..add55f3 100644 --- a/src/lib/app/hooks/useProvince.jsx +++ b/src/lib/app/hooks/useProvince.jsx @@ -1,28 +1,33 @@ import {GET_PROVINCE_LIST} from "@/core/data/apiRoutes"; -import useRequest from "@/lib/app/hooks/useRequest"; -import useSWR from "swr"; +import {useRequest} from "@witel/webapp-builder"; +import {useEffect, useState} from "react"; const useProvince = () => { + const [isLoadingProvinceList, setIsLoadingProvinceList] = useState(false) + const [errorProvinceList, setErrorProvinceList] = useState(false) + const [provinceList, setProvinceList] = useState([]) const requestServer = useRequest({auth: true, notification: false}) - //swr config - const fetcher = (...args) => { - return requestServer(args, 'get').then(({data}) => { - return data; + useEffect(()=> { + setIsLoadingProvinceList(true) + requestServer(GET_PROVINCE_LIST, 'get',{auth : true, notification : false}).then(({data}) => { + const formattedData = data.map((province, index) => ({ + id: index, + name: province.name, + value: province.id, + })); + setIsLoadingProvinceList(false) + setProvinceList(formattedData); }).catch(() => { + setIsLoadingProvinceList(false) + setErrorProvinceList(true) }) - }; - - const {data, isLoading} = useSWR(GET_PROVINCE_LIST, fetcher, { - revalidateIfStale: false, - revalidateOnFocus: false, - revalidateOnReconnect: false - }); + },[]) return { - provinceList: data, - isLoadingProvinceList: isLoading, - errorProvinceList: !data + provinceList, + isLoadingProvinceList, + errorProvinceList } };