diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 0fb31db..af44e73 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -14,7 +14,7 @@ "between": "میان", "header": { "open_profile": "پروفایل", - "edit_profile": "ویرایش پروفایل", + "edit_profile": " پروفایل", "change_password": "تغییر رمز عبور", "logout": "خروج" }, @@ -57,6 +57,7 @@ "Dashboard": { "dashboard_page": "داشبورد", "passenger_boss_page": "رئیس مسافر", + "transportation_assistance": "معاونت حمل و نقل", "change_password": "تغییر رمز عبور", "province_manager_page": "مدیر کل استانی", "passenger_office_page": "اداره مسافر", @@ -82,7 +83,7 @@ }, "UpdateProfile": { "error_invalid_email": "ایمیل نامعتبر است", - "typography_edit_profile": "ویرایش پروفایل", + "typography_edit_profile": "پروفایل", "text_field_email": "ایمیل", "text_field_enter_your_password": "رمز عبور خود را وارد کنید", "text_field_username": "نام کاربری", @@ -159,9 +160,9 @@ }, "ConfirmDialog": { "confirm": "تایید", - "context": "آیا از تایید این آیتم اطمینان دارید", - "button-confirm": "تایید", + "context": "آیا از تایید این آیتم اطمینان دارید؟", "button-cancel": "بستن", + "button-confirm": "تایید", "amount_error": "وارد کردن مقدار پیشنهادی الزامیست", "description_error": "وارد کردن توضیحات الزامی است!", "description": "توضیحات", @@ -172,10 +173,15 @@ }, "RejectDialog": { "reject": "عدم تایید", - "context": "آیا از عدم تایید این آیتم اطمینان دارید", - "button-reject": "عدم تایید", + "context": "آیا از عدم تایید این آیتم اطمینان دارید؟", "button-cancel": "بستن", + "button-reject": "عدم تایید", "description": "توضیحات", "description_error": "وارد کردن توضیحات الزامی است!" + }, + "UploadSystem": { + "upload_file": "آپلود فایل", + "delete": "پاک کردن", + "uploadfile_error": "حجم فایل بیشتر از 2 مگابایت می باشد" } } diff --git a/src/components/dashboard/loan-follow-up/index.jsx b/src/components/dashboard/loan-follow-up/index.jsx deleted file mode 100644 index e69147e..0000000 --- a/src/components/dashboard/loan-follow-up/index.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import CenterLayout from "@/layouts/CenterLayout"; -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import useUser from "@/lib/app/hooks/useUser"; -import { useTranslations } from "next-intl"; -import React from "react"; - -const DashboardLoanFollowUpComponent = () => { - const t = useTranslations(); - const { token } = useUser(); - return ( - - -

چه کشکی چه پشمی

-
-
- ); -}; - -export default DashboardLoanFollowUpComponent; diff --git a/src/components/dashboard/loan-request/index.jsx b/src/components/dashboard/loan-request/index.jsx deleted file mode 100644 index b13cf78..0000000 --- a/src/components/dashboard/loan-request/index.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import CenterLayout from "@/layouts/CenterLayout"; -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import useUser from "@/lib/app/hooks/useUser"; -import { useTranslations } from "next-intl"; -import React from "react"; - -const DashboardLoanRequestComponent = () => { - const t = useTranslations(); - const { token } = useUser(); - return ( - - -

نکنه وامم میخوای؟؟؟

-
-
- ); -}; - -export default DashboardLoanRequestComponent; diff --git a/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx b/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx index 55ae682..6166ff4 100644 --- a/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx +++ b/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx @@ -12,11 +12,19 @@ import { useTranslations } from "next-intl"; import { useState } from "react"; import { useFormik } from "formik"; import * as Yup from "yup"; +import UploadSystem from "@/core/components/UploadSystem"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import useDirection from "@/lib/app/hooks/useDirection"; const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { const t = useTranslations(); + const { directionApp } = useDirection(); const [proposedAmount, setProposedAmount] = useState(""); const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); //formik const validationSchema = Yup.object().shape({ @@ -47,8 +55,25 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { formik.handleChange(event); }; + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("confirm_img", uploadedFile); + setShowAddIcon(false); + } + }; return ( - + {t("ConfirmDialog.confirm")} {t("ConfirmDialog.context")} @@ -86,14 +111,27 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { sx={{ mt: 1 }} fullWidth /> + - + ); diff --git a/src/components/dashboard/machinary-office/Form/RejectForm.jsx b/src/components/dashboard/machinary-office/Form/RejectForm.jsx index 723f9a6..70c606c 100644 --- a/src/components/dashboard/machinary-office/Form/RejectForm.jsx +++ b/src/components/dashboard/machinary-office/Form/RejectForm.jsx @@ -12,10 +12,18 @@ import { useTranslations } from "next-intl"; import { useFormik } from "formik"; import * as Yup from "yup"; import { useState } from "react"; +import UploadSystem from "@/core/components/UploadSystem"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import useDirection from "@/lib/app/hooks/useDirection"; const RejectForm = ({ open, handleClose, rowId, rejectData }) => { const t = useTranslations(); + const { directionApp } = useDirection(); const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const validationSchema = Yup.object().shape({ description: Yup.string().required(t("RejectDialog.description_error")), @@ -39,8 +47,26 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { formik.handleChange(event); }; + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("reject_img", uploadedFile); + setShowAddIcon(false); + } + }; + return ( - + {t("RejectDialog.reject")} {t("RejectDialog.context")} @@ -60,14 +86,27 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { variant="outlined" sx={{ mt: 1 }} /> + - + ); diff --git a/src/components/dashboard/machinary-office/TableRowActions.jsx b/src/components/dashboard/machinary-office/TableRowActions.jsx index e9e815e..c7ee618 100644 --- a/src/components/dashboard/machinary-office/TableRowActions.jsx +++ b/src/components/dashboard/machinary-office/TableRowActions.jsx @@ -1,12 +1,14 @@ import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; import ThumbDownIcon from "@mui/icons-material/ThumbDown"; -import { Box, IconButton } from "@mui/material"; +import { Box, IconButton, Tooltip } from "@mui/material"; import { useContext } from "react"; import { DataTableContext } from "@/lib/app/contexts/DataTableContext"; import ConfirmForm from "./Form/ConfirmForm"; import RejectForm from "./Form/RejectForm"; +import { useTranslations } from "next-intl"; const TableRowActions = ({ row }) => { + const t = useTranslations(); const { openConfirmDialog, openRejectDialog, @@ -20,14 +22,16 @@ const TableRowActions = ({ row }) => { } = useContext(DataTableContext); return ( - { - handleOpenConfirmDialog(row); - }} - > - - + + { + handleOpenConfirmDialog(row); + }} + > + + + {openConfirmDialog && ( { confirmData={confirmData} /> )} - handleOpenRejectDialog(row)}> - - + + handleOpenRejectDialog(row)}> + + + {openRejectDialog && ( { const t = useTranslations(); + const { directionApp } = useDirection(); const [proposedAmount, setProposedAmount] = useState(""); const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); //formik const validationSchema = Yup.object().shape({ @@ -48,9 +56,26 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { } formik.handleChange(event); }; + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("confirm_img", uploadedFile); + setShowAddIcon(false); + } + }; return ( - + {t("ConfirmDialog.confirm")} {t("ConfirmDialog.context")} @@ -88,14 +113,27 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { sx={{ mt: 1 }} fullWidth /> + - + ); diff --git a/src/components/dashboard/passenger-boss/Form/RejectForm.jsx b/src/components/dashboard/passenger-boss/Form/RejectForm.jsx index 18a48a7..eeb23c1 100644 --- a/src/components/dashboard/passenger-boss/Form/RejectForm.jsx +++ b/src/components/dashboard/passenger-boss/Form/RejectForm.jsx @@ -12,10 +12,18 @@ import { useTranslations } from "next-intl"; import { useFormik } from "formik"; import * as Yup from "yup"; import { useState } from "react"; +import UploadSystem from "@/core/components/UploadSystem"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import useDirection from "@/lib/app/hooks/useDirection"; const RejectForm = ({ open, handleClose, rowId, rejectData }) => { const t = useTranslations(); + const { directionApp } = useDirection(); const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const validationSchema = Yup.object().shape({ description: Yup.string().required(t("RejectDialog.description_error")), @@ -39,8 +47,26 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { formik.handleChange(event); }; + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("reject_img", uploadedFile); + setShowAddIcon(false); + } + }; + return ( - + {t("RejectDialog.reject")} {t("RejectDialog.context")} @@ -60,14 +86,27 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { variant="outlined" sx={{ mt: 1 }} /> + - + ); diff --git a/src/components/dashboard/passenger-boss/TableRowActions.jsx b/src/components/dashboard/passenger-boss/TableRowActions.jsx index e9e815e..c7ee618 100644 --- a/src/components/dashboard/passenger-boss/TableRowActions.jsx +++ b/src/components/dashboard/passenger-boss/TableRowActions.jsx @@ -1,12 +1,14 @@ import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; import ThumbDownIcon from "@mui/icons-material/ThumbDown"; -import { Box, IconButton } from "@mui/material"; +import { Box, IconButton, Tooltip } from "@mui/material"; import { useContext } from "react"; import { DataTableContext } from "@/lib/app/contexts/DataTableContext"; import ConfirmForm from "./Form/ConfirmForm"; import RejectForm from "./Form/RejectForm"; +import { useTranslations } from "next-intl"; const TableRowActions = ({ row }) => { + const t = useTranslations(); const { openConfirmDialog, openRejectDialog, @@ -20,14 +22,16 @@ const TableRowActions = ({ row }) => { } = useContext(DataTableContext); return ( - { - handleOpenConfirmDialog(row); - }} - > - - + + { + handleOpenConfirmDialog(row); + }} + > + + + {openConfirmDialog && ( { confirmData={confirmData} /> )} - handleOpenRejectDialog(row)}> - - + + handleOpenRejectDialog(row)}> + + + {openRejectDialog && ( { const t = useTranslations(); + const { directionApp } = useDirection(); const [description, setDescription] = useState(""); - const [fileData, setFileData] = useState(null); - const inputRef = useRef(null); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const formik = useFormik({ initialValues: { description: "", - fileData: null, }, onSubmit: () => { const formData = new FormData(); if (description !== "") formData.append("expert_description", description); - if (fileData !== null) formData.append("file", fileData); handleClose(); confirmData(CONFIRM_PASSENGER_OFFICE, rowId, formData); }, }); - const handleUploadClick = () => { - // 👇 We redirect the click event onto the hidden input element - inputRef.current?.click(); - }; - const handleDescriptionChange = (event) => { setDescription(event.target.value); formik.handleChange(event); }; - const handleFileChange = (e) => { - const selectedFile = e.target.files[0]; - if (selectedFile) { - const fileSizeInBytes = selectedFile.size; - if (fileSizeInBytes > MAX_FILE_SIZE_IN_BYTES) { - formik.setFieldError( - "fileData", - `File size exceeds the limit (${MAX_FILE_SIZE_IN_BYTES / 1000000} MB)` - ); - e.target.value = null; - } else { - setFileData(selectedFile); - formik.setFieldValue("fileData", selectedFile); - formik.setFieldError("fileData", ""); + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("confirm_img", uploadedFile); + setShowAddIcon(false); } }; return ( - + {t("ConfirmDialog.confirm")} {t("ConfirmDialog.context")} @@ -80,47 +77,27 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { variant="outlined" sx={{ mt: 1 }} /> -
- - -
- - {formik.errors.fileData && formik.errors.fileData} - +
- +
); diff --git a/src/components/dashboard/passenger-office/Form/RejectForm.jsx b/src/components/dashboard/passenger-office/Form/RejectForm.jsx index 149c480..d4ab6d6 100644 --- a/src/components/dashboard/passenger-office/Form/RejectForm.jsx +++ b/src/components/dashboard/passenger-office/Form/RejectForm.jsx @@ -12,10 +12,18 @@ import { useTranslations } from "next-intl"; import { useFormik } from "formik"; import * as Yup from "yup"; import { useState } from "react"; +import UploadSystem from "@/core/components/UploadSystem"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import useDirection from "@/lib/app/hooks/useDirection"; const RejectForm = ({ open, handleClose, rowId, rejectData }) => { const t = useTranslations(); + const { directionApp } = useDirection(); const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const validationSchema = Yup.object().shape({ description: Yup.string().required(t("RejectDialog.description_error")), @@ -38,9 +46,25 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { setDescription(event.target.value); formik.handleChange(event); }; - + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("reject_img", uploadedFile); + setShowAddIcon(false); + } + }; return ( - + {t("RejectDialog.reject")} {t("RejectDialog.context")} @@ -60,14 +84,27 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { variant="outlined" sx={{ mt: 1 }} /> + - + ); diff --git a/src/components/dashboard/passenger-office/TableRowActions.jsx b/src/components/dashboard/passenger-office/TableRowActions.jsx index e9e815e..c7ee618 100644 --- a/src/components/dashboard/passenger-office/TableRowActions.jsx +++ b/src/components/dashboard/passenger-office/TableRowActions.jsx @@ -1,12 +1,14 @@ import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; import ThumbDownIcon from "@mui/icons-material/ThumbDown"; -import { Box, IconButton } from "@mui/material"; +import { Box, IconButton, Tooltip } from "@mui/material"; import { useContext } from "react"; import { DataTableContext } from "@/lib/app/contexts/DataTableContext"; import ConfirmForm from "./Form/ConfirmForm"; import RejectForm from "./Form/RejectForm"; +import { useTranslations } from "next-intl"; const TableRowActions = ({ row }) => { + const t = useTranslations(); const { openConfirmDialog, openRejectDialog, @@ -20,14 +22,16 @@ const TableRowActions = ({ row }) => { } = useContext(DataTableContext); return ( - { - handleOpenConfirmDialog(row); - }} - > - - + + { + handleOpenConfirmDialog(row); + }} + > + + + {openConfirmDialog && ( { confirmData={confirmData} /> )} - handleOpenRejectDialog(row)}> - - + + handleOpenRejectDialog(row)}> + + + {openRejectDialog && ( { const t = useTranslations(); + const { directionApp } = useDirection(); const [description, setDescription] = useState(""); - const [fileData, setFileData] = useState(null); - const inputRef = useRef(null); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const formik = useFormik({ initialValues: { description: "", - fileData: null, }, onSubmit: () => { const formData = new FormData(); if (description !== "") formData.append("expert_description", description); - if (fileData !== null) formData.append("file", fileData); handleClose(); confirmData(CONFIRM_PROVINCE_MANAGER, rowId, formData); }, }); - const handleUploadClick = () => { - // 👇 We redirect the click event onto the hidden input element - inputRef.current?.click(); - }; - const handleDescriptionChange = (event) => { setDescription(event.target.value); formik.handleChange(event); }; - const handleFileChange = (e) => { - const selectedFile = e.target.files[0]; - if (selectedFile) { - const fileSizeInBytes = selectedFile.size; - if (fileSizeInBytes > MAX_FILE_SIZE_IN_BYTES) { - formik.setFieldError( - "fileData", - `File size exceeds the limit (${MAX_FILE_SIZE_IN_BYTES / 1000000} MB)` - ); - e.target.value = null; - } else { - setFileData(selectedFile); - formik.setFieldValue("fileData", selectedFile); - formik.setFieldError("fileData", ""); + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("confirm_img", uploadedFile); + setShowAddIcon(false); } }; return ( - + {t("ConfirmDialog.confirm")} {t("ConfirmDialog.context")} @@ -80,47 +77,27 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { variant="outlined" sx={{ mt: 1 }} /> -
- - -
- - {formik.errors.fileData && formik.errors.fileData} - +
- +
); diff --git a/src/components/dashboard/province-manager/Form/RejectForm.jsx b/src/components/dashboard/province-manager/Form/RejectForm.jsx index 53f3c62..430c5b2 100644 --- a/src/components/dashboard/province-manager/Form/RejectForm.jsx +++ b/src/components/dashboard/province-manager/Form/RejectForm.jsx @@ -12,10 +12,18 @@ import { useTranslations } from "next-intl"; import { useFormik } from "formik"; import * as Yup from "yup"; import { useState } from "react"; +import UploadSystem from "@/core/components/UploadSystem"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import useDirection from "@/lib/app/hooks/useDirection"; const RejectForm = ({ open, handleClose, rowId, rejectData }) => { const t = useTranslations(); + const { directionApp } = useDirection(); const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const validationSchema = Yup.object().shape({ description: Yup.string().required(t("RejectDialog.description_error")), @@ -38,9 +46,26 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { setDescription(event.target.value); formik.handleChange(event); }; + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("reject_img", uploadedFile); + setShowAddIcon(false); + } + }; return ( - + {t("RejectDialog.reject")} {t("RejectDialog.context")} @@ -60,14 +85,27 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { variant="outlined" sx={{ mt: 1 }} /> + - + ); diff --git a/src/components/dashboard/province-manager/TableRowActions.jsx b/src/components/dashboard/province-manager/TableRowActions.jsx index e9e815e..c7ee618 100644 --- a/src/components/dashboard/province-manager/TableRowActions.jsx +++ b/src/components/dashboard/province-manager/TableRowActions.jsx @@ -1,12 +1,14 @@ import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; import ThumbDownIcon from "@mui/icons-material/ThumbDown"; -import { Box, IconButton } from "@mui/material"; +import { Box, IconButton, Tooltip } from "@mui/material"; import { useContext } from "react"; import { DataTableContext } from "@/lib/app/contexts/DataTableContext"; import ConfirmForm from "./Form/ConfirmForm"; import RejectForm from "./Form/RejectForm"; +import { useTranslations } from "next-intl"; const TableRowActions = ({ row }) => { + const t = useTranslations(); const { openConfirmDialog, openRejectDialog, @@ -20,14 +22,16 @@ const TableRowActions = ({ row }) => { } = useContext(DataTableContext); return ( - { - handleOpenConfirmDialog(row); - }} - > - - + + { + handleOpenConfirmDialog(row); + }} + > + + + {openConfirmDialog && ( { confirmData={confirmData} /> )} - handleOpenRejectDialog(row)}> - - + + handleOpenRejectDialog(row)}> + + + {openRejectDialog && ( { const t = useTranslations(); - const handleConfirm = () => { - handleClose(); - confirmData(CONFIRM_TRANSPORTATION_ASSISTANCE, rowId); + const { directionApp } = useDirection(); + const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); + + const formik = useFormik({ + initialValues: { + description: "", + }, + onSubmit: () => { + const formData = new FormData(); + if (description != "") formData.append("expert_description", description); + handleClose(); + confirmData(CONFIRM_TRANSPORTATION_ASSISTANCE, rowId, formData); + }, + }); + + const handleDescriptionChange = (event) => { + setDescription(event.target.value); + }; + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("confirm_img", uploadedFile); + setShowAddIcon(false); + } }; return ( - + {t("ConfirmDialog.confirm")} {t("ConfirmDialog.context")} + + - + ); diff --git a/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx b/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx index 262f9db..a022a33 100644 --- a/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx +++ b/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx @@ -12,10 +12,18 @@ import { useTranslations } from "next-intl"; import { useFormik } from "formik"; import * as Yup from "yup"; import { useState } from "react"; +import UploadSystem from "@/core/components/UploadSystem"; +import UploadFileNotification from "@/core/components/notifications/UploadFileNotification"; +import useDirection from "@/lib/app/hooks/useDirection"; const RejectForm = ({ open, handleClose, rowId, rejectData }) => { const [description, setDescription] = useState(""); + const [selectedImage, setSelectedImage] = useState(""); + const [fileType, setfileType] = useState(null); + const [fileName, setfileName] = useState(null); + const [showAddIcon, setShowAddIcon] = useState(true); const t = useTranslations(); + const { directionApp } = useDirection(); const validationSchema = Yup.object().shape({ description: Yup.string().required(t("RejectDialog.description_error")), @@ -38,9 +46,25 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { setDescription(event.target.value); formik.handleChange(event); }; - + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const maxFileSize = 2 * 1024 * 1024; + if (uploadedFile.size > maxFileSize) { + UploadFileNotification(directionApp, t); + 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("reject_img", uploadedFile); + setShowAddIcon(false); + } + }; return ( - + {t("RejectDialog.reject")} {t("RejectDialog.context")} @@ -60,14 +84,27 @@ const RejectForm = ({ open, handleClose, rowId, rejectData }) => { variant="outlined" sx={{ mt: 1 }} /> + - + ); diff --git a/src/components/dashboard/transportation-assistance/TableRowActions.jsx b/src/components/dashboard/transportation-assistance/TableRowActions.jsx index e9e815e..ccd5bde 100644 --- a/src/components/dashboard/transportation-assistance/TableRowActions.jsx +++ b/src/components/dashboard/transportation-assistance/TableRowActions.jsx @@ -1,12 +1,15 @@ import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; import ThumbDownIcon from "@mui/icons-material/ThumbDown"; -import { Box, IconButton } from "@mui/material"; +import { Box, IconButton, Tooltip } from "@mui/material"; import { useContext } from "react"; import { DataTableContext } from "@/lib/app/contexts/DataTableContext"; import ConfirmForm from "./Form/ConfirmForm"; import RejectForm from "./Form/RejectForm"; +import { useTranslations } from "next-intl"; const TableRowActions = ({ row }) => { + const t = useTranslations(); + const { openConfirmDialog, openRejectDialog, @@ -20,14 +23,16 @@ const TableRowActions = ({ row }) => { } = useContext(DataTableContext); return ( - { - handleOpenConfirmDialog(row); - }} - > - - + + { + handleOpenConfirmDialog(row); + }} + > + + + {openConfirmDialog && ( { confirmData={confirmData} /> )} - handleOpenRejectDialog(row)}> - - + + handleOpenRejectDialog(row)}> + + + {openRejectDialog && ( { + const t = useTranslations(); + const fileInputRef = useRef(null); + + const handleClick = () => { + fileInputRef.current.click(); + }; + + const handleDeleteImage = () => { + setselectedImage(null); + setFieldValue(fieldname, null); + setShowAddIcon(true); + }; + + 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 ( + + {showAddIcon ? ( + // Show the add icon and "Upload File" text when no image is selected + <> + + + + {t("UploadSystem.upload_file")} + + + + ) : ( + // Show the uploaded content along with the delete button when an image or document is selected + <> + {fileType && fileType.startsWith("image/") ? ( + {imageAlt} + ) : ( + fileType && + isDocumentFormat(fileType) && ( + + + {fileName} + + + ) + )} + + + )} + + + ); +}; + +export default UploadSystem; diff --git a/src/core/components/notifications/ErrorNotification.jsx b/src/core/components/notifications/ErrorNotification.jsx index 6fb64d8..f0c887d 100644 --- a/src/core/components/notifications/ErrorNotification.jsx +++ b/src/core/components/notifications/ErrorNotification.jsx @@ -4,7 +4,7 @@ import { toast } from "react-toastify"; const ErrorNotification = (directionApp, status, t, message) => { toast( - ({ closeToast }) => ( + () => ( <> { + toast( + ({ closeToast }) => ( + <> + + + + + + {t("UploadSystem.uploadfile_error")} + + + + + + ), + { + position: directionApp === "ltr" ? "top-left" : "top-right", + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); +}; + +export default UploadFileNotification; diff --git a/src/core/components/notifications/WarningNotification.jsx b/src/core/components/notifications/WarningNotification.jsx new file mode 100644 index 0000000..8a2bfa3 --- /dev/null +++ b/src/core/components/notifications/WarningNotification.jsx @@ -0,0 +1,41 @@ +import ReportIcon from "@mui/icons-material/Report"; +import { Box, Typography } from "@mui/material"; +import { toast } from "react-toastify"; + +const WarningNotification = (directionApp, status, t) => { + toast( + () => ( + <> + + + + + + {t("notifications.warning")} ({t("notifications.code")}:{" "} + {status}) + + + {t("notifications.warning_static_text")} + + + + + + ), + { + position: directionApp === "ltr" ? "top-left" : "top-right", + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); +}; + +export default WarningNotification; diff --git a/src/core/components/notifications/index.jsx b/src/core/components/notifications/index.jsx index f9eb82c..ddef384 100644 --- a/src/core/components/notifications/index.jsx +++ b/src/core/components/notifications/index.jsx @@ -1,4 +1,5 @@ import ErrorNotification from "./ErrorNotification"; +import WarningNotification from "./WarningNotification"; import SuccessNotification from "./successNotification"; const Notifications = async (directionApp, response, t) => { diff --git a/src/core/utils/theme.jsx b/src/core/utils/theme.jsx index 7fd1e47..e921777 100644 --- a/src/core/utils/theme.jsx +++ b/src/core/utils/theme.jsx @@ -16,6 +16,15 @@ const theme = { }, }, faIR, + components: { + MuiBackdrop: { + styleOverrides: { + root: { + backgroundColor: "#02020226", // Replace with your desired backdrop color and opacity + }, + }, + }, + }, }; export default theme; diff --git a/src/layouts/dashboardLayouts/header/ProfileData.jsx b/src/layouts/dashboardLayouts/header/ProfileData.jsx index c3fdf58..e07dba6 100644 --- a/src/layouts/dashboardLayouts/header/ProfileData.jsx +++ b/src/layouts/dashboardLayouts/header/ProfileData.jsx @@ -8,10 +8,10 @@ export default function ProfileData() { - {user.user_username} + {user.username} ); diff --git a/src/layouts/dashboardLayouts/header/ProfileMenu.jsx b/src/layouts/dashboardLayouts/header/ProfileMenu.jsx index 50f34db..1c53ef5 100644 --- a/src/layouts/dashboardLayouts/header/ProfileMenu.jsx +++ b/src/layouts/dashboardLayouts/header/ProfileMenu.jsx @@ -29,7 +29,7 @@ function ProfileMenu() { color: "primary.main", }} alt="User Image" - src={user.user_avatar} + src={user.avatar} /> diff --git a/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx b/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx index 8d56ad0..949b171 100644 --- a/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx +++ b/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx @@ -2,6 +2,7 @@ import { NextLinkComposed } from "@/core/components/LinkRouting"; import ExpandLess from "@mui/icons-material/ExpandLess"; import ExpandMore from "@mui/icons-material/ExpandMore"; import { + Badge, ListItem, ListItemButton, ListItemIcon, @@ -59,6 +60,15 @@ const SidebarListItem = ({ item, dispatch, handleDrawerToggle }) => { {item.type == "menu" && (item.showSubItem ? : )} + {item.subItem && ( diff --git a/src/pages/dashboard/loan-follow-up/index.jsx b/src/pages/dashboard/loan-follow-up/index.jsx deleted file mode 100644 index 6bab35f..0000000 --- a/src/pages/dashboard/loan-follow-up/index.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import DashboardLoanFollowUpComponent from "@/components/dashboard/loan-follow-up"; -import TitlePage from "@/core/components/TitlePage"; -import WithAuthMiddleware from "@/middlewares/WithoutAuth"; -import { parse } from "next-useragent"; - -export default function LoanFollowUp() { - return ( - - - - - ); -} - -export async function getServerSideProps({ req, locale }) { - const { isBot } = parse(req.headers["user-agent"]); - return { - props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, - isBot, - }, - }; -} diff --git a/src/pages/dashboard/loan-request/index.jsx b/src/pages/dashboard/loan-request/index.jsx deleted file mode 100644 index ad64ce8..0000000 --- a/src/pages/dashboard/loan-request/index.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import DashboardLoanRequestComponent from "@/components/dashboard/loan-request"; -import TitlePage from "@/core/components/TitlePage"; -import WithAuthMiddleware from "@/middlewares/WithoutAuth"; -import { parse } from "next-useragent"; - -export default function LoanRequest() { - return ( - - - - - ); -} - -export async function getServerSideProps({ req, locale }) { - const { isBot } = parse(req.headers["user-agent"]); - return { - props: { - messages: (await import(`&/locales/${locale}/app.json`)).default, - isBot, - }, - }; -} diff --git a/src/pages/dashboard/transportation-assistance/index.jsx b/src/pages/dashboard/transportation-assistance/index.jsx index 9c089ad..ef9a661 100644 --- a/src/pages/dashboard/transportation-assistance/index.jsx +++ b/src/pages/dashboard/transportation-assistance/index.jsx @@ -6,7 +6,7 @@ import { parse } from "next-useragent"; export default function TransportationAssistance() { return ( - + );