diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 6c9d65b..19247db 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -47,6 +47,7 @@ "refahi": "رفاهی", "navgan": "ناوگان", "reports": "گزارشات", + "reports-refahi": "گزارشات", "refahi-province-manager": "بررسی وام های تبصره 18", "admin-setting": "تنظیمات ", "machinery-expert": "کارتابل کارشناسی", @@ -82,6 +83,8 @@ "passenger-boss": "کارگروه", "loan-followup": "ناوگان", "loan-history": "ناوگان", + "reports": "ناوگان", + "reports-refahi": "رفاهی", "refahi-loan-management": "رفاهی", "loan-history-refahi": "رفاهی", "refahi-province-manager": "رفاهی", @@ -1048,10 +1051,39 @@ "transportation_assistant": "عملکرد معاون", "province_manager": "عملکرد مدیر", "bank": "عملکرد بانک", + "bus": "گزارش عملکرد ناوگان اتوبوس", + "report_build": "گزارش عملکرد ساخت مجتمع رفاهی", + "report_repair": "گزارش عملکرد مرمت مجتمع رفاهی", + "rejected_loans": "رد درخواست", + "reserved_loans": "رزرو شده", + "sent_to_planning_council": "ارسال به شورا", + "need_user_modification": "نیاز به اصلاح کاربر", + "minibus": "گزارش عملکرد ناوگان مینی بوس", + "bank_report_bus": "گزارش عملکرد موسسه عامل (اتوبوس)", + "bank_report_minibus": "گزارش عملکرد موسسه عامل (مینی بوس)", + "bank_report_build": "گزارش عملکرد موسسه عامل (ساخت)", + "bank_report_repair": "گزارش عملکرد موسسه عامل (مرمت)", + "pending_bank_contract": "در انتظار انعقاد قرارداد", + "bank_rejected": "رد درخواست", + "bank_paid": "پرداخت شده", + "planing_council_bus": "گزارش عملکرد شورا برنامه ریزی (اتوبوس)", + "planing_council_minibus": "گزارش عملکرد شورا برنامه ریزی (مینی بوس)", + "planing_council_build": "گزارش عملکرد شورا برنامه ریزی (ساخت)", + "planing_council_repair": "گزارش عملکرد شورا برنامه ریزی (مرمت)", + "planning_council_referred": "عودت جهت اصلاح", + "planning_council_rejected": "رد درخواست", + "planning_council_confirmed": "تایید و ارسال به بانک", "loan_progress": "درصد پیشرفت تسویه وام", "loan_distribution": "درصد توزیع وام ها در هر مرحله", "filter_as": "فیلتر های اعمال شده", "loan_details": "جزئیات وام ها", + "performance_report": "گزارش عملکرد", + "edit_required": "نیاز به اصلاح", + "send_to_shora": "ارسال به شورا", + "reserved": "رزرو شده", + "reject": "رد درخواست", + "build": "ساخت مجتمع رفاهی", + "repair": "مرمت مجتمع رفاهی", "cost_of_loan_refer_to_bank": "مبلغ وام های معرفی به بانک", "number_of_loan_refer_to_bank": "تعداد وام های معرفی به بانک", "cost_of_payed_loan": "مبلغ وام های پرداخت شده", diff --git a/src/components/dashboard/loan-history/navgan/index.jsx b/src/components/dashboard/loan-history/navgan/index.jsx index 118009d..d5db2a8 100644 --- a/src/components/dashboard/loan-history/navgan/index.jsx +++ b/src/components/dashboard/loan-history/navgan/index.jsx @@ -47,10 +47,10 @@ function DashboardLoanHistoryComponent() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.name, + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), id: "name", header: t("LoanHistory.name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/loan-history/refahi/Buttons/printExcel.jsx b/src/components/dashboard/loan-history/refahi/Buttons/printExcel.jsx index 9afd5e8..d48e436 100644 --- a/src/components/dashboard/loan-history/refahi/Buttons/printExcel.jsx +++ b/src/components/dashboard/loan-history/refahi/Buttons/printExcel.jsx @@ -2,7 +2,7 @@ import { Button, CircularProgress } from "@mui/material"; import { useTranslations } from "next-intl"; import { useMemo, useState } from "react"; import useRequest from "@/lib/app/hooks/useRequest"; -import { EXPORT_LOAN_HISTORY } from "@/core/data/apiRoutes"; +import { EXPORT_LOAN_HISTORY_REFAHI } from "@/core/data/apiRoutes"; import moment from "jalali-moment"; import FileSaver from "file-saver"; import DescriptionIcon from "@mui/icons-material/Description"; @@ -37,7 +37,7 @@ const PrintExcel = ({ table }) => { const clickHandler = () => { setLoading(true); - requestServer(`${EXPORT_LOAN_HISTORY}?${filterParams}`, "get", { + requestServer(`${EXPORT_LOAN_HISTORY_REFAHI}?${filterParams}`, "get", { auth: true, requestOptions: { responseType: "blob" }, }) diff --git a/src/components/dashboard/loan-history/refahi/Form/HistoryForm/TableContent.jsx b/src/components/dashboard/loan-history/refahi/Form/HistoryForm/TableContent.jsx index 831c842..948cf3f 100644 --- a/src/components/dashboard/loan-history/refahi/Form/HistoryForm/TableContent.jsx +++ b/src/components/dashboard/loan-history/refahi/Form/HistoryForm/TableContent.jsx @@ -11,7 +11,7 @@ import { Typography, } from "@mui/material"; import { useTranslations } from "next-intl"; -import { GET_HISTORY_DETAIL } from "@/core/data/apiRoutes"; +import { GET_HISTORY_DETAIL_REFAHI } from "@/core/data/apiRoutes"; import moment from "jalali-moment"; import PrintHistory from "./PrintHistory"; import useRequest from "@/lib/app/hooks/useRequest"; @@ -32,7 +32,7 @@ const TableContent = ({ rowId }) => { const [error, setError] = useState(false); useEffect(() => { - requestServer(`${GET_HISTORY_DETAIL}/${rowId}`, "get") + requestServer(`${GET_HISTORY_DETAIL_REFAHI}/${rowId}`, "get") .then((response) => { setIsLoading(false); setHistoryDetails(response.data.data); diff --git a/src/components/dashboard/loan-history/refahi/index.jsx b/src/components/dashboard/loan-history/refahi/index.jsx index 118009d..af60ad9 100644 --- a/src/components/dashboard/loan-history/refahi/index.jsx +++ b/src/components/dashboard/loan-history/refahi/index.jsx @@ -1,11 +1,9 @@ -import { Box, Stack, Typography } from "@mui/material"; +import { Box, Typography } from "@mui/material"; import { useMemo } from "react"; -import { GET_LOAN_HISTORY } from "@/core/data/apiRoutes"; +import { GET_LOAN_HISTORY_REFAHI } from "@/core/data/apiRoutes"; import { useTranslations } from "next-intl"; import TableRowActions from "./TableRowActions"; -import moment from "jalali-moment"; import DataTable from "@/core/components/DataTable"; -import MuiDatePicker from "@/core/components/MuiDatePicker"; import TableToolbar from "./TableToolbar"; function DashboardLoanHistoryComponent() { @@ -37,20 +35,11 @@ function DashboardLoanHistoryComponent() { ), }, { - accessorFn: (row) => row.navgan_id, - id: "navgan_id", - header: t("LoanHistory.navgan_id"), - enableColumnFilter: true, - datatype: "numeric", - filterFn: "equals", - columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "between"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.name, + accessorFn: (row) => + row.is_legal_person === 1 ? `${row.company_name}` : `${row.first_name} ${row.last_name}`, id: "name", header: t("LoanHistory.name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], @@ -132,88 +121,6 @@ function DashboardLoanHistoryComponent() { columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "between"], Cell: ({ renderedCellValue }) => {renderedCellValue}, }, - { - accessorFn: (row) => row.statement_count, - id: "statement_count", - header: t("LoanHistory.statement_count"), - enableColumnFilter: true, - datatype: "numeric", - filterFn: "equals", - columnFilterModeOptions: ["equals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.navgan_capacity, - id: "navgan_capacity", - header: t("LoanHistory.navgan_capacity"), - enableColumnFilter: true, - datatype: "numeric", - filterFn: "equals", - columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "between"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.manufacture_date, - id: "manufacture_date", - header: t("LoanHistory.manufacture_date"), - enableColumnFilter: true, - datatype: "numeric", - filterFn: "equals", - columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "between"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.vehicle_type, - id: "vehicle_type", - header: t("LoanHistory.vehicle_type"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.plate_number, - id: "plate_number", - header: t("LoanHistory.plate_number"), - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => ( - - - {renderedCellValue.split("-")[3]} - - - - {renderedCellValue.split("-")[2]} - - - {renderedCellValue.split("-")[1]} - - - {renderedCellValue.split("-")[0]} - - - - ), - }, { accessorFn: (row) => row.approved_amount, id: "approved_amount", @@ -330,18 +237,18 @@ function DashboardLoanHistoryComponent() { return ( {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", header: t("BankManagement.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("BankManagement.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/LegalTableContent.jsx index 8c01afb..575d4cd 100644 --- a/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/LegalTableContent.jsx @@ -49,18 +49,7 @@ const LegalTableContent = ({ rowId, row }) => { - - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} - + {row.original.name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/RealTableContent.jsx index 34e4223..8d69ee6 100644 --- a/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/navgan/loan-followup/Form/UserInfoForm/RealTableContent.jsx @@ -45,20 +45,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/loan-followup/index.jsx b/src/components/dashboard/navgan/loan-followup/index.jsx index 92ccd9e..3f00afd 100644 --- a/src/components/dashboard/navgan/loan-followup/index.jsx +++ b/src/components/dashboard/navgan/loan-followup/index.jsx @@ -33,20 +33,10 @@ function DashboardLoanFollowUpComponent() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", header: t("LoanFollowUp.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("LoanFollowUp.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/navgan/navgan-loan-management/index.jsx b/src/components/dashboard/navgan/navgan-loan-management/index.jsx index b0b244d..c652998 100644 --- a/src/components/dashboard/navgan/navgan-loan-management/index.jsx +++ b/src/components/dashboard/navgan/navgan-loan-management/index.jsx @@ -50,20 +50,10 @@ function DashboardNavganLoanManagementComponent() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", header: t("NavganLoanManagement.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("NavganLoanManagement.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/LegalTableContent.jsx index 8c01afb..575d4cd 100644 --- a/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/LegalTableContent.jsx @@ -49,18 +49,7 @@ const LegalTableContent = ({ rowId, row }) => { - - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} - + {row.original.name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/RealTableContent.jsx index 34e4223..8d69ee6 100644 --- a/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/navgan/navgan-province-manager/Form/UserInfoForm/RealTableContent.jsx @@ -45,20 +45,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/navgan-province-manager/index.jsx b/src/components/dashboard/navgan/navgan-province-manager/index.jsx index 2de65d3..9b8ca24 100644 --- a/src/components/dashboard/navgan/navgan-province-manager/index.jsx +++ b/src/components/dashboard/navgan/navgan-province-manager/index.jsx @@ -50,20 +50,10 @@ function DashboardNavganProvinceManagerComponent() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", header: t("NavganProvinceManager.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("NavganProvinceManager.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx index 8c01afb..45ea430 100644 --- a/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx @@ -45,22 +45,11 @@ const LegalTableContent = ({ rowId, row }) => { - + - - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} - + {row.original.name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/RealTableContent.jsx index 34e4223..8d69ee6 100644 --- a/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/navgan/passenger-boss/Form/UserInfoForm/RealTableContent.jsx @@ -45,20 +45,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/passenger-boss/index.jsx b/src/components/dashboard/navgan/passenger-boss/index.jsx index fa3cc5e..5363095 100644 --- a/src/components/dashboard/navgan/passenger-boss/index.jsx +++ b/src/components/dashboard/navgan/passenger-boss/index.jsx @@ -48,20 +48,10 @@ function DashboardPassengerOfficeComponent() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", - header: t("PassengerBoss.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("PassengerBoss.last_name"), - enableColumnFilter: true, + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", + header: t("PassengerBoss.name"), + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/navgan/reserve-loan/index.jsx b/src/components/dashboard/navgan/reserve-loan/index.jsx index 43986f6..789f5f9 100644 --- a/src/components/dashboard/navgan/reserve-loan/index.jsx +++ b/src/components/dashboard/navgan/reserve-loan/index.jsx @@ -47,20 +47,10 @@ function DashboardReserveLoan() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", - header: t("ReserveLoan.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("ReserveLoan.last_name"), - enableColumnFilter: true, + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", + header: t("ReserveLoan.name"), + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx index 8c01afb..575d4cd 100644 --- a/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx @@ -49,18 +49,7 @@ const LegalTableContent = ({ rowId, row }) => { - - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} - + {row.original.name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx index 34e4223..8d69ee6 100644 --- a/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/navgan/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx @@ -45,20 +45,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/navgan/transportation-assistance/index.jsx b/src/components/dashboard/navgan/transportation-assistance/index.jsx index 327d52a..10d6880 100644 --- a/src/components/dashboard/navgan/transportation-assistance/index.jsx +++ b/src/components/dashboard/navgan/transportation-assistance/index.jsx @@ -49,20 +49,10 @@ function DashboardTransportationAssistanceComponent() { Cell: ({ renderedCellValue }) => {renderedCellValue}, }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => (row.is_legal_person === 1 ? `${row.name}` : `${row.first_name} ${row.last_name}`), + id: "name", header: t("TransportationAssistance.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("TransportationAssistance.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/LegalTableContent.jsx index 2646c62..96caeae 100644 --- a/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/LegalTableContent.jsx @@ -47,21 +47,12 @@ const LegalTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} + {row.original.company_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/RealTableContent.jsx index 2a2bc4b..9bdf701 100644 --- a/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/refahi/loan-followup/Form/UserInfoForm/RealTableContent.jsx @@ -48,20 +48,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/loan-followup/index.jsx b/src/components/dashboard/refahi/loan-followup/index.jsx index c52b0e5..b148874 100644 --- a/src/components/dashboard/refahi/loan-followup/index.jsx +++ b/src/components/dashboard/refahi/loan-followup/index.jsx @@ -47,20 +47,11 @@ function DashboardLoanFollowUpComponent() { ), }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => + row.is_legal_person === 1 ? `${row.company_name}` : `${row.first_name} ${row.last_name}`, + id: "name", header: t("RefahiLoanFollowUp.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("RefahiLoanFollowUp.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx index 2646c62..96caeae 100644 --- a/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/LegalTableContent.jsx @@ -47,21 +47,12 @@ const LegalTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} + {row.original.company_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/RealTableContent.jsx index 2a2bc4b..9bdf701 100644 --- a/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/refahi/passenger-boss/Form/UserInfoForm/RealTableContent.jsx @@ -48,20 +48,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/passenger-boss/restore/index.jsx b/src/components/dashboard/refahi/passenger-boss/restore/index.jsx index 19572da..dce8267 100644 --- a/src/components/dashboard/refahi/passenger-boss/restore/index.jsx +++ b/src/components/dashboard/refahi/passenger-boss/restore/index.jsx @@ -48,20 +48,11 @@ function DashboardPassengerOfficeComponent() { ), }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => + row.is_legal_person === 1 ? `${row.company_name}` : `${row.first_name} ${row.last_name}`, + id: "name", header: t("PassengerBoss.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("PassengerBoss.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/refahi/refahi-loan-management/index.jsx b/src/components/dashboard/refahi/refahi-loan-management/index.jsx index afea1cd..49f616a 100644 --- a/src/components/dashboard/refahi/refahi-loan-management/index.jsx +++ b/src/components/dashboard/refahi/refahi-loan-management/index.jsx @@ -47,20 +47,11 @@ function DashboardRefahiLoanManagementComponent() { ), }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => + row.is_legal_person === 1 ? `${row.company_name}` : `${row.first_name} ${row.last_name}`, + id: "name", header: t("RefahiLoanManagement.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("RefahiLoanManagement.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/LegalTableContent.jsx index 2646c62..96caeae 100644 --- a/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/LegalTableContent.jsx @@ -47,21 +47,12 @@ const LegalTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} + {row.original.company_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/RealTableContent.jsx index 2a2bc4b..9bdf701 100644 --- a/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/refahi/refahi-province-manager/Form/UserInfoForm/RealTableContent.jsx @@ -48,20 +48,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/refahi-province-manager/restore/index.jsx b/src/components/dashboard/refahi/refahi-province-manager/restore/index.jsx index 0a54133..a08d339 100644 --- a/src/components/dashboard/refahi/refahi-province-manager/restore/index.jsx +++ b/src/components/dashboard/refahi/refahi-province-manager/restore/index.jsx @@ -47,20 +47,11 @@ function DashboardRefahiProvinceManagerComponent() { ), }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => + row.is_legal_person === 1 ? `${row.company_name}` : `${row.first_name} ${row.last_name}`, + id: "name", header: t("NavganProvinceManager.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("NavganProvinceManager.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx b/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx index 2646c62..96caeae 100644 --- a/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx +++ b/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/LegalTableContent.jsx @@ -47,21 +47,12 @@ const LegalTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - - {row.original.last_name || t("UserInfoDialog.no_info")} + {row.original.company_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx b/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx index 2a2bc4b..9bdf701 100644 --- a/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx +++ b/src/components/dashboard/refahi/transportation-assistance/Form/UserInfoForm/RealTableContent.jsx @@ -48,20 +48,12 @@ const RealTableContent = ({ rowId, row }) => { - + - {row.original.first_name || t("UserInfoDialog.no_info")} - - - - - - - - + {row.original.first_name || t("UserInfoDialog.no_info")}{" "} {row.original.last_name || t("UserInfoDialog.no_info")} diff --git a/src/components/dashboard/refahi/transportation-assistance/restore/index.jsx b/src/components/dashboard/refahi/transportation-assistance/restore/index.jsx index c6543dc..dce496e 100644 --- a/src/components/dashboard/refahi/transportation-assistance/restore/index.jsx +++ b/src/components/dashboard/refahi/transportation-assistance/restore/index.jsx @@ -47,20 +47,11 @@ function DashboardTransportationAssistanceComponent() { ), }, { - accessorFn: (row) => row.first_name, - id: "first_name", + accessorFn: (row) => + row.is_legal_person === 1 ? `${row.company_name}` : `${row.first_name} ${row.last_name}`, + id: "name", header: t("TransportationAssistance.first_name"), - enableColumnFilter: true, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({ renderedCellValue }) => {renderedCellValue}, - }, - { - accessorFn: (row) => row.last_name, - id: "last_name", - header: t("TransportationAssistance.last_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "text", filterFn: "contains", columnFilterModeOptions: ["contains", "equals", "notEquals"], diff --git a/src/components/dashboard/reports/LoanDetails/FunctionalityCharts.jsx b/src/components/dashboard/reports/LoanDetails/FunctionalityCharts.jsx deleted file mode 100644 index 80c7ed6..0000000 --- a/src/components/dashboard/reports/LoanDetails/FunctionalityCharts.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Grid, Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; -import RadialBarSemiCircularChart from "@/components/dashboard/reports/LoanDetails/RadialBarSemiCircularChart"; - -const FunctionalityCharts = ({ reportList }) => { - const t = useTranslations(); - const DataItemsName = [ - { id: "expert", name: t("reports.expert") }, - { id: "transportation_assistant", name: t("reports.transportation_assistant") }, - { id: "province_manager", name: t("reports.province_manager") }, - { id: "bank", name: t("reports.bank") }, - ]; - return ( - - {Object.entries(reportList).map(([entryKey, innerObject]) => { - let percentage = - innerObject.total !== 0 && innerObject.pending !== 64 - ? ((innerObject.total - innerObject.pending) / innerObject.total) * 100 - : 0; - const ItemName = DataItemsName.find((item) => item.id === entryKey).name; - return ( - - - {ItemName} - - `${val}%`} - label={t("reports.dynamic_label_functionality", { - total: innerObject.total.toLocaleString("en"), - done: (innerObject.total - innerObject.pending).toLocaleString("en"), - })} - /> - - ); - })} - - ); -}; - -export default FunctionalityCharts; diff --git a/src/components/dashboard/reports/ExcelExport/index.jsx b/src/components/dashboard/reports/navgan/ExcelExport/index.jsx similarity index 100% rename from src/components/dashboard/reports/ExcelExport/index.jsx rename to src/components/dashboard/reports/navgan/ExcelExport/index.jsx diff --git a/src/components/dashboard/reports/Filter/ProvinceFilter.jsx b/src/components/dashboard/reports/navgan/Filter/ProvinceFilter.jsx similarity index 100% rename from src/components/dashboard/reports/Filter/ProvinceFilter.jsx rename to src/components/dashboard/reports/navgan/Filter/ProvinceFilter.jsx diff --git a/src/components/dashboard/reports/Filter/YearFilter.jsx b/src/components/dashboard/reports/navgan/Filter/YearFilter.jsx similarity index 100% rename from src/components/dashboard/reports/Filter/YearFilter.jsx rename to src/components/dashboard/reports/navgan/Filter/YearFilter.jsx diff --git a/src/components/dashboard/reports/Filter/index.jsx b/src/components/dashboard/reports/navgan/Filter/index.jsx similarity index 98% rename from src/components/dashboard/reports/Filter/index.jsx rename to src/components/dashboard/reports/navgan/Filter/index.jsx index b2f74f0..686a6dd 100644 --- a/src/components/dashboard/reports/Filter/index.jsx +++ b/src/components/dashboard/reports/navgan/Filter/index.jsx @@ -11,8 +11,8 @@ import { Typography, } from "@mui/material"; import { useFormik } from "formik"; -import ProvinceFilter from "../Filter/ProvinceFilter"; -import YearFilter from "../Filter/YearFilter"; +import ProvinceFilter from "./ProvinceFilter"; +import YearFilter from "./YearFilter"; import FilterAltIcon from "@mui/icons-material/FilterAlt"; import EqualizerIcon from "@mui/icons-material/Equalizer"; import { useTranslations } from "next-intl"; diff --git a/src/components/dashboard/reports/navgan/LoanDetails/FunctionalityCharts.jsx b/src/components/dashboard/reports/navgan/LoanDetails/FunctionalityCharts.jsx new file mode 100644 index 0000000..56e159a --- /dev/null +++ b/src/components/dashboard/reports/navgan/LoanDetails/FunctionalityCharts.jsx @@ -0,0 +1,36 @@ +import { Grid, Typography } from "@mui/material"; +import { useTranslations } from "next-intl"; +import UniqDetailComponent from "./UniqDetailComponent"; + +const FunctionalityCharts = ({ reportList, name }) => { + const t = useTranslations(); + + return ( + <> + + {name} + + + {Object.entries(reportList).map(([entryKey, innerObject]) => { + let percentage = + innerObject.total_budget !== 0 + ? (innerObject.total_amount / innerObject.total_budget) * 100 + : 0; + const numColumns = Object.entries(reportList).length; + let columnSize = 12 / numColumns; + return ( + + + + ); + })} + + + ); +}; + +export default FunctionalityCharts; diff --git a/src/components/dashboard/reports/LoanDetails/RadialBarSemiCircularChart.jsx b/src/components/dashboard/reports/navgan/LoanDetails/RadialBarSemiCircularChart.jsx similarity index 100% rename from src/components/dashboard/reports/LoanDetails/RadialBarSemiCircularChart.jsx rename to src/components/dashboard/reports/navgan/LoanDetails/RadialBarSemiCircularChart.jsx diff --git a/src/components/dashboard/reports/LoanDetails/ReferredCharts.jsx b/src/components/dashboard/reports/navgan/LoanDetails/ReferredCharts.jsx similarity index 97% rename from src/components/dashboard/reports/LoanDetails/ReferredCharts.jsx rename to src/components/dashboard/reports/navgan/LoanDetails/ReferredCharts.jsx index 113f2be..6222875 100644 --- a/src/components/dashboard/reports/LoanDetails/ReferredCharts.jsx +++ b/src/components/dashboard/reports/navgan/LoanDetails/ReferredCharts.jsx @@ -1,5 +1,5 @@ import { Box, Grid, Typography } from "@mui/material"; -import RadialBarSemiCircularChart from "@/components/dashboard/reports/LoanDetails/RadialBarSemiCircularChart"; +import RadialBarSemiCircularChart from "./RadialBarSemiCircularChart"; import { useTranslations } from "next-intl"; // Make sure to import React if it's not already imported const ReferredCharts = ({ reportList }) => { diff --git a/src/components/dashboard/reports/navgan/LoanDetails/UniqDetailComponent.jsx b/src/components/dashboard/reports/navgan/LoanDetails/UniqDetailComponent.jsx new file mode 100644 index 0000000..aeb185e --- /dev/null +++ b/src/components/dashboard/reports/navgan/LoanDetails/UniqDetailComponent.jsx @@ -0,0 +1,51 @@ +import { Box, Grid, Stack, Typography } from "@mui/material"; +import RadialBarSemiCircularChart from "./RadialBarSemiCircularChart"; +import { useTranslations } from "next-intl"; + +const UniqDetailComponent = ({ item, percentage, title }) => { + const t = useTranslations(); + return ( + + + + {title} + + + {t("reports.dynamic_total_budget", { + total_budget: (item.total_budget / 1000000).toLocaleString("en"), + })} + + + 100 ? 100 : percentage)} + formatter={(val) => `${Math.round(percentage)}%`} + label={t("reports.dynamic_label_referred", { + count: item.count.toLocaleString("en"), + total_amount: (item.total_amount / 1000000).toLocaleString("en"), + })} + /> + + ); +}; +export default UniqDetailComponent; diff --git a/src/components/dashboard/reports/LoanDetails/index.jsx b/src/components/dashboard/reports/navgan/LoanDetails/index.jsx similarity index 63% rename from src/components/dashboard/reports/LoanDetails/index.jsx rename to src/components/dashboard/reports/navgan/LoanDetails/index.jsx index 5c16ccf..c517771 100644 --- a/src/components/dashboard/reports/LoanDetails/index.jsx +++ b/src/components/dashboard/reports/navgan/LoanDetails/index.jsx @@ -1,12 +1,15 @@ import { Divider, Grid, Paper, Stack, Typography } from "@mui/material"; import { useTranslations } from "next-intl"; -import Filter from "@/components/dashboard/reports/Filter"; +import Filter from "../Filter"; import useChart from "@/lib/app/hooks/useChart"; -import { GET_LOAN_EXPERTPROGRESS, GET_LOAN_REFERREDLOANS } from "@/core/data/apiRoutes"; +import { + GET_LOAN_EXPERTPROGRESS_BANK_REPORT, + GET_LOAN_EXPERTPROGRESS_CARTABLE, + GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL, +} from "@/core/data/apiRoutes"; import LoadingHardPage from "@/core/components/LoadingHardPage"; import AnalyticsIcon from "@mui/icons-material/Analytics"; -import FunctionalityCharts from "@/components/dashboard/reports/LoanDetails/FunctionalityCharts"; -import ReferredCharts from "@/components/dashboard/reports/LoanDetails/ReferredCharts"; +import FunctionalityCharts from "./FunctionalityCharts"; const LoanDetails = () => { const t = useTranslations(); @@ -17,16 +20,21 @@ const LoanDetails = () => { reportList: reportList1, setFilterOption: setFilterOption1, mutate: mutate1, - } = useChart(GET_LOAN_EXPERTPROGRESS); - - // Use the useChart hook for the second API route + } = useChart(GET_LOAN_EXPERTPROGRESS_CARTABLE); const { errorReportList: errorReportList2, isLoadingReportList: isLoadingReportList2, reportList: reportList2, setFilterOption: setFilterOption2, mutate: mutate2, - } = useChart(GET_LOAN_REFERREDLOANS); + } = useChart(GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL); + const { + errorReportList: errorReportList3, + isLoadingReportList: isLoadingReportList3, + reportList: reportList3, + setFilterOption: setFilterOption3, + mutate: mutate3, + } = useChart(GET_LOAN_EXPERTPROGRESS_BANK_REPORT); return ( @@ -36,26 +44,28 @@ const LoanDetails = () => { setFilterOption={(fields) => { setFilterOption1(fields); setFilterOption2(fields); + setFilterOption3(fields); }} - isLoadingReportList={isLoadingReportList1 || isLoadingReportList2} + isLoadingReportList={isLoadingReportList1 || isLoadingReportList3 || isLoadingReportList2} mutate={() => { mutate1(); mutate2(); + mutate3(); }} /> - {isLoadingReportList1 || isLoadingReportList2 ? ( + {isLoadingReportList1 || isLoadingReportList2 || isLoadingReportList3 ? ( } - loading={isLoadingReportList1 || isLoadingReportList2} + loading={isLoadingReportList1 || isLoadingReportList2 || isLoadingReportList3} label={t("reports.loading_fetching_reports")} width={100} height={100} sx={{ position: "absolute", bgcolor: "#f7f7f7e6" }} /> - ) : errorReportList1 || errorReportList2 ? ( + ) : errorReportList1 || errorReportList2 || errorReportList3 ? ( { ) : ( - + - + + + + + + + + + )} diff --git a/src/components/dashboard/reports/index.jsx b/src/components/dashboard/reports/navgan/index.jsx similarity index 84% rename from src/components/dashboard/reports/index.jsx rename to src/components/dashboard/reports/navgan/index.jsx index 944c39b..87a22b9 100644 --- a/src/components/dashboard/reports/index.jsx +++ b/src/components/dashboard/reports/navgan/index.jsx @@ -1,5 +1,5 @@ -import LoanDetails from "@/components/dashboard/reports/LoanDetails"; -import ExcelExport from "@/components/dashboard/reports/ExcelExport"; +import LoanDetails from "./LoanDetails"; +import ExcelExport from "./ExcelExport"; import { GET_EXCEL_EXPORT, GET_EXCEL_EXPORT_status } from "@/core/data/apiRoutes"; import { useTranslations } from "next-intl"; diff --git a/src/components/dashboard/reports/refahi/ExcelExport/index.jsx b/src/components/dashboard/reports/refahi/ExcelExport/index.jsx new file mode 100644 index 0000000..f8b2cf6 --- /dev/null +++ b/src/components/dashboard/reports/refahi/ExcelExport/index.jsx @@ -0,0 +1,66 @@ +import { Accordion, AccordionSummary, Box, Button, CircularProgress, Stack, Typography } from "@mui/material"; +import AssignmentIcon from "@mui/icons-material/Assignment"; +import BackupIcon from "@mui/icons-material/Backup"; +import { useTranslations } from "next-intl"; +import moment from "jalali-moment"; +import FileSaver from "file-saver"; +import useRequest from "@/lib/app/hooks/useRequest"; +import { useState } from "react"; + +const ExcelExport = ({ filenameStr, url, title }) => { + const t = useTranslations(); + const requestServer = useRequest(); + const [loading, setLoading] = useState(false); + + const clickHandler = () => { + setLoading(true); + requestServer(url, "get", { + auth: true, + requestOptions: { responseType: "blob" }, + }) + .then((response) => { + const filename = `${filenameStr}_${moment().format("jDD_jMM_jYYYY")}.xlsx`; + FileSaver.saveAs(response.data, filename); + }) + .catch(() => {}) + .finally(() => { + setLoading(false); + }); + }; + + return ( + + + + + + + {title} + + + + + + + ); +}; + +export default ExcelExport; diff --git a/src/components/dashboard/reports/refahi/Filter/ProvinceFilter.jsx b/src/components/dashboard/reports/refahi/Filter/ProvinceFilter.jsx new file mode 100644 index 0000000..a9e2733 --- /dev/null +++ b/src/components/dashboard/reports/refahi/Filter/ProvinceFilter.jsx @@ -0,0 +1,122 @@ +import { + Box, + FormControl, + IconButton, + InputAdornment, + InputLabel, + MenuItem, + OutlinedInput, + Select, + Typography, +} from "@mui/material"; +import { useTranslations } from "next-intl"; +import useProvince from "@/lib/app/hooks/useProvince"; +import ClearIcon from "@mui/icons-material/Clear"; + +const provinceList = [ + { name: "قزوین", id: 1 }, + { name: "تبریز", id: 2 }, + { name: "مشهد", id: 3 }, +]; + +const ProvinceFilter = ({ formik, multiple, setFilteredText }) => { + const { errorProvinceList, isLoadingProvinceList, provinceList } = useProvince(); + const t = useTranslations(); + const provinceChange = (event) => { + const { + target: { value }, + } = event; + formik.setFieldValue("province_id", value); + if (Array.isArray(value)) { + const province_names = []; + value.map((item) => { + province_names.push(provinceList.find((province) => province.id === item).name); + }); + setFilteredText((prevState) => ({ + ...prevState, + province: province_names.length !== 0 ? `${t("filters.provinces")}: ${province_names.join(" , ")}` : "", + })); + } else { + const selectedProvince = provinceList.find((province) => province.id === value); + setFilteredText((prevState) => ({ + ...prevState, + province: `${t("filters.province")}: ${selectedProvince.name}`, + })); + } + }; + const needAdorment = multiple ? formik.values.province_id.length === 0 : formik.values.province_id === ""; + return ( + + {t("filters.choose_province")} + + + ); +}; + +export default ProvinceFilter; diff --git a/src/components/dashboard/reports/refahi/Filter/YearFilter.jsx b/src/components/dashboard/reports/refahi/Filter/YearFilter.jsx new file mode 100644 index 0000000..72cda4c --- /dev/null +++ b/src/components/dashboard/reports/refahi/Filter/YearFilter.jsx @@ -0,0 +1,72 @@ +import { Box, Chip, FormControl, InputLabel, MenuItem, OutlinedInput, Select } from "@mui/material"; +import moment from "jalali-moment"; +import { useTranslations } from "next-intl"; +import { periodOfYear } from "@/core/utils/yearPeriodFinder"; + +const currentShamsiYear = moment().format("jYYYY"); +const shamsiYearList = Array.from({ length: currentShamsiYear - 1399 }, (_, index) => + (currentShamsiYear - index).toString() +); + +const YearFilter = ({ formik, multiple, setFilteredText }) => { + const t = useTranslations(); + const yearChange = (event) => { + const { + target: { value }, + } = event; + formik.handleChange(event); + formik.setFieldValue("date", value); + const { from, to } = periodOfYear(value); + formik.setFieldValue("from_date", from); + formik.setFieldValue("to_date", to); + if (Array.isArray(value)) { + setFilteredText((prevState) => ({ + ...prevState, + year: `| ${t("filters.years")}: ${value.join(" , ")}`, + })); + } else { + setFilteredText((prevState) => ({ + ...prevState, + year: `| ${t("filters.year")}: ${value}`, + })); + } + }; + return ( + + {t("filters.choose_year")} + + + ); +}; + +export default YearFilter; diff --git a/src/components/dashboard/reports/refahi/Filter/index.jsx b/src/components/dashboard/reports/refahi/Filter/index.jsx new file mode 100644 index 0000000..686a6dd --- /dev/null +++ b/src/components/dashboard/reports/refahi/Filter/index.jsx @@ -0,0 +1,167 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Button, + CircularProgress, + IconButton, + Stack, + Tooltip, + Typography, +} from "@mui/material"; +import { useFormik } from "formik"; +import ProvinceFilter from "./ProvinceFilter"; +import YearFilter from "./YearFilter"; +import FilterAltIcon from "@mui/icons-material/FilterAlt"; +import EqualizerIcon from "@mui/icons-material/Equalizer"; +import { useTranslations } from "next-intl"; +import TroubleshootIcon from "@mui/icons-material/Troubleshoot"; +import CachedIcon from "@mui/icons-material/Cached"; +import { useEffect, useState } from "react"; +import moment from "jalali-moment"; + +const Filter = ({ title, filterItem, setFilterOption, isLoadingReportList, mutate }) => { + const t = useTranslations(); + const filter_by_province = filterItem.find((item) => item.type === "province"); + const filter_by_year = filterItem.find((item) => item.type === "year"); + const [expanded, setExpanded] = useState(true); + const [filteredText, setFilteredText] = useState({ + ...(filter_by_province ? { province: t("filters.all_provinces") } : {}), + ...(filter_by_year ? { year: "" } : {}), + }); + const [textFilter, setTextFilter] = useState(); + const [stepValue, setStepValue] = useState({ + ...(filter_by_year && { + date: filter_by_year.multiple ? [] : `${moment().format("jYYYY")}`, + }), + ...(filter_by_province && { + province_id: filter_by_province.multiple ? [] : "", + }), + from_date: "", + to_date: "", + }); + + const formik = useFormik({ + enableReinitialize: true, + initialValues: stepValue, + onSubmit: (values, { setSubmitting }) => { + setStepValue(values); + const province = values.province_id; + const fields = [ + values.from_date ? { key: "from_date", value: values.from_date } : null, + values.to_date ? { key: "to_date", value: values.to_date } : null, + ...(Array.isArray(province) + ? province.length !== 0 + ? province.map((item, index) => ({ key: `province_id[${index}]`, value: item })) + : [] + : province + ? [{ key: "province_id", value: province }] + : []), + ].filter(Boolean); + setFilterOption(fields); + textMaker(); + }, + }); + + const textMaker = () => { + setTextFilter(`| ${Object.values(filteredText).join(", ")}`); + }; + + useEffect(() => { + const province = formik.values.province_id; + const fields = [ + formik.values.from_date ? { key: "from_date", value: formik.values.from_date } : null, + formik.values.to_date ? { key: "to_date", value: formik.values.to_date } : null, + ...(Array.isArray(province) + ? province.length !== 0 + ? province.map((item, index) => ({ key: `province_id[${index}]`, value: item })) + : [] + : province + ? [{ key: "province_id", value: province }] + : []), + ].filter(Boolean); + setTextFilter(`| ${Object.values(filteredText).join(", ")}`); + }, []); + + return ( + {}} + sx={{ + mb: 2, + borderBottom: 2, + borderBottomColor: "divider", + backgroundColor: "#f1f1f1", + }} + > + + + + + {title} + + {textFilter} + + + + + mutate()} size="small"> + + + + + setExpanded((prevExpanded) => !prevExpanded)} size="small"> + + + + + + + + + {filter_by_province ? ( + + ) : ( + "" + )} + {filter_by_year ? ( + + ) : ( + "" + )} + + + + + + + ); +}; + +export default Filter; diff --git a/src/components/dashboard/reports/refahi/LoanDetails/FunctionalityCharts.jsx b/src/components/dashboard/reports/refahi/LoanDetails/FunctionalityCharts.jsx new file mode 100644 index 0000000..56e159a --- /dev/null +++ b/src/components/dashboard/reports/refahi/LoanDetails/FunctionalityCharts.jsx @@ -0,0 +1,36 @@ +import { Grid, Typography } from "@mui/material"; +import { useTranslations } from "next-intl"; +import UniqDetailComponent from "./UniqDetailComponent"; + +const FunctionalityCharts = ({ reportList, name }) => { + const t = useTranslations(); + + return ( + <> + + {name} + + + {Object.entries(reportList).map(([entryKey, innerObject]) => { + let percentage = + innerObject.total_budget !== 0 + ? (innerObject.total_amount / innerObject.total_budget) * 100 + : 0; + const numColumns = Object.entries(reportList).length; + let columnSize = 12 / numColumns; + return ( + + + + ); + })} + + + ); +}; + +export default FunctionalityCharts; diff --git a/src/components/dashboard/reports/refahi/LoanDetails/RadialBarSemiCircularChart.jsx b/src/components/dashboard/reports/refahi/LoanDetails/RadialBarSemiCircularChart.jsx new file mode 100644 index 0000000..6cf42b9 --- /dev/null +++ b/src/components/dashboard/reports/refahi/LoanDetails/RadialBarSemiCircularChart.jsx @@ -0,0 +1,42 @@ +import Chart from "@/core/components/Chart"; +import { calculateGradientColor } from "@/core/utils/gradientColorHandler"; + +const RadialBarSemiCircularChart = ({ data, label, formatter }) => { + const specialOption = { + title: { + text: undefined, + }, + plotOptions: { + radialBar: { + startAngle: -90, + endAngle: 90, + track: { + background: "#e7e7e7", + strokeWidth: "80%", + }, + dataLabels: { + name: { + fontSize: "1rem", + offsetY: 30, + color: "#8c8c8c", + }, + value: { + offsetY: -30, + fontSize: "30px", + fontWeight: 500, + color: "#8c8c8c", + formatter: formatter, + }, + }, + }, + }, + fill: { + colors: calculateGradientColor(data), + }, + labels: [label], + }; + const series = [data]; + return ; +}; + +export default RadialBarSemiCircularChart; diff --git a/src/components/dashboard/reports/refahi/LoanDetails/ReferredCharts.jsx b/src/components/dashboard/reports/refahi/LoanDetails/ReferredCharts.jsx new file mode 100644 index 0000000..6222875 --- /dev/null +++ b/src/components/dashboard/reports/refahi/LoanDetails/ReferredCharts.jsx @@ -0,0 +1,76 @@ +import { Box, Grid, Typography } from "@mui/material"; +import RadialBarSemiCircularChart from "./RadialBarSemiCircularChart"; +import { useTranslations } from "next-intl"; // Make sure to import React if it's not already imported + +const ReferredCharts = ({ reportList }) => { + const t = useTranslations(); + const DataItemsName = [ + { id: "referred_loans_to_bank", name: t("reports.referred_loans_to_bank") }, + { id: "paid_loans", name: t("reports.paid_loans") }, + ]; + + return ( + + {Object.entries(reportList).map(([entryKey, innerObject]) => { + const ItemName = DataItemsName.find((item) => item.id === entryKey).name; + return ( + + + + {ItemName} + + + + {innerObject.map((item, index) => { + let percentage = + item.total_budget !== 0 ? (item.total_amount / item.total_budget) * 100 : 0; + return ( + + + + {item.vehicle_type} + + + {t("reports.dynamic_total_budget", { + total_budget: (item.total_budget / 1000000).toLocaleString("en"), + })} + + + 100 ? 100 : percentage)} + formatter={(val) => `${Math.round(percentage)}%`} + label={t("reports.dynamic_label_referred", { + count: item.count.toLocaleString("en"), + total_amount: (item.total_amount / 1000000).toLocaleString("en"), + })} + /> + + ); + })} + + + ); + })} + + ); +}; + +export default ReferredCharts; diff --git a/src/components/dashboard/reports/refahi/LoanDetails/UniqDetailComponent.jsx b/src/components/dashboard/reports/refahi/LoanDetails/UniqDetailComponent.jsx new file mode 100644 index 0000000..aeb185e --- /dev/null +++ b/src/components/dashboard/reports/refahi/LoanDetails/UniqDetailComponent.jsx @@ -0,0 +1,51 @@ +import { Box, Grid, Stack, Typography } from "@mui/material"; +import RadialBarSemiCircularChart from "./RadialBarSemiCircularChart"; +import { useTranslations } from "next-intl"; + +const UniqDetailComponent = ({ item, percentage, title }) => { + const t = useTranslations(); + return ( + + + + {title} + + + {t("reports.dynamic_total_budget", { + total_budget: (item.total_budget / 1000000).toLocaleString("en"), + })} + + + 100 ? 100 : percentage)} + formatter={(val) => `${Math.round(percentage)}%`} + label={t("reports.dynamic_label_referred", { + count: item.count.toLocaleString("en"), + total_amount: (item.total_amount / 1000000).toLocaleString("en"), + })} + /> + + ); +}; +export default UniqDetailComponent; diff --git a/src/components/dashboard/reports/refahi/LoanDetails/index.jsx b/src/components/dashboard/reports/refahi/LoanDetails/index.jsx new file mode 100644 index 0000000..2ea305a --- /dev/null +++ b/src/components/dashboard/reports/refahi/LoanDetails/index.jsx @@ -0,0 +1,108 @@ +import { Divider, Grid, Paper, Stack, Typography } from "@mui/material"; +import { useTranslations } from "next-intl"; +import Filter from "../Filter"; +import useChart from "@/lib/app/hooks/useChart"; +import { + //GET_LOAN_EXPERTPROGRESS_CARTABLE_REFAHI , GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL_REFAHI, GET_LOAN_EXPERTPROGRESS_BANK_REPORT_REFAHI + GET_LOAN_EXPERTPROGRESS_BANK_REPORT, + GET_LOAN_EXPERTPROGRESS_CARTABLE, + GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL, +} from "@/core/data/apiRoutes"; +import LoadingHardPage from "@/core/components/LoadingHardPage"; +import AnalyticsIcon from "@mui/icons-material/Analytics"; +import FunctionalityCharts from "./FunctionalityCharts"; + +const LoanDetails = () => { + const t = useTranslations(); + + const { + errorReportList: errorReportList1, + isLoadingReportList: isLoadingReportList1, + reportList: reportList1, + setFilterOption: setFilterOption1, + mutate: mutate1, + } = useChart(GET_LOAN_EXPERTPROGRESS_CARTABLE); + const { + errorReportList: errorReportList2, + isLoadingReportList: isLoadingReportList2, + reportList: reportList2, + setFilterOption: setFilterOption2, + mutate: mutate2, + } = useChart(GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL); + const { + errorReportList: errorReportList3, + isLoadingReportList: isLoadingReportList3, + reportList: reportList3, + setFilterOption: setFilterOption3, + mutate: mutate3, + } = useChart(GET_LOAN_EXPERTPROGRESS_BANK_REPORT); + + return ( + + { + setFilterOption1(fields); + setFilterOption2(fields); + setFilterOption3(fields); + }} + isLoadingReportList={isLoadingReportList1 || isLoadingReportList3 || isLoadingReportList2} + mutate={() => { + mutate1(); + mutate2(); + mutate3(); + }} + /> + + {isLoadingReportList1 || isLoadingReportList2 || isLoadingReportList3 ? ( + + } + loading={isLoadingReportList1 || isLoadingReportList2 || isLoadingReportList3} + label={t("reports.loading_fetching_reports")} + width={100} + height={100} + sx={{ position: "absolute", bgcolor: "#f7f7f7e6" }} + /> + + ) : errorReportList1 || errorReportList2 || errorReportList3 ? ( + + + {t("reports.error_fetching_reports")} + + + ) : ( + + + + + + + + + + + + + + )} + + + ); +}; + +export default LoanDetails; diff --git a/src/components/dashboard/reports/refahi/index.jsx b/src/components/dashboard/reports/refahi/index.jsx new file mode 100644 index 0000000..87a22b9 --- /dev/null +++ b/src/components/dashboard/reports/refahi/index.jsx @@ -0,0 +1,26 @@ +import LoanDetails from "./LoanDetails"; +import ExcelExport from "./ExcelExport"; +import { GET_EXCEL_EXPORT, GET_EXCEL_EXPORT_status } from "@/core/data/apiRoutes"; +import { useTranslations } from "next-intl"; + +const DashboardReportsComponent = (props) => { + const t = useTranslations(); + + return ( + <> + + + + + ); +}; + +export default DashboardReportsComponent; diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index 17c57c4..2817059 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -161,15 +161,26 @@ export const GET_EXCEL_EXPORT = BASE_URL + "/dashboard/exports/navgan/expert_pro export const GET_EXCEL_EXPORT_status = BASE_URL + "/dashboard/exports/navgan/loans_state"; export const GET_PROVINCE_PROGRESS = BASE_URL + "/dashboard/reports/navgan/province_progress"; export const GET_LOAN_DISTRIBUTION = BASE_URL + "/dashboard/reports/navgan/loan_distribution"; -export const GET_LOAN_EXPERTPROGRESS = BASE_URL + "/dashboard/reports/navgan/expert_progress"; +export const GET_LOAN_EXPERTPROGRESS_CARTABLE = BASE_URL + "/dashboard/reports/navgan/cartable_reports"; +export const GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL = BASE_URL + "/dashboard/reports/navgan/planning_council_reports"; +export const GET_LOAN_EXPERTPROGRESS_BANK_REPORT = BASE_URL + "/dashboard/reports/navgan/bank_reports"; +export const GET_LOAN_EXPERTPROGRESS_CARTABLE_REFAHI = BASE_URL + "/dashboard/reports/refahi/cartable_reports"; +export const GET_LOAN_EXPERTPROGRESS_PLANING_COUNCIL_REFAHI = + BASE_URL + "/dashboard/reports/refahi/planning_council_reports"; +export const GET_LOAN_EXPERTPROGRESS_BANK_REPORT_REFAHI = BASE_URL + "/dashboard/reports/refahi/bank_reports"; export const GET_LOAN_REFERREDLOANS = BASE_URL + "/dashboard/reports/navgan/referred_loans"; // reports -//loan history +//loan history navgan export const GET_LOAN_HISTORY = BASE_URL + "/dashboard/navgan_loans"; export const GET_HISTORY_DETAIL = BASE_URL + "/dashboard/navgan_loans"; export const EXPORT_LOAN_HISTORY = BASE_URL + "/dashboard/navgan_loans/export"; +//loan history refahi +export const GET_LOAN_HISTORY_REFAHI = BASE_URL + "/dashboard/refahi_loans"; +export const GET_HISTORY_DETAIL_REFAHI = BASE_URL + "/dashboard/refahi_loans"; +export const EXPORT_LOAN_HISTORY_REFAHI = BASE_URL + "/dashboard/refahi_loans/export"; + //admin setting export const GET_ADMIN_SETTING = BASE_URL + "/dashboard/settings/show"; export const ADD_ADMIN_SETTING = BASE_URL + "/dashboard/settings/store"; @@ -225,3 +236,6 @@ export const GET_REFAHI_COMEBACK_LOAN_DETAIL = BASE_URL + "/dashboard/vezarat_re export const GET_REFAHI_BANK_PAYMENT = BASE_URL + "/dashboard/vezarat_refahi_loan_tracking/bank_payment_loan"; export const GET_REFAHI_APPROVED_BANK_LOAN = BASE_URL + "/dashboard/vezarat_refahi_loan_tracking/approved_loan"; //refahi loan follow up + +//refahi report +export const GET_LOAN_REFAHI_EXPERTPROGRESS = BASE_URL + "/dashboard/reports/navgan/expert_progress"; diff --git a/src/core/data/sidebarMenu.jsx b/src/core/data/sidebarMenu.jsx index 488638b..8a48ea8 100644 --- a/src/core/data/sidebarMenu.jsx +++ b/src/core/data/sidebarMenu.jsx @@ -4,7 +4,7 @@ import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; import DesktopWindowsIcon from "@mui/icons-material/DesktopWindows"; import GavelIcon from "@mui/icons-material/Gavel"; import BusinessCenterIcon from "@mui/icons-material/BusinessCenter"; -import PollIcon from '@mui/icons-material/Poll'; +import PollIcon from "@mui/icons-material/Poll"; import PaidIcon from "@mui/icons-material/Paid"; import ManageAccountsIcon from "@mui/icons-material/ManageAccounts"; import PersonIcon from "@mui/icons-material/Person"; @@ -15,7 +15,8 @@ import SettingsIcon from "@mui/icons-material/Settings"; import RepartitionIcon from "@mui/icons-material/Repartition"; import AccountBalanceIcon from "@mui/icons-material/AccountBalance"; import RepeatIcon from "@mui/icons-material/Repeat"; -import DisplaySettingsIcon from '@mui/icons-material/DisplaySettings'; +import DisplaySettingsIcon from "@mui/icons-material/DisplaySettings"; +import BarChartIcon from "@mui/icons-material/BarChart"; const sidebarMenu = [ [ @@ -27,15 +28,27 @@ const sidebarMenu = [ selected: false, permissions: ["all"], }, - { - key: "sidebar.reports", - name: "reports", - type: "page", - route: "/dashboard/reports", - icon: , - selected: false, - permissions: ["view_reports_navgan"], - }, + // TODO : should un-command this part after reports get fixed + // { + // key: "sidebar.reports", + // name: "reports", + // secondary: "secondary.reports", + // type: "page", + // route: "/dashboard/reports/navgan", + // icon: , + // selected: false, + // permissions: ["view_reports_navgan"], + // }, + // { + // key: "sidebar.reports-refahi", + // name: "reports-refahi", + // secondary: "secondary.reports-refahi", + // type: "page", + // route: "/dashboard/reports/refahi", + // icon: , + // selected: false, + // permissions: ["view_reports_refahi"], + // }, { key: "sidebar.loan-history", secondary: "secondary.loan-history", @@ -198,7 +211,7 @@ const sidebarMenu = [ route: "/dashboard/refahi/loan-followup", icon: , selected: false, - permissions: ["manage_vezarat_eghtesad_loans_refahi"], + permissions: ["manage_vezarat_eghtesad_loans"], }, { key: "sidebar.refahi-loan-management", diff --git a/src/pages/dashboard/refahi/loan-followup/index.jsx b/src/pages/dashboard/refahi/loan-followup/index.jsx index 7a1206a..73aa3f8 100644 --- a/src/pages/dashboard/refahi/loan-followup/index.jsx +++ b/src/pages/dashboard/refahi/loan-followup/index.jsx @@ -13,7 +13,7 @@ export async function getServerSideProps({ req, locale }) { title: "Dashboard.loan_followup", isBot, locale, - layout: { name: "DashboardLayout", props: { permissions: ["manage_vezarat_eghtesad_loans_refahi"] } }, + layout: { name: "DashboardLayout", props: { permissions: ["manage_vezarat_eghtesad_loans"] } }, }, }; } diff --git a/src/pages/dashboard/reports/index.jsx b/src/pages/dashboard/reports/navgan/index.jsx similarity index 97% rename from src/pages/dashboard/reports/index.jsx rename to src/pages/dashboard/reports/navgan/index.jsx index 088dc33..df380e0 100644 --- a/src/pages/dashboard/reports/index.jsx +++ b/src/pages/dashboard/reports/navgan/index.jsx @@ -1,4 +1,4 @@ -import DashboardReportsComponent from "@/components/dashboard/reports"; +import DashboardReportsComponent from "@/components/dashboard/reports/navgan"; import { parse } from "next-useragent"; export default function Reports() { diff --git a/src/pages/dashboard/reports/refahi/index.jsx b/src/pages/dashboard/reports/refahi/index.jsx new file mode 100644 index 0000000..baa68df --- /dev/null +++ b/src/pages/dashboard/reports/refahi/index.jsx @@ -0,0 +1,18 @@ +import DashboardReportsComponent from "@/components/dashboard/reports/refahi"; +import { parse } from "next-useragent"; + +export default function Reports() { + return ; +} + +export async function getServerSideProps({ req, locale }) { + const { isBot } = parse(req.headers["user-agent"]); + return { + props: { + messages: (await import(`&/locales/${locale}/app.json`)).default, + title: "Dashboard.reports", + isBot, + layout: { name: "DashboardLayout", props: { permissions: ["view_reports_refahi"] } }, + }, + }; +}