diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js b/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js index 67311d9..ac976b1 100644 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js +++ b/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js @@ -3,7 +3,7 @@ import WithPermission from "@/core/middlewares/withPermission"; export default function page() { return ( - + ); diff --git a/src/components/dashboard/damages/report/Search/SelectProvince.jsx b/src/components/dashboard/damages/report/Search/SelectProvince.jsx index 7f738bc..89395f0 100644 --- a/src/components/dashboard/damages/report/Search/SelectProvince.jsx +++ b/src/components/dashboard/damages/report/Search/SelectProvince.jsx @@ -1,8 +1,6 @@ -import { Controller } from "react-hook-form"; -import MuiDatePicker from "@/core/components/MuiDatePicker"; -import React from "react"; -import { FormControl, FormHelperText, InputLabel, LinearProgress, MenuItem, Select, Typography } from "@mui/material"; import useProvinces from "@/lib/hooks/useProvince"; +import { FormControl, FormHelperText, InputLabel, MenuItem, Select } from "@mui/material"; +import { Controller } from "react-hook-form"; const SelectProvince = ({ control }) => { const { provinces, loadingProvinces, errorProvinces } = useProvinces(); diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/CityContent.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/CityContent.jsx new file mode 100644 index 0000000..8a64a72 --- /dev/null +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/CityContent.jsx @@ -0,0 +1,33 @@ +import SelectBox from "@/core/components/SelectBox"; +import useEdaratLists from "@/lib/hooks/useEdaratLists"; +import { useEffect, useState } from "react"; + +const CityContent = ({ provinceID, field, fieldState: { error } }) => { + const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists(provinceID); + const [prevDependency, setPrevDependency] = useState(provinceID); + + useEffect(() => { + if (prevDependency === provinceID) return; + field.onChange(null); + setPrevDependency(provinceID); + }, [provinceID]); + + return ( + + ); +}; +export default CityContent; diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/CityController.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/CityController.jsx new file mode 100644 index 0000000..cd9bc1c --- /dev/null +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/CityController.jsx @@ -0,0 +1,14 @@ +import { Controller, useWatch } from "react-hook-form"; +import CityContent from "./CityContent"; + +const CityController = ({ control }) => { + const provinceID = useWatch({ control, name: "provinceId" }); + return ( + } + /> + ); +}; +export default CityController; diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx index ff8be50..6e08101 100644 --- a/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx @@ -3,11 +3,23 @@ import StyledForm from "@/core/components/StyledForm"; import validateNationalCode from "@/core/utils/nationalCodeValidation"; import { yupResolver } from "@hookform/resolvers/yup"; import { Beenhere, ExitToApp } from "@mui/icons-material"; -import { Button, DialogActions, DialogContent, Grid, Stack, TextField } from "@mui/material"; +import { + Button, + DialogActions, + DialogContent, + Grid, + Stack, + TextField, + ToggleButton, + ToggleButtonGroup, +} from "@mui/material"; import { Controller, useForm } from "react-hook-form"; -import { object, string } from "yup"; +import { number, object, string } from "yup"; +import LogesticController from "./LogesticController"; const validationSchema = object({ + provinceId: number().required("لطفا استان را وارد کنید!!!"), + edarehShahriId: number().required("لطفا اداره را وارد کنید!!!"), name: string().required("وارد کردن نام و نام خانوادگی الزامیست!"), code: string() .required("لطفا کد ملی را وارد کنید!!!") @@ -37,6 +49,32 @@ const CreateFormContent = ({ setOpen, defaultValues, onSubmitBase }) => { + + ( + { + if (newAlignment !== null) { + field.onChange(newAlignment); + } + }} + > + + راهدار + + + راننده + + + )} + /> + + diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/LogesticController.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/LogesticController.jsx new file mode 100644 index 0000000..c05aab3 --- /dev/null +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/LogesticController.jsx @@ -0,0 +1,42 @@ +import { Grid, Stack } from "@mui/material"; +import CityController from "./CityController"; +import useProvinces from "@/lib/hooks/useProvince"; +import { Controller, useWatch } from "react-hook-form"; +import SelectBox from "@/core/components/SelectBox"; + +const LogesticController = ({ control }) => { + const { provinces, errorProvinces, loadingProvinces } = useProvinces(); + const isProvince = useWatch({ control, name: "isProvince" }); + return ( + <> + {!isProvince ? ( + + { + return ( + + ); + }} + /> + + ) : null} + + + + + ); +}; +export default LogesticController; diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx index fbc264f..79ef047 100644 --- a/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx @@ -1,19 +1,32 @@ -import { Dialog, DialogTitle, IconButton } from "@mui/material"; -import CreateFormContent from "./CreateFormContent"; -import CloseIcon from "@mui/icons-material/Close"; -import useRequest from "@/lib/hooks/useRequest"; import { CREATE_RAHDARAN_ITEM } from "@/core/utils/routes"; +import { useAuth } from "@/lib/contexts/auth"; +import { usePermissions } from "@/lib/hooks/usePermissions"; +import useRequest from "@/lib/hooks/useRequest"; +import CloseIcon from "@mui/icons-material/Close"; +import { Dialog, DialogTitle, IconButton } from "@mui/material"; import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog"; +import CreateFormContent from "./CreateFormContent"; const CreateForm = ({ open, setOpen, mutate }) => { const requestServer = useRequest({ notificationSuccess: true }); + const { data: userPermissions } = usePermissions(); + const { user } = useAuth(); + const hasCountryPermission = userPermissions?.includes("manage-rahdaran-country"); + const defaultValues = { + isDriver: "0", + isProvince: !hasCountryPermission, + provinceId: !hasCountryPermission ? user.province_id : "", + edarehShahriId: "", name: "", code: "", phone_number: "", }; const onSubmit = async (result) => { const formData = new FormData(); + formData.append("is_driver", result.isDriver); + formData.append("province_id", result.provinceId); + formData.append("edareh_shahri_id", result.edarehShahriId); formData.append("name", result.name); formData.append("code", result.code); formData.append("mobile", result.phone_number); diff --git a/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx b/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx index 6fc5d76..8d6903e 100644 --- a/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx +++ b/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx @@ -8,12 +8,18 @@ const EditController = ({ rowId, mutate, setOpen, row }) => { const requestServer = useRequest({ notificationSuccess: true }); const defaultData = { + isDriver: `${row.original?.is_driver}` || "0", + provinceId: row.original?.province_id || "", + edarehShahriId: row.original?.edareh_shahri_id || "", name: row.original?.name || "", code: row.original?.code || "", phone_number: row.original?.mobile || "", }; const handleSubmit = async (result) => { const formData = new FormData(); + formData.append("is_driver", result.isDriver); + formData.append("province_id", result.provinceId); + formData.append("edareh_shahri_id", result.edarehShahriId); formData.append("name", result.name); formData.append("code", result.code); formData.append("mobile", result.phone_number); diff --git a/src/components/dashboard/rahdaran/RahdaranList.jsx b/src/components/dashboard/rahdaran/RahdaranList.jsx index 7fe1ffb..ad24f23 100644 --- a/src/components/dashboard/rahdaran/RahdaranList.jsx +++ b/src/components/dashboard/rahdaran/RahdaranList.jsx @@ -2,13 +2,57 @@ import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import { GET_RAHDARAN_TABLE_LIST } from "@/core/utils/routes"; import { Box } from "@mui/material"; -import { useMemo } from "react"; +import { useEffect, useMemo, useState } from "react"; import RowActions from "./RowActions"; import Toolbar from "./Toolbar"; +import { useAuth } from "@/lib/contexts/auth"; +import useProvinces from "@/lib/hooks/useProvince"; +import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency"; +import useEdaratLists from "@/lib/hooks/useEdaratLists"; +import { usePermissions } from "@/lib/hooks/usePermissions"; const RahdaranList = () => { - const columns = useMemo( - () => [ + const { data: userPermissions } = usePermissions(); + const { user } = useAuth(); + const hasCountryPermission = userPermissions?.includes("manage-rahdaran-country"); + const columns = useMemo(() => { + const provinceColumn = { + accessorKey: "province_id", + header: "استان", + id: "province_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 130, + ColumnSelectComponent: (props) => { + const { provinces, errorProvinces, loadingProvinces } = useProvinces(); + const getColumnSelectOptions = useMemo(() => { + if (loadingProvinces) { + return [{ value: "loading", label: "در حال بارگذاری..." }]; + } + if (errorProvinces) { + return [{ value: "error", label: "خطا در بارگذاری" }]; + } + return [ + { value: "", label: "کل کشور" }, + ...provinces.map((province) => ({ + value: province.id, + label: province.name_fa, + })), + ]; + }, [provinces, errorProvinces, loadingProvinces]); + return ( + + ); + }, + Cell: ({ row }) => <>{row.original.province_name}, + }; + return [ { accessorKey: "id", header: "کد یکتا", @@ -21,6 +65,64 @@ const RahdaranList = () => { grow: false, size: 100, }, + ...(hasCountryPermission ? [provinceColumn] : []), + { + header: "اداره", + id: "edareh_shahri_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + dependencyId: hasCountryPermission ? "province_id" : null, + grow: false, + size: 120, + ColumnSelectComponent: (props) => { + const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists( + hasCountryPermission ? props.dependencyFieldValue.value : user.province_id + ); + const [prevDependency, setPrevDependency] = useState( + hasCountryPermission ? props.dependencyFieldValue.value : user.province_id + ); + + const getColumnSelectOptions = useMemo(() => { + if (hasCountryPermission && props.dependencyFieldValue.value === "") { + return [{ value: "empty", label: "ابتدا استان را انتخاب کنید" }]; + } + if (loadingEdaratList) { + return [{ value: "loading", label: "در حال بارگذاری..." }]; + } + if (errorEdaratList) { + return [{ value: "error", label: "خطا در بارگذاری" }]; + } + return [ + { value: "", label: "کل ادارات" }, + ...edaratList.map((edare) => ({ + value: edare.id, + label: edare.name_fa, + })), + ]; + }, [edaratList, loadingEdaratList, errorEdaratList]); + useEffect(() => { + if (hasCountryPermission) return; + if (prevDependency === props.dependencyFieldValue?.value) return; + props.handleChange({ ...props.filterParameters, value: "" }); + setPrevDependency(props.dependencyFieldValue?.value); + }, [props.dependencyFieldValue?.value, hasCountryPermission]); + return ( + + ); + }, + Cell: ({ renderedCellValue, row }) => <>{row.original.edareh_shahri_name}, + }, { accessorKey: "name", header: "نام و نام خانوادگی", @@ -54,9 +156,8 @@ const RahdaranList = () => { grow: false, size: 100, }, - ], - [] - ); + ]; + }, []); return ( <> diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx index e06d06b..f5d4395 100644 --- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx +++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx @@ -12,6 +12,7 @@ import { missionTypes } from "@/core/utils/missionTypes"; import moment from "jalali-moment"; import MachinesDialog from "./MachinesDialog"; import DriversDialog from "./DriversDialog"; +import LtrTextField from "@/core/components/LtrTextField"; const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => { const bound = useMemo( () => @@ -21,14 +22,16 @@ const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => { const requestServer = useRequest({ notificationSuccess: true }); const [machine, setMachine] = useState(); const [driver, setDriver] = useState(); + const [kilometer, setKilometer] = useState(); const [isSubmitting, setIsSubmitting] = useState(false); - const handleSubmit = async (_machine, _driver) => { + const handleSubmit = async (_machine, _driver, _kilometer) => { setIsSubmitting(true); await requestServer(`${ALLOCATE_REQUEST_MISSION}/${row.id}`, "post", { data: { machines: [_machine.id], driver: _driver.id, + km: kilometer, }, hasSidebarUpdate: true, }) @@ -107,6 +110,23 @@ const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => { )} )} + {driver && ( + + { + if (isNaN(Number(e.target.value))) return; + setKilometer(e.target.value); + }} + size="small" + fullWidth + label="کیلومتر خودرو" + InputLabelProps={{ shrink: true }} + /> + + )} @@ -188,10 +208,10 @@ const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => {