diff --git a/.env.local.example b/.env.local.example index c93a078..fa80b33 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1,2 +1,3 @@ NEXT_PUBLIC_VERSION="0.2.0" -NEXT_PUBLIC_API_URL="https://rms.witel.ir" \ No newline at end of file +NEXT_PUBLIC_API_URL="https://rms.witel.ir" +NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map" \ No newline at end of file diff --git a/package.json b/package.json index 7bec569..9ca9364 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "next": "^14.2.3", "react": "^18", "react-dom": "^18", + "react-leaflet": "^4.2.1", "react-toastify": "^10.0.5", "sass": "^1.75.0", "stylis": "^4.3.1", @@ -41,4 +42,4 @@ "eslint-config-prettier": "^9.1.0", "prettier": "^3.3.2" } -} +} \ No newline at end of file diff --git a/public/global.scss b/public/global.scss index d1d10e3..7b73e7e 100644 --- a/public/global.scss +++ b/public/global.scss @@ -1,8 +1,10 @@ @import "fontiran"; +@import "leaflet/dist/leaflet.css"; @import "react-toastify/dist/ReactToastify.css"; .filter-toast { - box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, - rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - background-color: #d0dfe8; + box-shadow: + rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, + rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + background-color: #d0dfe8; } diff --git a/public/images/locationMarker.png b/public/images/locationMarker.png new file mode 100644 index 0000000..5e19b95 Binary files /dev/null and b/public/images/locationMarker.png differ diff --git a/src/components/dashboard/inquiryPrivacyFencing/Create/Form/LocationOnMap/index.jsx b/src/components/dashboard/inquiryPrivacyFencing/Create/Form/LocationOnMap/index.jsx new file mode 100644 index 0000000..ce08a88 --- /dev/null +++ b/src/components/dashboard/inquiryPrivacyFencing/Create/Form/LocationOnMap/index.jsx @@ -0,0 +1,23 @@ +import MapLoading from "@/core/components/MapLayer/Loading"; +import MarkerLocation from "@/core/components/MapLayer/MarkerLocation"; +import { Paper, Stack } from "@mui/material"; +import { useFormikContext } from "formik"; +import dynamic from "next/dynamic"; + +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const LocationOnMap = () => { + return ( + + + + + + + + ) +} +export default LocationOnMap \ No newline at end of file diff --git a/src/components/dashboard/inquiryPrivacyFencing/Create/Form/index.jsx b/src/components/dashboard/inquiryPrivacyFencing/Create/Form/index.jsx new file mode 100644 index 0000000..e302b9d --- /dev/null +++ b/src/components/dashboard/inquiryPrivacyFencing/Create/Form/index.jsx @@ -0,0 +1,407 @@ +import LtrTextField from "@/core/components/LtrTextField"; +import { Autocomplete, Button, Chip, DialogActions, DialogContent, Grid, InputAdornment, Stack, TextField, Typography } from "@mui/material"; +import { DatePicker, LocalizationProvider, faIR } from "@mui/x-date-pickers"; +import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import LocationOnMap from "./LocationOnMap"; +import { Formik } from "formik"; +import StyledForm from "@/core/components/StyledForm"; +import moment from "jalali-moment"; +import useRequest from "@/lib/hooks/useRequest"; +import { SET_INQUIRE_PRIVACY_FENCING } from "@/core/utils/routes"; + +const CreateForm = ({ handleClose }) => { + const request = useRequest() + return ( + + { + try { + await request(SET_INQUIRE_PRIVACY_FENCING, 'post', { data: { ...values, ehdasat_type_id: values.ehdasat_type_id.join("|") } }) + handleClose() + } catch (error) { + + } + finally { + setSubmitting(false); + } + }} + > + {formik => ( + <> + + + + + + + + formik.setFieldValue('nameh_date', moment(newValue))} + label="تاریخ نامه درخواست" + slotProps={{ + textField: { fullWidth: true, size: "small" }, + }} + /> + + + + + + { + formik.setFieldValue('motaghazi_is_legal_id', newValue) + }} + options={["حقوقی", "حقیقی"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('motaghazi_type_id', newValue) + }} + options={["دولتی", "خصوصی"]} + renderInput={(params) => } + /> + + + + + + + + + + + + + + + + + + + + + + { + formik.setFieldValue('edare_kol_id', newValue) + }} + renderInput={(params) => ( + + )} + /> + + + { + formik.setFieldValue('edare_shahri_id', newValue) + }} + options={["تهران"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('rah_type_id', newValue) + }} + options={["آزاد راه", "بزرگراه"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('name_mehvar_id', newValue) + }} + options={["تست"]} + renderInput={(params) => } + /> + + + {/* */} + + + { + formik.setFieldValue('samt_id', newValue) + }} + options={["چپ", "راست"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('mizan_harim', newValue) + }} + options={["12.5", "17.5"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('arze_navar', newValue) + }} + options={["15", "30"]} + renderInput={(params) => } + /> + + + + + + + + + + + + { + formik.setFieldValue('zone', newValue) + }} + options={["38", "39"]} + renderInput={(params) => } + /> + + + + { + formik.setFieldValue('karbari_type_id', newValue) + }} + renderInput={(params) => } + /> + + + + + + + مترمربع, + }} /> + + + { + formik.setFieldValue('ehdasat_type_id', newValue) + }} + renderTags={(value, getTagProps) => + value.map((option, index) => { + const { key, ...tagProps } = getTagProps({ index }); + return ( + + ); + }) + } + options={["تعمیرات", "احداث بنا"]} + renderInput={(params) => } + /> + + + متر, + }} /> + + + متر, + }} /> + + + { + formik.setFieldValue('mahale_ejra_id', newValue) + }} + options={["داخل حریم"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('traffic_id', newValue) + }} + options={["سبک (ضریب ۱)"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('vaziat_eghtesadi_id', newValue) + }} + options={["تست"]} + renderInput={(params) => } + /> + + + { + formik.setFieldValue('has_access_id', newValue) + }} + options={["بله", "خیر"]} + renderInput={(params) => } + /> + + + + + + + حداکثر مدت زمان شروع عملیات: + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + + ); +}; +export default CreateForm; diff --git a/src/components/dashboard/inquiryPrivacyFencing/Create/index.jsx b/src/components/dashboard/inquiryPrivacyFencing/Create/index.jsx new file mode 100644 index 0000000..a939113 --- /dev/null +++ b/src/components/dashboard/inquiryPrivacyFencing/Create/index.jsx @@ -0,0 +1,41 @@ +"use client"; +import { Close } from "@mui/icons-material"; +import { Dialog, DialogTitle, IconButton, Slide } from "@mui/material"; +import { useState } from "react"; +import CreateForm from "./Form"; +import DialogTransition from "@/core/components/DialogTransition"; + +const InquiryPrivacyFencingCreate = () => { + const [open, setOpen] = useState(true); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = (value) => { + setOpen(false); + }; + return ( + <> + + + ایجاد پاسخ به استعلام + + theme.palette.grey[500], + }} + > + + + + + + ); +}; +export default InquiryPrivacyFencingCreate; diff --git a/src/core/components/DialogTransition.jsx b/src/core/components/DialogTransition.jsx new file mode 100644 index 0000000..f289140 --- /dev/null +++ b/src/core/components/DialogTransition.jsx @@ -0,0 +1,8 @@ +import { Slide } from "@mui/material"; +import React from "react"; + +const DialogTransition = React.forwardRef(function Transition(props, ref) { + return ; +}); + +export default DialogTransition \ No newline at end of file diff --git a/src/core/components/MapLayer/Loading/index.jsx b/src/core/components/MapLayer/Loading/index.jsx new file mode 100644 index 0000000..5d42012 --- /dev/null +++ b/src/core/components/MapLayer/Loading/index.jsx @@ -0,0 +1,17 @@ +import { Box, LinearProgress, Stack } from "@mui/material"; + +function MapLoading() { + return ( + + + + + + ); +} + +export default MapLoading; \ No newline at end of file diff --git a/src/core/components/MapLayer/MarkerLocation/index.jsx b/src/core/components/MapLayer/MarkerLocation/index.jsx new file mode 100644 index 0000000..c12a9d0 --- /dev/null +++ b/src/core/components/MapLayer/MarkerLocation/index.jsx @@ -0,0 +1,34 @@ +import { useFormikContext } from "formik"; +import { useRef } from "react"; +import { Marker, useMapEvents } from "react-leaflet" + +const prefix = process.env.NODE_ENV === "production" ? "/v3" : ""; + +const locationMarker = L.icon({ + iconUrl: prefix + "/images/locationMarker.png", + iconSize: [50, 50], + iconAnchor: [25, 50], +}); + +const MarkerLocation = () => { + const { setFieldValue } = useFormikContext() + const location = useRef(); + const map = useMapEvents({ + move: (e) => { + const latlon = e.target.getCenter() + location.current?.setLatLng(latlon); + setFieldValue('lat', latlon.lat) + setFieldValue('lon', latlon.lng) + }, + zoom: (e) => { + const latlon = e.target.getCenter() + location.current?.setLatLng(latlon); + setFieldValue('lat', latlon.lat) + setFieldValue('lon', latlon.lng) + }, + }); + return ( + + ) +} +export default MarkerLocation \ No newline at end of file diff --git a/src/core/components/MapLayer/index.jsx b/src/core/components/MapLayer/index.jsx new file mode 100644 index 0000000..52209da --- /dev/null +++ b/src/core/components/MapLayer/index.jsx @@ -0,0 +1,43 @@ +"use client"; +import { MapContainer, TileLayer, useMap } from "react-leaflet"; + +export const IRAN_CENTER = L.latLng(32.4279, 53.6880); + +const MapOptions = ({ options }) => { + const map = useMap(); + if (!options) return; + + if (options.mapDrag) { + map.dragging.enable(); + map.scrollWheelZoom.enable(); + map.touchZoom.enable(); + map.doubleClickZoom.enable(); + } else { + map.dragging.disable(); + map.scrollWheelZoom.disable(); + map.touchZoom.disable(); + map.doubleClickZoom.disable(); + } +}; + +function MapLayer({ children, style, otherLayers, options }) { + return ( + <> + + + + {children} + + {otherLayers} + + ); +} + +export default MapLayer; \ No newline at end of file diff --git a/src/core/components/StyledForm.jsx b/src/core/components/StyledForm.jsx new file mode 100644 index 0000000..1f299bb --- /dev/null +++ b/src/core/components/StyledForm.jsx @@ -0,0 +1,6 @@ +import { styled } from "@mui/material"; +import { Form } from "formik"; + +const StyledForm = styled(Form)``; + +export default StyledForm; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index eb14f6c..de863af 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -4,3 +4,5 @@ export const GET_USER_ROUTE = api + "/webapi/user/get-permission"; export const GET_LOGIN_ROUTE = api + "/login_dev"; export const GET_PERMISSIONS_ROUTE = api + "/webapi/user/get-permission"; + +export const SET_INQUIRE_PRIVACY_FENCING = api + "/api/v3/harim/divarkeshi/store";