369 lines
11 KiB
JavaScript
369 lines
11 KiB
JavaScript
import {
|
||
Button,
|
||
Card,
|
||
IconButton,
|
||
List,
|
||
ListItemButton,
|
||
ListItemIcon,
|
||
ListItemText,
|
||
Popover,
|
||
Tooltip,
|
||
} from "@mui/material";
|
||
import { useContext, useEffect, useState } from "react";
|
||
import { useDispatch, useSelector } from "react-redux";
|
||
// import { slaughterGetCars } from "../../services/slaughter-get-cars";
|
||
// import { slaughterDeleteCar } from "../../services/slaughter-delete-car";
|
||
import { Grid } from "../../../../components/grid/Grid";
|
||
import { SPACING } from "../../../../data/spacing";
|
||
// import { SlaughterNewCar } from "../slaughter-new-car/SlaughterNewCar";
|
||
// import { ProvinceRegisterCar } from "../province-register-car/ProvinceRegisterCar";
|
||
import { provinceGetCars } from "../../services/province-get-cars";
|
||
import {
|
||
DRAWER,
|
||
LOADING_END,
|
||
LOADING_START,
|
||
} from "../../../../lib/redux/slices/appSlice";
|
||
import { ProvinceRegisterCarForm } from "../province-register-car-form/ProvinceRegisterCarForm";
|
||
import { provinceRemoveCar } from "../../services/province-remove-car";
|
||
import { AppContext } from "../../../../contexts/AppContext";
|
||
import { ProvinceAllocateCarsForm } from "../province-allocate-cars-form/ProvinceAllocateCarsForm";
|
||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||
import { ManageCarState } from "../manage-car-state/ManageCarState";
|
||
import axios from "axios";
|
||
import { RiFileExcel2Fill } from "react-icons/ri";
|
||
import TuneIcon from "@mui/icons-material/Tune";
|
||
import LocalShippingIcon from "@mui/icons-material/LocalShipping";
|
||
import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
|
||
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||
import { provinceCarsDashboardService } from "../../services/province-cars-dashboard";
|
||
|
||
export const ProvinceManageCars = () => {
|
||
const dispatch = useDispatch();
|
||
const [dataTable, setDataTable] = useState([]);
|
||
const [openNotif] = useContext(AppContext);
|
||
const { provinceCars } = useSelector((state) => state.provinceSlice);
|
||
// const userInfo = useSelector((state) => state.userSlice);
|
||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||
|
||
useEffect(() => {
|
||
dispatch(provinceGetCars());
|
||
}, []);
|
||
|
||
const [dashboardData, setDashboardData] = useState([]);
|
||
|
||
useEffect(() => {
|
||
dispatch(provinceCarsDashboardService()).then((r) => {
|
||
setDashboardData(r.payload.data);
|
||
});
|
||
}, [dispatch, provinceCars]);
|
||
|
||
useEffect(() => {
|
||
const d = provinceCars?.map((item, i) => {
|
||
let carIdentity = "-";
|
||
if (item.type === "rental") {
|
||
carIdentity = "اجاره ای";
|
||
} else if (item.type === "exclusive") {
|
||
carIdentity = "اختصاصی";
|
||
}
|
||
|
||
// const handleDisable =
|
||
// getRoleFromUrl() === "ProvinceOperator" ||
|
||
// getRoleFromUrl() === "SuperAdmin" ||
|
||
// getRoleFromUrl() === "AdminX"
|
||
// ? false
|
||
// : true;
|
||
|
||
const killhouseList =
|
||
item.type === "rental"
|
||
? "همه کشتارگاه ها/کشتارکن ها"
|
||
: item?.killHouseList?.map((killHouse, index) => {
|
||
const separator =
|
||
index + 1 === item.killHouseList.length ? "" : " - ";
|
||
return killHouse?.killHouseName + separator;
|
||
});
|
||
|
||
return [
|
||
i + 1,
|
||
item.typeCar,
|
||
carIdentity,
|
||
item.pelak,
|
||
item.capocity,
|
||
parseInt(item.healthCode),
|
||
// Number(item.healthCode),
|
||
item.driverName,
|
||
item.driverMobile,
|
||
killhouseList,
|
||
<ManageCarState key={item.key} item={item} />,
|
||
<CarActions
|
||
key={`car-action-${item.key}`}
|
||
item={item}
|
||
openNotif={openNotif}
|
||
/>,
|
||
];
|
||
});
|
||
|
||
setDataTable(d);
|
||
}, [provinceCars, dispatch, openNotif]);
|
||
|
||
const [tableDataCol] = useState([
|
||
"ردیف",
|
||
"مدل خودرو",
|
||
"ماهیت",
|
||
"پلاک",
|
||
"ظرفیت",
|
||
"کد بهداشتی",
|
||
"نام راننده",
|
||
"موبایل راننده",
|
||
"کشتارگاه ها/کشتارکن ها",
|
||
"وضعیت",
|
||
"عملیات",
|
||
]);
|
||
return (
|
||
<>
|
||
<Grid
|
||
container
|
||
alignItems="center"
|
||
justifyContent="space-between"
|
||
gap={SPACING.SMALL}
|
||
xs={12}
|
||
>
|
||
<Button
|
||
variant="contained"
|
||
onClick={() => {
|
||
dispatch(
|
||
DRAWER({
|
||
right: !(window.innerWidth <= 600),
|
||
bottom: window.innerWidth <= 600,
|
||
title: "افزودن خودرو",
|
||
content: <ProvinceRegisterCarForm />,
|
||
})
|
||
);
|
||
}}
|
||
>
|
||
افزودن خودرو
|
||
</Button>
|
||
<Tooltip title="خروجی اکسل">
|
||
<a
|
||
href={`${
|
||
axios.defaults.baseURL
|
||
}car_province_excel/?key=${userKey}&role=${getRoleFromUrl()}`}
|
||
rel="noreferrer"
|
||
>
|
||
<Button color="success">
|
||
<RiFileExcel2Fill size={32} />
|
||
</Button>
|
||
</a>
|
||
</Tooltip>
|
||
<Card sx={{ width: "100%" }}>
|
||
<Grid container mt={2} mb={4} isDashboard>
|
||
<ResponsiveTable
|
||
noPagination
|
||
isDashboard
|
||
columns={[
|
||
"تعداد خودرو ها",
|
||
"اختصاصی",
|
||
"اجاره ای",
|
||
"فعال",
|
||
"غیر فعال",
|
||
"معلق",
|
||
]}
|
||
data={[
|
||
[
|
||
dashboardData?.total?.toLocaleString(),
|
||
dashboardData?.exclusive?.toLocaleString(),
|
||
dashboardData?.rental?.toLocaleString(),
|
||
dashboardData?.active?.toLocaleString(),
|
||
dashboardData?.inactive?.toLocaleString(),
|
||
dashboardData?.suspended?.toLocaleString(),
|
||
],
|
||
]}
|
||
title={"خلاصه اطلاعات"}
|
||
/>
|
||
</Grid>
|
||
|
||
<ResponsiveTable
|
||
paginated
|
||
title="خودروها"
|
||
columns={tableDataCol}
|
||
data={dataTable}
|
||
/>
|
||
</Card>
|
||
</Grid>
|
||
</>
|
||
);
|
||
};
|
||
|
||
const CarActions = ({ item, openNotif }) => {
|
||
const dispatch = useDispatch();
|
||
const [anchorEl, setAnchorEl] = useState(null);
|
||
|
||
const handleDisable = !(
|
||
getRoleFromUrl() === "ProvinceOperator" ||
|
||
getRoleFromUrl() === "SuperAdmin" ||
|
||
getRoleFromUrl() === "AdminX"
|
||
);
|
||
|
||
const hasForbiddenKillhouse = item.killHouseList?.some(
|
||
(killItem) => !killItem.allowState
|
||
);
|
||
|
||
const hasAccess = !handleDisable || !hasForbiddenKillhouse;
|
||
const isRental = item.type === "rental";
|
||
|
||
const open = Boolean(anchorEl);
|
||
const id = open ? `province-cars-popover-${item.key}` : undefined;
|
||
|
||
const closePopover = () => setAnchorEl(null);
|
||
|
||
const handleAllocate = () => {
|
||
closePopover();
|
||
dispatch(
|
||
DRAWER({
|
||
right: !(window.innerWidth <= 600),
|
||
bottom: window.innerWidth <= 600,
|
||
title: "تخصیص/حذف کشتارگاه",
|
||
content: (
|
||
<ProvinceAllocateCarsForm
|
||
driverKey={item.key}
|
||
killHouseList={item.killHouseList}
|
||
/>
|
||
),
|
||
})
|
||
);
|
||
};
|
||
|
||
const handleEdit = () => {
|
||
closePopover();
|
||
dispatch(
|
||
DRAWER({
|
||
right: !(window.innerWidth <= 600),
|
||
bottom: window.innerWidth <= 600,
|
||
title: "ویرایش خودرو",
|
||
content: (
|
||
<ProvinceRegisterCarForm
|
||
first_name={item.firstName}
|
||
pelak={item.pelak}
|
||
city_name={item.city}
|
||
type_car={item.typeCar}
|
||
last_name={item.lastName}
|
||
capocity={item.capocity}
|
||
health_code={item.healthCode}
|
||
driver_mobile={item.driverMobile}
|
||
driverKey={item?.key}
|
||
type={item?.type}
|
||
/>
|
||
),
|
||
})
|
||
);
|
||
};
|
||
|
||
const handleDelete = () => {
|
||
closePopover();
|
||
dispatch(LOADING_START());
|
||
dispatch(provinceRemoveCar(item.key)).then((r) => {
|
||
if (r.error) {
|
||
if (r.error.message.includes("403")) {
|
||
openNotif({
|
||
vertical: "top",
|
||
horizontal: "center",
|
||
msg: "امکان حذف بدلیل تخصیص بار فعال به خودرو وجود ندارد!",
|
||
severity: "error",
|
||
});
|
||
} else {
|
||
openNotif({
|
||
vertical: "top",
|
||
horizontal: "center",
|
||
msg: "مشکلی پیش آمده است!",
|
||
severity: "error",
|
||
});
|
||
}
|
||
} else {
|
||
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
||
dispatch(provinceGetCars());
|
||
openNotif({
|
||
vertical: "top",
|
||
horizontal: "center",
|
||
msg: "عملیات با موفقیت انجام شد.",
|
||
severity: "success",
|
||
});
|
||
}
|
||
dispatch(LOADING_END());
|
||
});
|
||
};
|
||
|
||
const actionsDisabled = !hasAccess || (handleDisable && isRental);
|
||
|
||
return (
|
||
<div>
|
||
<IconButton
|
||
aria-describedby={id}
|
||
color="primary"
|
||
size="small"
|
||
onClick={(event) => setAnchorEl(event.currentTarget)}
|
||
disabled={!hasAccess}
|
||
>
|
||
<TuneIcon />
|
||
</IconButton>
|
||
<Popover
|
||
id={id}
|
||
anchorEl={anchorEl}
|
||
open={open}
|
||
onClose={closePopover}
|
||
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
|
||
transformOrigin={{ vertical: "top", horizontal: "left" }}
|
||
disableRestoreFocus
|
||
PaperProps={{ sx: { p: 2 } }}
|
||
>
|
||
<List sx={{ py: 0 }}>
|
||
<ListItemButton onClick={handleAllocate} disabled={actionsDisabled}>
|
||
<ListItemIcon>
|
||
<LocalShippingIcon
|
||
fontSize="small"
|
||
color={actionsDisabled ? "disabled" : "primary"}
|
||
/>
|
||
</ListItemIcon>
|
||
<ListItemText
|
||
primary="تخصیص به کشتارگاه"
|
||
primaryTypographyProps={{
|
||
variant: "body2",
|
||
color: actionsDisabled ? "text.secondary" : "primary",
|
||
}}
|
||
/>
|
||
</ListItemButton>
|
||
<ListItemButton onClick={handleEdit} disabled={actionsDisabled}>
|
||
<ListItemIcon>
|
||
<EditOutlinedIcon
|
||
fontSize="small"
|
||
color={actionsDisabled ? "disabled" : "primary"}
|
||
/>
|
||
</ListItemIcon>
|
||
<ListItemText
|
||
primary="ویرایش"
|
||
primaryTypographyProps={{
|
||
variant: "body2",
|
||
color: actionsDisabled ? "text.secondary" : "primary",
|
||
}}
|
||
/>
|
||
</ListItemButton>
|
||
<ListItemButton onClick={handleDelete} disabled={actionsDisabled}>
|
||
<ListItemIcon>
|
||
<DeleteOutlineIcon
|
||
fontSize="small"
|
||
color={actionsDisabled ? "disabled" : "error"}
|
||
/>
|
||
</ListItemIcon>
|
||
<ListItemText
|
||
primary="حذف"
|
||
primaryTypographyProps={{
|
||
variant: "body2",
|
||
color: actionsDisabled ? "text.secondary" : "error",
|
||
}}
|
||
/>
|
||
</ListItemButton>
|
||
</List>
|
||
</Popover>
|
||
</div>
|
||
);
|
||
};
|