Merge branch 'feature/yasi_reserve_loan' into 'develop'

add reserve_loan

See merge request witel-front-end/loan-facilities/expert!151
This commit is contained in:
AmirHossein Mahmoodi
2024-02-07 13:49:56 +00:00
10 changed files with 568 additions and 2 deletions

View File

@@ -63,7 +63,8 @@
"role-management": "مدیریت نقش ها",
"edit-profile": "ویرایش پروفایل",
"loan-history": "کارتابل نظارت",
"loan-history-province": "کارتابل نظارت استانی"
"loan-history-province": "کارتابل نظارت استانی",
"reserve-loan" : "وام های رزرو"
},
"secondary": {
"passenger-office": "توزیع درخواست",
@@ -117,6 +118,7 @@
"passenger_office_page": "اداره مسافر",
"loan_management_page": "مدیریت وام",
"machinary_office_page": "کارتابل کارشناسی",
"reserve_loans": "وام های رزرو",
"development_assistant_page": "معاون توسعه",
"inspector_expert_page": "بازدید کارشناس",
"commercial_chief_page": "رئیس اداره بازرگانی",
@@ -413,7 +415,19 @@
"upload_file_format": "فرمت قابل قبول : png,jpg,pdf",
"print_report": "چاپ گزارش کارشناسی",
"max_amount": "حداکثر مبلغ پیشنهادی {value} میلیون ریال می باشد",
"excel_report": "گزارش اکسل"
"excel_report": "گزارش اکسل",
"reserve-loan-title" : "رزرو وام",
"description-reserve-loan-first": "آیا از رزرو وام به کد یکتا",
"description-reserve-loan-second": "اطمینان دارید؟",
"button-reserve-cancel": "بستن",
"button-reserve-confirm": "رزرو"
},
"ReserveLoan": {
"title": "لغو رزرو",
"description-loan-first": "آیا از لغو رزرو وام به کد یکتا",
"description-loan-second": "اطمینان دارید؟",
"button-cancel": "بستن",
"button-confirm": "لغو رزرو"
},
"BankManagement": {
"name": "نام",

View File

@@ -0,0 +1,75 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip, Typography
} from "@mui/material";
import {useTranslations} from "next-intl";
import {useState} from "react";
import RepartitionIcon from '@mui/icons-material/Repartition';
import useRequest from "@/lib/app/hooks/useRequest";
import useNotification from "@/lib/app/hooks/useNotification";
import {RESERVE_MACHINARY_LOAN} from "@/core/data/apiRoutes";
const ReserveForm = ({rowId, mutate}) => {
const t = useTranslations();
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
const requestServer = useRequest({auth: true, notification: false});
const [isSubmitting, setIsSubmitting] = useState(false);
const {update_notification} = useNotification()
const handleSubmit = () => {
setIsSubmitting(true)
requestServer(`${RESERVE_MACHINARY_LOAN}/${rowId}`, 'post').then((response) => {
setOpenConfirmDialog(false)
mutate()
update_notification()
}).catch(() => {
}).finally(() => {
setIsSubmitting(false)
});
}
return (
<>
<Tooltip title={t("MachinaryOffice.button-reserve-confirm")}>
<IconButton
color="primary"
onClick={() => {
setOpenConfirmDialog(true)
}}
>
<RepartitionIcon/>
</IconButton>
</Tooltip>
<Dialog
open={openConfirmDialog}
PaperProps={{
sx: {
transition: 'all .3s',
boxShadow: 'rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px'
}
}}
maxWidth="sm"
>
<DialogTitle>
{t("MachinaryOffice.reserve-loan-title")}
</DialogTitle>
<DialogContent>
<Typography> {t("MachinaryOffice.description-reserve-loan-first")} {rowId} {t("MachinaryOffice.description-reserve-loan-second")}</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenConfirmDialog(false)} variant="outlined" color="secondary" disabled={isSubmitting}>{t("MachinaryOffice.button-reserve-cancel")}</Button>
<Button onClick={() => handleSubmit()} variant="contained" color="primary" disabled={isSubmitting}>
{t("MachinaryOffice.button-reserve-confirm")}
</Button>
</DialogActions>
</Dialog>
</>
)
}
export default ReserveForm;

View File

