diff --git a/public/images/upload-image.svg b/public/images/upload-image.svg
new file mode 100644
index 0000000..3bbca65
--- /dev/null
+++ b/public/images/upload-image.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json
index 67cc090..138c4b9 100644
--- a/public/locales/fa/app.json
+++ b/public/locales/fa/app.json
@@ -11,6 +11,7 @@
"pending": "درحال اجرا...",
"user_navy": "ناوگان",
"page_not_found": "صفحه مورد نظر یافت نشد",
+ "delete": "حذف",
"header": {
"open_profile": "پروفایل",
"edit_profile": "ویرایش پروفایل",
@@ -83,10 +84,8 @@
"error_message_required": "اجباری!",
"text_field_phone_number": "شماره تلفن",
"text_field_enter_your_phone_number": "شماره تلفن خود را وارد کنید",
- "text_field_first_name": "نام",
- "text_field_enter_your_first_name": "نام خود را وارد کنید",
- "text_field_last_name": "نام خانوادگی",
- "text_field_enter_your_last_name": "نام خانوادگی خود را وارد کنید",
+ "text_field_name": "نام",
+ "text_field_enter_your_name": "نام خود را وارد کنید",
"text_field_vehicle_type": "نام وسیله نقلیه",
"text_field_enter_your_vehicle_type": "نام وسیله نقلیه خود را وارد کنید",
"text_field_province": "استان",
@@ -95,8 +94,8 @@
"text_field_enter_your_navgan_id": "شماره ناوگان خود را وارد کنید",
"text_field_national_code": "کد ملی",
"text_field_enter_your_national_code": "کد ملی خود را وارد کنید",
- "text_field_birth_certificate_id": "شماره شناسنامه",
- "text_field_enter_your_birth_certificate_id": "شماره شناسنامه خود را وارد کنید",
+ "text_field_shenasname_id": "شماره شناسنامه",
+ "text_field_enter_your_shenasname_id": "شماره شناسنامه خود را وارد کنید",
"text_field_plate_number": "شماره پلاک",
"text_field_enter_your_plate_number": "شماره پلاک خود را وارد کنید",
"button_submit": "ثبت درخواست"
diff --git a/src/components/dashboard/loan-follow-up/index.jsx b/src/components/dashboard/loan-follow-up/index.jsx
index e05fa20..1b211af 100644
--- a/src/components/dashboard/loan-follow-up/index.jsx
+++ b/src/components/dashboard/loan-follow-up/index.jsx
@@ -1,11 +1,8 @@
-import CenterLayout from "@/layouts/CenterLayout";
import DashboardLayouts from "@/layouts/dashboardLayouts";
import useUser from "@/lib/app/hooks/useUser";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import {
- Avatar,
- Box,
- Card,
+ Avatar, Card,
CardActions,
CardContent,
CardHeader,
@@ -13,7 +10,7 @@ import {
Grid,
IconButton,
Stack,
- Typography,
+ Typography
} from "@mui/material";
import { styled } from "@mui/material/styles";
import { useTranslations } from "next-intl";
@@ -30,19 +27,42 @@ const ExpandMore = styled((props) => {
}),
}));
+const data = [
+ {
+ name: "جان دو",
+ date: "۱۳۹۹/۰۴/۲۵",
+ description:
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.",
+ },
+ {
+ name: "جین اسمیت",
+ date: "۱۳۹۹/۰۴/۲۶",
+ description: "نُلا ویته الیت لیبرو آ، آ فارِترا آوگوه.",
+ },
+ {
+ name: "مایک جانسون",
+ date: "۱۳۹۹/۰۴/۲۷",
+ description:
+ "دوئیس مولیس، است نُن کُمُدو لُکتوس، نیسی ارات پورتیتور لیگولا.",
+ },
+];
+
const DashboardLoanFollowUpComponent = () => {
const t = useTranslations();
const { token } = useUser();
- const [expanded, setExpanded] = useState(false);
+ const [expanded, setExpanded] = useState([]);
- const handleExpandClick = () => {
- setExpanded(!expanded);
+ const handleExpandClick = (index) => {
+ setExpanded((prevExpanded) => {
+ const newExpanded = [...prevExpanded];
+ newExpanded[index] = !newExpanded[index];
+ return newExpanded;
+ });
};
return (
-
{
container
columnSpacing={2}
rowSpacing={2}
- sx={{ alignItems: "center", justifyContent: "center" }}
+ sx={{ alignItems: "start", justifyContent: "center" }}
>
-
-
-
- }
- title="اسم اقاهه"
- subheader="تاریخ اگه خواستیم"
- />
-
-
- متن تست
-
-
-
-
-
-
-
-
+ {data.map((item, index) => (
+
+
+
+ }
+ title={item.name}
+ subheader={item.date}
+ />
- اطلاعات تکمیلی:
- پارت دوم متن تست
- پارت سه همون قبلی
- در ادامه باید بگم که...
- درپایان همینه که هست
+
+ متن تست
+
-
-
-
-
-
-
- }
- title="اسم اقاهه"
- subheader="تاریخ اگه خواستیم"
- />
-
-
- متن تست
-
-
-
-
-
-
-
-
-
- اطلاعات تکمیلی:
- پارت دوم متن تست
- پارت سه همون قبلی
- در ادامه باید بگم که...
- درپایان همینه که هست
-
-
-
-
-
-
-
- }
- title="اسم اقاهه"
- subheader="تاریخ اگه خواستیم"
- />
-
-
- متن تست
-
-
-
-
-
-
-
-
-
- اطلاعات تکمیلی:
- پارت دوم متن تست
- پارت سه همون قبلی
- در ادامه باید بگم که...
- درپایان همینه که هست
-
-
-
-
+
+ handleExpandClick(index)}
+ aria-expanded={expanded[index]}
+ aria-label="show more"
+ >
+
+
+
+
+
+ اطلاعات تکمیلی:
+ {item.description}
+
+
+
+
+ ))}
-
);
};
diff --git a/src/components/dashboard/loan-request/NavyForm.jsx b/src/components/dashboard/loan-request/NavyForm.jsx
index fc7ed83..7686862 100644
--- a/src/components/dashboard/loan-request/NavyForm.jsx
+++ b/src/components/dashboard/loan-request/NavyForm.jsx
@@ -1,4 +1,6 @@
+import Notifications from "@/core/components/notifications";
import StyledForm from "@/core/components/StyledForm";
+import useDirection from "@/lib/app/hooks/useDirection";
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
import { Box, Button, Stack, TextField } from "@mui/material";
import { Field, Formik } from "formik";
@@ -7,26 +9,45 @@ import Image from "next/image";
const NavyForm = () => {
const t = useTranslations();
+ const { directionApp } = useDirection();
const initialValues = {
- first_name: "",
- last_name: "",
+ name: "",
phone_number: "",
vehicle_type: "",
plate_number: "",
province: "",
navgan_id: "",
national_code: "",
- birth_certificate_id: "",
+ shenasname_id: "",
national_card_img: "",
- birth_certificate_img: "",
+ shenasname_img: "",
+ };
+
+ const handleSubmit = async (values, props) => {
+ Notifications(directionApp, t, undefined);
+ await axios
+ .post(SEND_LOAN_REQUEST_NAVGAN, {
+ name: values.name,
+ phone_number: values.phone_number,
+ vehicle_type: values.vehicle_type,
+ plate_number: values.plate_number,
+ province_id: values.province,
+ navgan_id: values.navgan_id,
+ national_code: values.national_code,
+ shenasname_id: values.shenasname_id,
+ })
+ .then(function (response) {
+ Notifications(directionApp, t, response);
+ })
+ .catch(function (error) {
+ Notifications(directionApp, t, error.response);
+ props.setSubmitting(false);
+ });
};
return (
-
+
{(props) => (
{
-
-
-
{
diff --git a/src/components/dashboard/loan-request/WelfareServicesForm.jsx b/src/components/dashboard/loan-request/WelfareServicesForm.jsx
index 0bca6ff..4ea21b6 100644
--- a/src/components/dashboard/loan-request/WelfareServicesForm.jsx
+++ b/src/components/dashboard/loan-request/WelfareServicesForm.jsx
@@ -1,31 +1,71 @@
+import Notifications from "@/core/components/notifications";
import StyledForm from "@/core/components/StyledForm";
+import UploadSystem from "@/core/components/UploadSystem";
+import { SEND_LOAN_REQUEST_WELFARE } from "@/core/data/apiRoutes";
+import useDirection from "@/lib/app/hooks/useDirection";
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
import { Box, Button, Stack, TextField } from "@mui/material";
+import axios from "axios";
import { Field, Formik } from "formik";
import { useTranslations } from "next-intl";
-import Image from "next/image";
+import { useState } from "react";
import * as Yup from "yup";
const WelfareServicesForm = () => {
const t = useTranslations();
+ const { directionApp } = useDirection();
+ // upload files
+ const [selectedImageShenasname, setSelectedImageShenasname] = useState(
+ "/images/upload-image.svg"
+ );
+ const [fileTypeShenasname, setFileTypeShenasname] = useState(null);
+ const [fileNameShenasname, setFileNameShenasname] = useState(null);
+ const [selectedImageNationalCard, setSelectedImageNationalCard] = useState(
+ "/images/upload-image.svg"
+ );
+ const [fileTypeNationalCard, setFileTypeNationalCard] = useState(null);
+ const [fileNameNationalCard, setFileNameNationalCard] = useState(null);
+
+ const handleUploadChangeShenasname = (event, setFieldValue) => {
+ const uploadedFile = event.target?.files?.[0];
+ const fileType = event.target.files[0].type;
+ const fileName = event.target.files[0].name;
+ if (uploadedFile) {
+ setSelectedImageShenasname(URL.createObjectURL(uploadedFile));
+ setFileTypeShenasname(fileType);
+ setFileNameShenasname(fileName);
+ setFieldValue("shenasname_img", uploadedFile);
+ }
+ };
+ const handleUploadChangeNationalCard = (event, setFieldValue) => {
+ const uploadedFile = event.target?.files?.[0];
+ const fileType = event.target.files[0].type;
+ const fileName = event.target.files[0].name;
+ if (uploadedFile) {
+ setSelectedImageNationalCard(URL.createObjectURL(uploadedFile));
+ setFileTypeNationalCard(fileType);
+ setFileNameNationalCard(fileName);
+ setFieldValue("national_card_img", uploadedFile);
+ }
+ };
+ // end upload files
+
+ // initial values, validation and request action of form
const initialValues = {
- first_name: "",
- last_name: "",
+ name: "",
phone_number: "",
vehicle_type: "",
plate_number: "",
province: "",
- navgan_id: "",
national_code: "",
- birth_certificate_id: "",
- national_card_img: "",
- birth_certificate_img: "",
+ shenasname_id: "",
+ national_card_img: null,
+ shenasname_img: null,
};
const validationSchema = Yup.object().shape({
- first_name: Yup.string().required(t("LoanRequest.error_message_required")),
- last_name: Yup.string().required(t("LoanRequest.error_message_required")),
+ name: Yup.string().required(t("LoanRequest.error_message_required")),
phone_number: Yup.string().required(
t("LoanRequest.error_message_required")
),
@@ -36,19 +76,45 @@ const WelfareServicesForm = () => {
t("LoanRequest.error_message_required")
),
province: Yup.string().required(t("LoanRequest.error_message_required")),
- navgan_id: Yup.string().required(t("LoanRequest.error_message_required")),
national_code: Yup.string().required(
t("LoanRequest.error_message_required")
),
- birth_certificate_id: Yup.string().required(
+ shenasname_id: Yup.string().required(
t("LoanRequest.error_message_required")
),
});
+ const handleSubmit = async (values, props) => {
+ Notifications(directionApp, t, undefined);
+ console.log(values.national_card_img);
+ console.log(values.shenasname_img);
+ await axios
+ .post(SEND_LOAN_REQUEST_WELFARE, {
+ name: values.name,
+ phone_number: values.phone_number,
+ vehicle_type: values.vehicle_type,
+ plate_number: values.plate_number,
+ province_id: values.province,
+ navgan_id: values.navgan_id,
+ national_code: values.national_code,
+ shenasname_id: values.shenasname_id,
+ national_card_image: values.national_card_img,
+ shenasname_image: values.shenasname_img,
+ })
+ .then(function (response) {
+ Notifications(directionApp, t, response);
+ })
+ .catch(function (error) {
+ Notifications(directionApp, t, error.response);
+ props.setSubmitting(false);
+ });
+ };
+ // end initial values, validation and request action of form
+
return (
{(props) => (
@@ -79,50 +145,15 @@ const WelfareServicesForm = () => {
-
-
-
{
width: "100%",
}}
>
-
-
-
{
@@ -365,24 +368,32 @@ const WelfareServicesForm = () => {
width: "100%",
}}
>
-
-
-
-
-
-
+
+ handleUploadChangeShenasname(e, props.setFieldValue)
+ }
+ setselectedImage={setSelectedImageShenasname}
+ setFieldValue={props.setFieldValue}
+ fieldname="shenasname_img"
+ fileType={fileTypeShenasname}
+ fileName={fileNameShenasname}
+ imageAlt={t("app_name")}
+ imageSize={[300 /*width*/, 150 /*height*/]}
+ />
+
+ handleUploadChangeNationalCard(e, props.setFieldValue)
+ }
+ setselectedImage={setSelectedImageNationalCard}
+ setFieldValue={props.setFieldValue}
+ fieldname="national_card_img"
+ fileType={fileTypeNationalCard}
+ fileName={fileNameNationalCard}
+ imageAlt={t("app_name")}
+ imageSize={[300 /*width*/, 150 /*height*/]}
+ />
{
flexDirection: { xs: "column", sm: "row" },
alignItems: "center",
mx: "auto",
+ my: 2,
width: { xs: "100%", sm: "30%", md: "25%" },
}}
>
diff --git a/src/components/first/index.jsx b/src/components/first/index.jsx
index 897f7cd..edd3a8a 100644
--- a/src/components/first/index.jsx
+++ b/src/components/first/index.jsx
@@ -19,6 +19,7 @@ const FirstComponent = () => {
alt={t("app_name")}
width={300}
height={200}
+ priority
/>
{t("app_name")}
diff --git a/src/components/register-navy/SendToken.jsx b/src/components/register-navy/SendToken.jsx
index fcba709..62bbb86 100644
--- a/src/components/register-navy/SendToken.jsx
+++ b/src/components/register-navy/SendToken.jsx
@@ -76,6 +76,7 @@ const SendToken = ({ PhoneNumber, nationalId, navganId, typeId }) => {
fill
src="/images/register.svg"
alt={t("app_name")}
+ priority
/>
diff --git a/src/components/register-navy/SendUserData.jsx b/src/components/register-navy/SendUserData.jsx
index bb13517..1433266 100644
--- a/src/components/register-navy/SendUserData.jsx
+++ b/src/components/register-navy/SendUserData.jsx
@@ -4,6 +4,7 @@ import StyledForm from "@/core/components/StyledForm";
import { REGISTER_SEND_OTP_TOKEN } from "@/core/data/apiRoutes";
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
+import useDirection from "@/lib/app/hooks/useDirection";
import FingerprintIcon from "@mui/icons-material/Fingerprint";
import {
Box,
@@ -90,6 +91,7 @@ const SendUserData = ({
fill
src="/images/register.svg"
alt={t("app_name")}
+ priority
/>
diff --git a/src/components/register-welfare-services/SendUserData.jsx b/src/components/register-welfare-services/SendUserData.jsx
index c74a1f4..07fb6e0 100644
--- a/src/components/register-welfare-services/SendUserData.jsx
+++ b/src/components/register-welfare-services/SendUserData.jsx
@@ -88,6 +88,7 @@ const SendUserData = ({
fill
src="/images/register.svg"
alt={t("app_name")}
+ priority
/>
diff --git a/src/components/register-welfare-services/sendToken.jsx b/src/components/register-welfare-services/sendToken.jsx
index 7634f93..5d5af44 100644
--- a/src/components/register-welfare-services/sendToken.jsx
+++ b/src/components/register-welfare-services/sendToken.jsx
@@ -76,6 +76,7 @@ const SendToken = ({ PhoneNumber, nationalId, typeId }) => {
fill
src="/images/register.svg"
alt={t("app_name")}
+ priority
/>
diff --git a/src/core/components/Messages.jsx b/src/core/components/Messages.jsx
index db6a980..2bd45c8 100644
--- a/src/core/components/Messages.jsx
+++ b/src/core/components/Messages.jsx
@@ -11,6 +11,7 @@ const Message = ({ text, actions }) => {
alt="loading loan facilities"
width={100}
height={100}
+ priority
/>
{text}
{actions}
diff --git a/src/core/components/UploadSystem.jsx b/src/core/components/UploadSystem.jsx
new file mode 100644
index 0000000..b60552a
--- /dev/null
+++ b/src/core/components/UploadSystem.jsx
@@ -0,0 +1,163 @@
+import { Box, Button, TextField, Typography } from "@mui/material";
+import { useTranslations } from "next-intl";
+import Image from "next/image";
+import DeleteForeverIcon from "@mui/icons-material/DeleteForever";
+import { useRef } from "react";
+
+const UploadSystem = ({
+ selectedImage,
+ setselectedImage,
+ handleUploadChange,
+ fieldname,
+ setFieldValue,
+ imageAlt,
+ imageSize,
+ fileType,
+ fileName,
+}) => {
+ const t = useTranslations();
+ const fileInputRef = useRef(null);
+
+ const handleClick = () => {
+ fileInputRef.current.click();
+ };
+ const handleDeleteImage = () => {
+ setselectedImage("/images/upload-image.svg");
+ setFieldValue(fieldname, null);
+ };
+
+ const isDocumentFormat = (fileType) => {
+ const documentFormats = [
+ "application/pdf",
+ "application/msword",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.ms-excel",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ ];
+ return documentFormats.includes(fileType);
+ };
+
+ return (
+
+ {selectedImage === "/images/upload-image.svg" ? (
+
+ ) : fileType && fileType.startsWith("image/") ? (
+
+ ) : (
+ fileType &&
+ isDocumentFormat(fileType) && (
+
+
+ {fileName}
+
+
+ )
+ )}
+
+
+ }
+ variant="contained"
+ onClick={handleDeleteImage}
+ >
+ {t("delete")}
+
+
+ );
+};
+
+export default UploadSystem;
+
+
+
+//////****** usage document ******/////////
+// 1.) use component inside your page
+// 2.) list of props that you need to send is down below
+// 2.1) selectedImage // this value come from useState that you need to write on your own component
+// 2.2) handleUploadChange // use on your own component (explain below more) you should set it to {(e) =>handleUploadChange[your special name]](e, props.setFieldValue)}
+// 2.3) setFieldValue // for setting value of file to null when user click on Delete button. you should set it to {props.setFieldValue}
+// 2.4) fieldname name that file field has on your formik initialValues.
+// 2.5) fileType // type of your file shows its document image etc...
+// 2.6) imageAlt // alt of your image.
+// 2.7) imageSize // this is size of your image box and value type is like that imageSize={ [width , height] }.
+// 2.9) setselectedImage // for making box empty when user click on delete button (explain below more)
+
+// const [selectedImage[your special name]], setSelectedImage[your special name]] = useState(
+// "/images/upload-image.svg" // default image
+// );
+// const [fileType[your special name], setFileType[your special name]] = useState(null);
+// const [fileName[your special name], setFileName[your special name]] = useState(null);
+
+
+// const handleUploadChange[your special name]] = (event, setFieldValue) => {
+// const uploadedFile = event.target?.files?.[0];
+// const fileType = event.target.files[0].type;
+// const fileName = event.target.files[0].name;
+// if (uploadedFile) { // just check file is uploaded or not
+// setSelectedImage[your special name]](URL.createObjectURL(uploadedFile)); // set image value
+// setFileType[your special name]](fileType); // set fileType
+// setFileName[your special name]](fileName); // set fileName
+// setFieldValue("[your special name]]_img", uploadedFile); set field value for sending data (this automaticaly append value in initial state)
+// }
+// };
+//////****** end usage document ******/////////
diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js
index b4a2241..ebbd73c 100644
--- a/src/core/data/apiRoutes.js
+++ b/src/core/data/apiRoutes.js
@@ -5,5 +5,7 @@ export const LOGIN = BASE_URL + "/login";
export const REGISTER_SEND_OTP_TOKEN = BASE_URL + "/register/send_otp";
export const REGISTER = BASE_URL + "/register";
export const USER_INFO = BASE_URL + "/profile/info";
+export const SEND_LOAN_REQUEST_NAVGAN = BASE_URL + "/navgan/store_loan";
+export const SEND_LOAN_REQUEST_WELFARE = BASE_URL + "/navgan/store_loan";