diff --git a/src/assets/scss/leaflet-measure.scss b/src/assets/scss/leaflet-measure.scss new file mode 100644 index 0000000..97e3bc1 --- /dev/null +++ b/src/assets/scss/leaflet-measure.scss @@ -0,0 +1,170 @@ +// leaflet-measure.scss + +$color-divider: #ddd; +$color-button: #5e66cc; +$color-lightertext: #999; + +$spacing-external: 12px; +$spacing-internal: 10px; + +$max-width: 280px; + +$button-icon-size: 12px; +$button-icon-spacing: 4px; + +@mixin hoverbutton { + color: $color-button; + text-decoration: none; + &:hover { + opacity: 0.5; + text-decoration: none; + } +} + +@mixin button ($icon) { + display: inline; + width: auto; + height: auto; + padding-left: 20px; + margin-right: $button-icon-spacing; + line-height: 1em; + border: 0; + text-align: left; + color: $color-button; + &, + &:hover { + background-color: transparent; + } + background: { + image: url('assets/#{ $icon }.png'); + repeat: no-repeat; + position: 0% 50%; + size: $button-icon-size $button-icon-size; + } + .leaflet-retina & { + background-image: url('assets/#{ $icon }_@2X.png'); + } + + @include hoverbutton; +} + +.leaflet-control-measure, +.leaflet-measure-resultpopup { + h3 { + margin: 0 0 $spacing-external 0; + padding-bottom: $spacing-internal; + border-bottom: solid 1px $color-divider; + } + p { + margin: $spacing-internal 0 0 0; + line-height: 1.5em; + &:first-child { + margin-top: 0; + } + } + .tasks { + margin: $spacing-external 0 0 0; + padding: $spacing-internal 0 0 0; + border-top: solid 1px $color-divider; + text-align: right; + + list-style: none; + list-style-image: none; + + li { + display: inline; + margin: 0 $spacing-internal 0 0; + &:last-child { + margin-right: 0; + } + } + } + + .coorddivider { + color: $color-lightertext; + } +} + +.leaflet-control-measure { + max-width: $max-width; + background: #fff; + + .leaflet-control-measure-toggle, + .leaflet-control-measure-toggle:hover { + background: { + size: 14px 14px; + image: url(assets/rulers.png); + } + border: 0; + border-radius: 4px; + .leaflet-touch & { + border-radius: 2px; + } + + // Hide text + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + + .leaflet-retina & { + background-image: url(assets/rulers_@2X.png); + } + + .leaflet-touch & { + background-size: 16px 16px; + } + } + + // Special styling because start prompt has no content, just header and tasks + .startprompt { + h3 { + margin-bottom: $spacing-internal; + } + .tasks { + margin-top: 0; + padding-top: 0; + border-top: 0; + text-align: left; + } + } + + .leaflet-control-measure-interaction { + padding: $spacing-internal $spacing-external; + } + + .results { + .group { + margin-top: $spacing-internal; + padding-top: $spacing-internal; + border-top: dotted 1px lighten($color-divider, 5); + &:first-child { + margin-top: 0; + padding-top: 0; + border-top: 0; + } + } + .heading { + margin-right: $spacing-internal * 0.5; + color: $color-lightertext; + } + } + + a.start { + @include button(start); + } + a.cancel { + @include button(cancel); + } + a.finish { + @include button(check); + } +} + +.leaflet-measure-resultpopup { + a.zoomto { + @include button(focus); + } + a.deletemarkup { + @include button(trash); + } +} \ No newline at end of file diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/CityAdminList.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/CityAdminList.jsx index be14803..14b18ec 100644 --- a/src/components/dashboard/inquiryPrivacy/city-admin/CityAdminList.jsx +++ b/src/components/dashboard/inquiryPrivacy/city-admin/CityAdminList.jsx @@ -1,15 +1,37 @@ +import CustomSelectByDependency from '@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency'; import DataTableWithAuth from '@/core/components/DataTableWithAuth'; import { GET_CITY_ADMIN_LIST } from '@/core/utils/routes'; -import { Box } from '@mui/material'; +import useInquiryPrivacyState from '@/lib/hooks/useInquiryPrivacyState'; +import { Box, Stack } from '@mui/material'; +import moment from 'jalali-moment'; import { useMemo } from 'react'; +import MapsHomeWorkIcon from '@mui/icons-material/MapsHomeWork'; +import SecurityIcon from '@mui/icons-material/Security'; +import ManageAccountsIcon from '@mui/icons-material/ManageAccounts'; +import PsychologyAltIcon from '@mui/icons-material/PsychologyAlt'; +import ReceiptLongIcon from '@mui/icons-material/ReceiptLong'; +import WindowIcon from '@mui/icons-material/Window'; +import DangerousIcon from '@mui/icons-material/Dangerous'; +import AutorenewIcon from '@mui/icons-material/Autorenew'; import RowActions from './RowActions'; +import ShowPrimaryArea from './ShowPrimaryArea'; const CityAdminList = () => { + const stateIcon = (state_id) => { + if (state_id === 1) return ; + if (state_id === 2 || state_id === 5 || state_id === 13) return ; + if (state_id === 3 || state_id === 6 || state_id === 14) return ; + if (state_id === 4 || state_id === 7 || state_id === 15) return ; + if (state_id === 8) return ; + if (state_id === 9 || state_id === 11) return ; + if (state_id === 10) return ; + if (state_id === 12) return ; + }; const columns = useMemo(() => { return [ { - accessorKey: "id", - header: "کد یکتا", + accessorKey: "panjare_vahed_id", + header: "کدرهگیری درخواست", id: "panjare_vahed_id", enableColumnFilter: true, datatype: "text", @@ -33,6 +55,166 @@ const CityAdminList = () => { size: 100, Cell: ({ row }) => <>{row.original.national_id}, }, + { + accessorKey: "state_id", + header: "وضعیت", + id: "state_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + sortDescFirst: false, + grow: false, + size: 100, + ColumnSelectComponent: (props) => { + const { itemsList, loadingItemsList, errorItemsList } = useInquiryPrivacyState(); + + const getColumnSelectOptions = useMemo(() => { + if (loadingItemsList) { + return [{ value: "loading", label: "در حال بارگذاری..." }]; + } + if (errorItemsList) { + return [{ value: "error", label: "خطا در بارگذاری" }]; + } + return [ + { value: "", label: "همه موارد" }, + ...itemsList.map((item) => ({ + value: item.id, + label: item.name, + })), + ]; + }, [itemsList, loadingItemsList, errorItemsList]); + + return ( + + ); + }, + Cell: ({ row }) => ( + + {stateIcon(row.original.state_id)} + + {row.original.state_name} + + + ), + }, + { + accessorKey: "plan_title", + header: "عنوان طرح", + id: "plan_title", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.plan_title}, + }, + { + accessorKey: "plan_group", + header: "گروه طرح", + id: "plan_group", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.plan_group}, + }, + { + accessorKey: "requested_organization", + header: "دستگاه صادر کننده", + id: "requested_organization", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.requested_organization}, + }, + { + accessorKey: "worksheet_id", + header: "شناسه کاربرگ", + id: "worksheet_id", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.worksheet_id}, + }, + { + accessorKey: "primary_area", + header: "نمایش محدوده طرح", + id: "primary_area", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => row.original.primary_area ? ( + + + + ) : ("-"), + }, + { + accessorKey: "province_id", + header: "استان", + id: "province_id", + enableColumnFilter: false, + datatype: "numeric", + sortDescFirst: false, + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.province_name}, + }, + { + accessorKey: "city_id", + header: "شهر", + id: "city_id", + enableColumnFilter: false, + datatype: "numeric", + sortDescFirst: false, + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.city_name}, + }, + { + accessorKey: "isic", + header: "کد آیسیک", + id: "isic", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => <>{row.original.isic}, + }, + { + accessorFn: (row) => moment(row.request_date).locale("fa").format("YYYY/MM/DD"), + header: "تاریخ درخواست", + id: "request_date", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, ]; }, []); diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/MapDrawPolygon/DrawBound.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/MapDrawPolygon/DrawBound.jsx new file mode 100644 index 0000000..e715f3e --- /dev/null +++ b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/MapDrawPolygon/DrawBound.jsx @@ -0,0 +1,114 @@ +import React, { useCallback, useEffect, useRef, useState } from "react"; +import L from "leaflet"; +import { FeatureGroup, useMap } from "react-leaflet"; +import "leaflet-draw"; + +const DrawPolygon = ({ control, controlDispach, drawBound, setDrawBound }) => { + const map = useMap(); + const featureRef = useRef(null); + const [area, setArea] = useState(); + const drawControlRef = useRef(null); + + const safeFitBounds = (layer) => { + if (!layer || !map) return; + try { + const latLngs = layer.getLatLngs(); + map.fitBounds(latLngs, { + paddingTopLeft: [20, 35], + paddingBottomRight: [20, 55], + }); + } catch (e) { + console.warn("fitBounds failed:", e); + } + }; + + const bindEditEvent = (layer) => { + if (!layer) return; + layer.on("edit", function (e) { + const editedLayer = e.target; + setArea(editedLayer); + setDrawBound(editedLayer); + }); + }; + + const handlerCreatedBound = useCallback((event) => { + const { layer } = event; + layer.editing.enable(); + featureRef.current.addLayer(layer); + setArea(layer); + setDrawBound(layer); + bindEditEvent(layer); + controlDispach({ type: "SET_STATUS", status: 2 }); + }, []); + + useEffect(() => { + if ( + control.status === 1 && + drawControlRef.current && + drawControlRef.current._toolbars?.draw?._modes?.polygon?.handler + ) { + drawControlRef.current._toolbars.draw._modes.polygon.handler.enable(); + } + }, [control.status]); + + useEffect(() => { + if (control.status === 0 && area && featureRef.current) { + featureRef.current.removeLayer(area); + setArea(null); + setDrawBound(null); + } + }, [control.status, area]); + + useEffect(() => { + if (control.status === 2 && drawBound && featureRef.current) { + setArea(drawBound); + featureRef.current.addLayer(drawBound); + drawBound.editing.enable(); + safeFitBounds(drawBound); + bindEditEvent(drawBound); + } + }, [control.status, drawBound]); + + useEffect(() => { + if (!featureRef.current) return; + + L.drawLocal.draw.handlers.polygon.tooltip.start = "برای شروع ترسیم محدوده، روی نقشه کلیک کنید"; + L.drawLocal.draw.handlers.polygon.tooltip.cont = "برای ادامه ترسیم، نقاط بعدی را کلیک کنید"; + L.drawLocal.draw.handlers.polygon.tooltip.end = "برای بستن محدوده، روی نقطه‌ی شروع کلیک کنید"; + + const drawControl = new L.Control.Draw({ + draw: { + polygon: { + shapeOptions: { + color: "red", + weight: 3, + clickable: true, + }, + }, + polyline: false, + rectangle: false, + circle: false, + marker: false, + circlemarker: false, + }, + edit: { + featureGroup: featureRef.current, + edit: true, + remove: false, + }, + }); + + drawControlRef.current = drawControl; + map.addControl(drawControl); + map.on(L.Draw.Event.CREATED, handlerCreatedBound); + + return () => { + map.off(L.Draw.Event.CREATED, handlerCreatedBound); + map.removeControl(drawControl); + }; + }, [map, handlerCreatedBound]); + + return ; +}; + +export default DrawPolygon; diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/MapDrawPolygon/index.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/MapDrawPolygon/index.jsx new file mode 100644 index 0000000..bef1529 --- /dev/null +++ b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/MapDrawPolygon/index.jsx @@ -0,0 +1,116 @@ +import { Delete, Route } from "@mui/icons-material"; +import { Box, Button, Stack, Typography } from "@mui/material"; +import { useReducer } from "react"; +import DrawPolygon from "./DrawBound"; + +const statusType = [ + { + id: 0, + message: "برای آغاز ترسیم محدوده، کلیک کنید!", + buttons: [ + { + label: "شروع ترسیم محدوده", + key: "start", + color: "warning", + icon: , + onclick: (controlDispach) => { + controlDispach({ type: "SET_STATUS", status: 1 }); + }, + }, + ], + }, + { + id: 1, + message: "محدوده‌ی موردنظر را با کلیک روی نقشه مشخص کنید. برای اتمام، روی نقطه‌ی ابتدایی کلیک کنید!", + buttons: [], + }, + { + id: 2, + message: "برای اصلاح محدوده، گوشه‌ها را بکشید. برای ترسیم دوباره، آن را حذف کنید", + buttons: [ + { + label: "حذف", + key: "end", + color: "error", + icon: , + onclick: (controlDispach) => { + controlDispach({ type: "SET_STATUS", status: 0 }); + }, + }, + ], + }, +]; + +const createInitialState = (drawBound) => { + if (drawBound) { + return { status: 2 }; + } + return { status: 0 }; +}; + +const reducer = (state, action) => { + switch (action.type) { + case "SET_STATUS": + return { ...state, status: action.status }; + default: + return state; + } +}; + +const MapDrawPolygon = ({ drawBound, setDrawBound }) => { + const [control, controlDispach] = useReducer(reducer, drawBound, createInitialState); + + return ( + <> + + + theme.palette.secondary.main, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + py: 0.5, + px: 2, + }} + > + + {statusType.find((st) => st.id == control.status).message} + + + + + + {statusType + .find((st) => st.id == control.status) + .buttons.map((button) => ( + + ))} + + + + ); +}; +export default MapDrawPolygon; diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/index.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/index.jsx new file mode 100644 index 0000000..e954aeb --- /dev/null +++ b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/FeedbackAction/index.jsx @@ -0,0 +1,135 @@ +import MapLayer from "@/core/components/MapLayer"; +import { CITY_ADMIN_FEEDBACK } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { yupResolver } from "@hookform/resolvers/yup"; +import CloseIcon from "@mui/icons-material/Close"; +import ForumIcon from '@mui/icons-material/Forum'; +import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, TextField, Tooltip, Typography } from '@mui/material'; +import { useEffect, useMemo, useState } from 'react'; +import { useForm } from "react-hook-form"; +import { object, string } from 'yup'; +import ShowBound from "../../ShowPrimaryArea/ShowBound"; +import MapDrawPolygon from "./MapDrawPolygon"; + +const validationSchema = object({ + expert_description: string().required("توضیحات ناظر اجباری است!"), +}); + +const FeedbackAction = ({rowId, mutate, rowPrimaryArea}) => { + const requestServer = useRequest({ notificationSuccess: true }); + const [openFeedbackDialog, setOpenFeedbackDialog] = useState(false); + const [drawBound, setDrawBound] = useState(null); + const bound = useMemo(() => { + const latLngCoords = rowPrimaryArea.coordinates.map(coord => [coord[1], coord[0]]); + return rowPrimaryArea.type === "polygon" + ? L.polygon(latLngCoords) + : L.polyline(latLngCoords); + }, [rowPrimaryArea]); + + + useEffect(() => { + console.log("drawBound", drawBound); + + }, [drawBound]) + + + const { + control, + register, + handleSubmit, + setValue, + formState: { isSubmitting, errors }, + } = useForm({ + defaultValues: {expert_description: "", forbidden_area: ""}, + resolver: yupResolver(validationSchema), + mode: "all" + }); + + + const onSubmit = async (data) => { + const formData = new FormData(); + formData.append("expert_description", data.expert_description); + + try { + await requestServer(`${CITY_ADMIN_FEEDBACK}/${rowId}`, "post", { + data: formData, + }); + mutate(); + setOpenFeedbackDialog(false); + } catch (error) {} + }; + + + return ( + <> + + + setOpenFeedbackDialog(true)}> + + + + setOpenFeedbackDialog(false)} + 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", + borderRadius: 2, + }, + }} + maxWidth="sm" + fullWidth + dir="rtl" + > + + + توضیحات ناظر + + setOpenFeedbackDialog(false)} size="small"> + + + + + منطقه ممنوعه (در صورت وجود انتخاب کنید) + + + + + + + + + + + + + + + + ) +} + +export default FeedbackAction \ No newline at end of file diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/index.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/index.jsx index c8906f2..a823158 100644 --- a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/index.jsx +++ b/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/index.jsx @@ -1,13 +1,10 @@ import { Box } from "@mui/material"; -import ConfirmAction from "./ConfirmAction"; -import RejectAction from "./RejectAction"; +import FeedbackAction from "./FeedbackAction"; const RowActions = ({ row, mutate }) => { - return ( - - - + + ); }; diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/ShowPrimaryArea/ShowBound.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/ShowPrimaryArea/ShowBound.jsx new file mode 100644 index 0000000..24db476 --- /dev/null +++ b/src/components/dashboard/inquiryPrivacy/city-admin/ShowPrimaryArea/ShowBound.jsx @@ -0,0 +1,29 @@ +import { useEffect, useRef } from "react"; +import { FeatureGroup, useMap } from "react-leaflet"; + +const ShowBound = ({ bound }) => { + const map = useMap(); + const featureRef = useRef(null); + + const safeFitBounds = (layer) => { + if (!layer || !map) return; + try { + const latLngs = layer.getLatLngs(); + map.fitBounds(latLngs, { + paddingTopLeft: [20, 20], + paddingBottomRight: [20, 20], + }); + } catch (e) { + console.warn("fitBounds failed:", e); + } + }; + + useEffect(() => { + bound?.editing?.disable(); + featureRef.current.addLayer(bound); + safeFitBounds(bound); + }, []); + + return ; +}; +export default ShowBound; diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/ShowPrimaryArea/index.jsx b/src/components/dashboard/inquiryPrivacy/city-admin/ShowPrimaryArea/index.jsx new file mode 100644 index 0000000..7300a1f --- /dev/null +++ b/src/components/dashboard/inquiryPrivacy/city-admin/ShowPrimaryArea/index.jsx @@ -0,0 +1,61 @@ +const { Button, IconButton, Tooltip, Box, Dialog, DialogTitle, Typography, DialogContent, DialogActions } = require("@mui/material"); +import LayersIcon from '@mui/icons-material/Layers'; +import CloseIcon from "@mui/icons-material/Close"; +import { useMemo, useState } from 'react'; +import MapLayer from '@/core/components/MapLayer'; +import ShowBound from './ShowBound'; + +const ShowPrimaryArea = ({primaryArea}) => { + const [openShowAreaDialog, setOpenShowAreaDialog] = useState(false); + const bound = useMemo(() => { + const latLngCoords = primaryArea.coordinates.map(coord => [coord[1], coord[0]]); + return primaryArea.type === "polygon" + ? L.polygon(latLngCoords) + : L.polyline(latLngCoords); + }, [primaryArea]); + + return ( + + + setOpenShowAreaDialog(true)}> + + + + setOpenShowAreaDialog(false)} + 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", + borderRadius: 2, + padding: 1, + }, + }} + maxWidth="sm" + fullWidth + dir="rtl" + > + + + محدوده طرح + + setOpenShowAreaDialog(false)} size="small"> + + + + + + + + + + + + + + + ) +} + +export default ShowPrimaryArea \ No newline at end of file diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/ConfirmAction/index.jsx b/src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/ConfirmAction/index.jsx similarity index 100% rename from src/components/dashboard/inquiryPrivacy/city-admin/RowActions/ConfirmAction/index.jsx rename to src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/ConfirmAction/index.jsx diff --git a/src/components/dashboard/inquiryPrivacy/city-admin/RowActions/RejectAction/index.jsx b/src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/RejectAction/index.jsx similarity index 100% rename from src/components/dashboard/inquiryPrivacy/city-admin/RowActions/RejectAction/index.jsx rename to src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/RejectAction/index.jsx diff --git a/src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/index.jsx b/src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/index.jsx new file mode 100644 index 0000000..45e1693 --- /dev/null +++ b/src/components/dashboard/inquiryPrivacy/privacy-office/RowActions/index.jsx @@ -0,0 +1,14 @@ +import { Box } from "@mui/material"; +import ConfirmAction from "./ConfirmAction"; +import RejectAction from "./RejectAction"; + +const RowActions = ({ row, mutate }) => { + + return ( + + + + + ); +}; +export default RowActions; diff --git a/src/components/dashboard/inquiryPrivacy/privacy-office/index.jsx b/src/components/dashboard/inquiryPrivacy/privacy-office/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/core/utils/pageMenuDev.js b/src/core/utils/pageMenuDev.js index 68c6537..67b05dc 100644 --- a/src/core/utils/pageMenuDev.js +++ b/src/core/utils/pageMenuDev.js @@ -24,6 +24,10 @@ import RouteIcon from "@mui/icons-material/Route"; import ScienceIcon from "@mui/icons-material/Science"; import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard"; import SpeedIcon from "@mui/icons-material/Speed"; +import PsychologyAltIcon from '@mui/icons-material/PsychologyAlt'; +import MapsHomeWorkIcon from '@mui/icons-material/MapsHomeWork'; +import SecurityIcon from '@mui/icons-material/Security'; +import ManageAccountsIcon from '@mui/icons-material/ManageAccounts'; export const pageMenuDev = [ { @@ -299,6 +303,7 @@ export const pageMenuDev = [ label: "کارتابل شهرستان", type: "page", route: "/dashboard/inquiry-privacy/city-admin", + icon: , permissions: ["all"], }, { @@ -306,6 +311,7 @@ export const pageMenuDev = [ label: "کارتابل اداره حریم", type: "page", route: "/dashboard/inquiry-privacy/privacy-office", + icon: , permissions: ["all"], }, { @@ -313,6 +319,7 @@ export const pageMenuDev = [ label: "کارتابل معاون", type: "page", route: "/dashboard/inquiry-privacy/assistant", + icon: , permissions: ["all"], }, { @@ -320,6 +327,7 @@ export const pageMenuDev = [ label: "کارتابل مدیر", type: "page", route: "/dashboard/inquiry-privacy/general-manager", + icon: , permissions: ["all"], }, ], diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 780cd12..0a3ee79 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -236,4 +236,6 @@ export const UPDATE_RAHDARAN_ITEM = api + "/api/v3/rahdaran"; export const CREATE_RAHDARAN_ITEM = api + "/api/v3/rahdaran"; // estelam harim -export const GET_CITY_ADMIN_LIST = api + "/api/v3/harim/province_office"; \ No newline at end of file +export const GET_CITY_ADMIN_LIST = api + "/api/v3/harim/province_office"; +export const GET_INQUIRY_PRIVACY_STATE_LIST = api + "/api/v3/harim/detail/states"; +export const CITY_ADMIN_FEEDBACK = api + "/api/v3/harim/province_office/feedback"; \ No newline at end of file diff --git a/src/lib/hooks/useInquiryPrivacyState.js b/src/lib/hooks/useInquiryPrivacyState.js new file mode 100644 index 0000000..a66d83f --- /dev/null +++ b/src/lib/hooks/useInquiryPrivacyState.js @@ -0,0 +1,30 @@ +import { GET_INQUIRY_PRIVACY_STATE_LIST } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { useEffect, useState } from "react"; + +const useInquiryPrivacyState = () => { + const requestServer = useRequest(); + const [itemsList, setItemsList] = useState([]); + const [loadingItemsList, setLoadingItemsList] = useState(true); + const [errorItemsList, setErrorItemsList] = useState(null); + + useEffect(() => { + const fetchItems = async () => { + try { + const response = await requestServer(`${GET_INQUIRY_PRIVACY_STATE_LIST}`); + setItemsList(response.data.data); + setLoadingItemsList(false); + setErrorItemsList(false); + } catch (e) { + setErrorItemsList(e); + setLoadingItemsList(false); + } + }; + + fetchItems(); + }, []); + + return { itemsList, loadingItemsList, errorItemsList }; +}; + +export default useInquiryPrivacyState;