@@ -1,6 +1,7 @@
import {Box} from "@mui/material";
import Confirm from "./Form/ConfirmForm";
import Reject from "./Form/RejectForm";
import ReserveForm from "@/components/dashboard/machinary-office/Form/ReserveForm";
const TableRow = ({row, mutate}) => {
return (
@@ -10,6 +11,10 @@ const TableRow = ({row, mutate}) => {
vehicle_type={row.original.vehicle_type}
mutate={mutate}
/>
<ReserveForm
rowId={row.getValue("id")}
mutate={mutate}
/>
<Reject
rowId={row.getValue("id")}
mutate={mutate}

View File

@@ -0,0 +1,73 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip, Typography
} from "@mui/material";
import {useTranslations} from "next-intl";
import {useState} from "react";
import KeyboardReturnSharpIcon from '@mui/icons-material/KeyboardReturnSharp';
import useRequest from "@/lib/app/hooks/useRequest";
import {CANSEL_RESERVE_MACHINARY_LOAN} from "@/core/data/apiRoutes";
const CanselReserve = ({rowId, mutate}) => {
const t = useTranslations();
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
const requestServer = useRequest({auth: true, notification: false});
const [isSubmitting, setIsSubmitting] = useState(false)
const handleSubmit = () => {
setIsSubmitting(true)
requestServer(`${CANSEL_RESERVE_MACHINARY_LOAN}/${rowId}`, 'get').then((response) => {
setOpenConfirmDialog(false)
mutate()
update_notification()
}).catch(() => {
}).finally(() => {
setIsSubmitting(false)
});
}
return (
<>
<Tooltip title={t("ReserveLoan.button-confirm")}>
<IconButton
color="primary"
onClick={() => {
setOpenConfirmDialog(true)
}}
>
<KeyboardReturnSharpIcon/>
</IconButton>
</Tooltip>
<Dialog
open={openConfirmDialog}
PaperProps={{
sx: {
transition: 'all .3s',
boxShadow: 'rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px'
}
}}
maxWidth="sm"
>
<DialogTitle>
{t("ReserveLoan.title")}
</DialogTitle>
<DialogContent>
<Typography>{t("ReserveLoan.description-loan-first")} {rowId} {t("ReserveLoan.description-loan-second")}</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenConfirmDialog(false)} variant="outlined" color="secondary" disabled={isSubmitting}>{t("ReserveLoan.button-cancel")}</Button>
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
{t("ReserveLoan.button-confirm")}
</Button>
</DialogActions>
</Dialog>
</>
)
}
export default CanselReserve;

View File

@@ -0,0 +1,15 @@
import {Box} from "@mui/material";
import CanselReserve from "./Form/CanselReserve";
const TableRow = ({row, mutate}) => {
return (
<Box sx={{display: "flex", flexWrap: "nowrap", gap: "8px"}}>
{/*<CanselReserve*/}
{/* rowId={row.getValue("id")}*/}
{/* mutate={mutate}*/}
{/*/>*/}
</Box>
);
};
export default TableRow;

View File

@@ -0,0 +1,12 @@
import {Stack} from "@mui/material";
const TableToolbar = ({table}) => {
return (
<Stack direction={"row"} spacing={2}>
</Stack>
)
}
export default TableToolbar

View File

@@ -0,0 +1,331 @@
import {Box, Stack, Typography} from "@mui/material";
import {useMemo} from "react";
import {GET_RESERVE_MACHINARY_LOAN} 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 "@/components/dashboard/reserve-loan/TableToolbar";
function DashboardReserveLoan() {
const t = useTranslations();
const columns = useMemo(
() => [
{
accessorFn: (row) => row.id,
id: "id",
header: t("MachinaryOffice.id"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.score,
id: "score",
header: t("MachinaryOffice.score"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.is_legal_person,
id: "is_legal_person",
header: t("MachinaryOffice.is_legal_person"),
enableColumnFilter: false,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: ["equals"],
Cell: ({renderedCellValue}) => (
<Typography
variant="body2">{renderedCellValue === 1 ? `${t("MachinaryOffice.hoghoghi")}` : `${t("MachinaryOffice.haghighi")}`}</Typography>
),
},
{
accessorFn: (row) => row.navgan_id,
id: "navgan_id",
header: t("MachinaryOffice.navgan_id"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.name,
id: "name",
header: t("MachinaryOffice.name"),
enableColumnFilter: true,
datatype: "text",
filterFn: "contains",
columnFilterModeOptions: ["contains", "equals", "notEquals"],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.national_id,
id: "national_id",
header: t("MachinaryOffice.national_id"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.shenase_meli,
id: "shenase_meli",
header: t("MachinaryOffice.shenase_meli"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.province_name,
id: "province_name",
header: t("MachinaryOffice.province_name"),
enableColumnFilter: true,
datatype: "text",
filterFn: "contains",
columnFilterModeOptions: ["contains", "equals", "notEquals"],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.city_name,
id: "city_name",
header: t("MachinaryOffice.city_name"),
enableColumnFilter: true,
datatype: "text",
filterFn: "contains",
columnFilterModeOptions: ["contains", "equals", "notEquals"],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) =>
moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"),
id: "created_at",
header: t("MachinaryOffice.created_at"),
enableColumnFilter: true,
datatype: "date",
filterFn: "lessThan",
columnFilterModeOptions: ["lessThan", "greaterThan"],
Cell: ({renderedCellValue}) => {
return <Typography variant="body2">{renderedCellValue}</Typography>;
},
Header: ({column}) => <>{column.columnDef.header}</>,
Filter: ({column}) => {
return (
<MuiDatePicker column={column}/>
);
},
},
{
accessorFn: (row) => row.phone_number,
id: "phone_number",
header: t("MachinaryOffice.phone_number"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.statement_count,
id: "statement_count",
header: t("MachinaryOffice.statement_count"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.navgan_capacity,
id: "navgan_capacity",
header: t("MachinaryOffice.navgan_capacity"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.manufacture_date,
id: "manufacture_date",
header: t("MachinaryOffice.manufacture_date"),
enableColumnFilter: true,
datatype: "numeric",
filterFn: "equals",
columnFilterModeOptions: [
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"between",
],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.vehicle_type,
id: "vehicle_type",
header: t("MachinaryOffice.vehicle_type"),
enableColumnFilter: true,
datatype: "text",
filterFn: "contains",
columnFilterModeOptions: ["contains", "equals", "notEquals"],
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
{
accessorFn: (row) => row.plate_number,
id: "plate_number",
header: t("MachinaryOffice.plate_number"),
enableColumnFilter: false,
datatype: "text",
filterFn: "contains",
columnFilterModeOptions: ["contains", "equals", "notEquals"],
Cell: ({renderedCellValue}) => (
<Stack sx={{border: 1, borderColor: "divider", borderRadius: 1}} direction={'row'}>
<Stack sx={{borderRight: 1, borderColor: "divider", textAlign: 'center', width: "40%"}}>
{renderedCellValue.split('-')[3]}
</Stack>
<Stack direction={'row'} sx={{width: "100%", px: 0.5}}>
<Stack sx={{
textAlign: "center",
width: "100%"
}}>{renderedCellValue.split('-')[2]}</Stack>
<Stack sx={{
textAlign: "center",
width: "100%"
}}>{renderedCellValue.split('-')[1]}</Stack>
<Stack sx={{
textAlign: "center",
width: "100%"
}}>{renderedCellValue.split('-')[0]}</Stack>
</Stack>
</Stack>
),
},
{
accessorFn: (row) => row.state_name,
id: "state_id",
header: t("MachinaryOffice.state_name"),
enableColumnFilter: false,
datatype: "numeric",
Cell: ({renderedCellValue}) => (
<Typography variant="body2">{renderedCellValue}</Typography>
),
},
],
[]
);
return (
<Box sx={{px: 3}}>
<DataTable
tableUrl={GET_RESERVE_MACHINARY_LOAN}
columns={columns}
selectableRow={false}
enableCustomToolbar={true}
CustomToolbar={TableToolbar}
enableLastUpdate={true}
sorting={[{
id: 'score', desc: false
}]}
enablePinning={true}
enableDensityToggle={false}
initialState={{density: 'compact'}} //compact (small) //comfortable (medium) //spacious (large)
enableColumnFilters={true}
enableHiding={true}
enableFullScreenToggle={false}
enableGlobalFilter={false}
enableColumnResizing={false} // if you want true this you shold change renderRowActions props ** see https://www.material-react-table.com/docs/guides/row-actions
enableRowActions={true}
TableRowAction={TableRowActions}
/>
</Box>
);
}
export default DashboardReserveLoan;

View File

@@ -73,6 +73,15 @@ export const REJECT_MACHINARY_OFFICE =
BASE_URL + "/dashboard/machinery_expert/reject";
export const EXPORT_MACHINARY_OFFICE =
BASE_URL + "/dashboard/machinery_expert/export";
export const GET_RESERVE_MACHINARY_LOAN =
BASE_URL + "/dashboard/machinery_expert/reserved/show";
export const RESERVE_MACHINARY_LOAN =
BASE_URL + "/dashboard/machinery_expert/reserve";
export const CANSEL_RESERVE_MACHINARY_LOAN =
BASE_URL + "/dashboard/machinery_expert/unreserved";
//machinary office
//commercial chief

View File

@@ -16,6 +16,7 @@ import AccessibilityIcon from '@mui/icons-material/Accessibility';
import AssessmentIcon from '@mui/icons-material/Assessment';
import SecurityIcon from '@mui/icons-material/Security';
import SettingsIcon from '@mui/icons-material/Settings';
import RepartitionIcon from '@mui/icons-material/Repartition';
import AccountBalanceIcon from '@mui/icons-material/AccountBalance';
const sidebarMenu = [
@@ -67,6 +68,16 @@ const sidebarMenu = [
selected: false,
permissions: ["manage_machinery_navgan"],
},
{
key: "sidebar.reserve-loan",
secondary: "secondary.navgan-province-manager",
name: "reserve_loan",
type: "page",
route: "/dashboard/reserve-loan",
icon: <RepartitionIcon sx={{width: 'inherit', height: 'inherit'}}/>,
selected: false,
permissions: ["manage_machinery_navgan"],
},
{
key: "sidebar.passenger-boss",
secondary: "secondary.navgan-province-manager",

View File

@@ -0,0 +1,21 @@
import {parse} from "next-useragent";
import DashboardReserveLoan from "@/components/dashboard/reserve-loan";
export default function PassengerOffice() {
return (
<DashboardReserveLoan/>
);
}
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.reserve_loans",
isBot,
locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_machinery_navgan"]}}
},
};
}