From fea4a54c83205094579f42f40dbd7e6b07115dbb Mon Sep 17 00:00:00 2001 From: ilnaz <237x237@gmail.com> Date: Sun, 9 Mar 2025 10:55:24 +0300 Subject: [PATCH] feat: add yandex-map --- bro.config.js | 1 + locales/en.json | 5 +- locales/ru.json | 5 +- package-lock.json | 1 - src/__data__/service/utils.ts | 1 + src/__data__/urls.ts | 12 ++++ src/components/Header/Header.tsx | 12 ++++ src/components/LayoutArm/LayoutArm.tsx | 4 ++ src/components/Map/Map.tsx | 82 ++++++++++++++++++++++++++ src/components/Map/index.ts | 1 + src/components/OrderItem/OrderItem.tsx | 16 ++++- src/components/Orders/Orders.tsx | 1 + src/models/api/order.ts | 1 + src/utils/getCoordinates.ts | 13 ++++ stubs/json/arm-orders/success.json | 2 +- 15 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 src/components/Map/Map.tsx create mode 100644 src/components/Map/index.ts create mode 100644 src/utils/getCoordinates.ts diff --git a/bro.config.js b/bro.config.js index e038fed..11da4e2 100644 --- a/bro.config.js +++ b/bro.config.js @@ -16,6 +16,7 @@ module.exports = { 'dry-wash.order.view': '/order/:orderId', 'dry-wash.arm.master': 'master', 'dry-wash.arm.order': 'order', + 'dry-wash.arm.map': 'map', 'dry-wash.arm': '/arm/*', }, features: { diff --git a/locales/en.json b/locales/en.json index 155e992..4717213 100644 --- a/locales/en.json +++ b/locales/en.json @@ -111,5 +111,8 @@ "dry-wash.errorBoundary.title": "Something went wrong", "dry-wash.errorBoundary.description": "We are already working on fixing the issue", "dry-wash.errorBoundary.button.reload": "Reload Page", - "dry-wash.washTime.timeSlot": "{{start}} - {{end}}" + "dry-wash.washTime.timeSlot": "{{start}} - {{end}}", + "dry-wash.arm.map.title": "Map of orders", + "dry-wash.arm.map.carNumber": "Car Number", + "dry-wash.arm.map.status": "Status" } diff --git a/locales/ru.json b/locales/ru.json index ed6718d..1467161 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -117,5 +117,8 @@ "dry-wash.errorBoundary.title": "Что-то пошло не так", "dry-wash.errorBoundary.description": "Мы уже работаем над исправлением проблемы", "dry-wash.errorBoundary.button.reload": "Перезагрузить страницу", - "dry-wash.washTime.timeSlot": "{{start}} - {{end}}" + "dry-wash.washTime.timeSlot": "{{start}} - {{end}}", + "dry-wash.arm.map.title": " Карта заказов", + "dry-wash.arm.map.carNumber": " Номер автомобиля", + "dry-wash.arm.map.status": "Статус" } diff --git a/package-lock.json b/package-lock.json index b44e215..102902a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3610,7 +3610,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/@pbe/react-yandex-maps/-/react-yandex-maps-1.2.5.tgz", "integrity": "sha512-cBojin5e1fPx9XVCAqHQJsCnHGMeBNsP0TrNfpWCrPFfxb30ye+JgcGr2mn767Gbr1d+RufBLRiUcX2kaiAwjQ==", - "license": "MIT", "dependencies": { "@types/yandex-maps": "2.1.29" }, diff --git a/src/__data__/service/utils.ts b/src/__data__/service/utils.ts index f55bb9c..c03db86 100644 --- a/src/__data__/service/utils.ts +++ b/src/__data__/service/utils.ts @@ -3,6 +3,7 @@ import { FetchBaseQueryError } from '@reduxjs/toolkit/query'; import { BaseResponse } from '../../models/api'; export const extractBodyFromResponse = (response: BaseResponse) => { + console.log('response', response); if (response.success) { return response.body; } diff --git a/src/__data__/urls.ts b/src/__data__/urls.ts index 74cd068..5d75abc 100644 --- a/src/__data__/urls.ts +++ b/src/__data__/urls.ts @@ -33,6 +33,18 @@ export const URLs = { url: getNavigationValue('dry-wash.arm.order'), isOn: Boolean(getNavigationValue('dry-wash.arm.order')), }, + armMap: { + url: getNavigationValue('dry-wash.arm.map'), + isOn: Boolean(getNavigationValue('dry-wash.arm.map')), + getUrl({ lat, lon, currentDate }) { + return ( + getFullUrls('/arm') + + '/' + + getNavigationValue('dry-wash.arm.map') + + `?lat=${lat}&lon=${lon}¤tDate=${currentDate}` + ); + }, + }, armBase: { url: getFullUrls(getNavigationValue('dry-wash.arm')), isOn: Boolean(getNavigationValue('dry-wash.arm')), diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 9adba6b..996f417 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -42,6 +42,18 @@ const Header = () => { {t('master')} )} + + {URLs.armMap.isOn && ( + + )} diff --git a/src/components/LayoutArm/LayoutArm.tsx b/src/components/LayoutArm/LayoutArm.tsx index 6c04037..9669efb 100644 --- a/src/components/LayoutArm/LayoutArm.tsx +++ b/src/components/LayoutArm/LayoutArm.tsx @@ -6,6 +6,7 @@ import Orders from '../Orders'; import Masters from '../Masters'; import { URLs } from '../../__data__/urls'; import Header from '../Header'; +import OrdersMap from '../Map'; const LayoutArm = () => { let defaultRedirect = null; @@ -28,6 +29,9 @@ const LayoutArm = () => { {URLs.armMaster.isOn && ( } /> )} + {URLs.armMap.isOn && ( + } /> + )} diff --git a/src/components/Map/Map.tsx b/src/components/Map/Map.tsx new file mode 100644 index 0000000..5a3c19c --- /dev/null +++ b/src/components/Map/Map.tsx @@ -0,0 +1,82 @@ +import React, { useMemo } from 'react'; +import { Box, Flex, Heading, Spinner } from '@chakra-ui/react'; +import { useTranslation } from 'react-i18next'; +import { YMaps, Map, Placemark } from '@pbe/react-yandex-maps'; +import { useLocation } from 'react-router-dom'; + +import { useGetOrdersQuery } from '../../__data__/service/api'; +import getCoordinates from '../../utils/getCoordinates'; + +const OrdersMap = () => { + const { t } = useTranslation('~', { + keyPrefix: 'dry-wash.arm.map', + }); + + const location = useLocation(); + const params = new URLSearchParams(location.search); + const latFromUrl = parseFloat(params.get('lat') || 55.78); + const lonFromUrl = parseFloat(params.get('lon') || 49.12); + const currentDate = useMemo( + () => + params.get('currentDate') + ? new Date(params.get('currentDate')) + : new Date(), + [], + ); + + const { + data: ordersData, + isLoading, + isSuccess, + } = useGetOrdersQuery({ date: currentDate }); + + // Получаем координаты из location + const orders = ordersData + ?.map((order) => { + const coords = getCoordinates(order.location); + return coords ? { ...order, ...coords } : null; + }) + .filter(Boolean); + + return ( + + + {t('title')} + + + {isLoading && ( + + + + )} + + {isSuccess && ( + + + {orders.map(({ id, lat, lon, carNumber, status }) => ( + ${t('carNumber')} ${carNumber}
${t('status')} ${status}`, + }} + /> + ))} +
+
+ )} +
+ ); +}; + +export default OrdersMap; diff --git a/src/components/Map/index.ts b/src/components/Map/index.ts new file mode 100644 index 0000000..84bebe9 --- /dev/null +++ b/src/components/Map/index.ts @@ -0,0 +1 @@ +export { default } from './Map'; diff --git a/src/components/OrderItem/OrderItem.tsx b/src/components/OrderItem/OrderItem.tsx index e3fd853..f323e25 100644 --- a/src/components/OrderItem/OrderItem.tsx +++ b/src/components/OrderItem/OrderItem.tsx @@ -1,13 +1,15 @@ import React, { ChangeEvent, useState } from 'react'; -import { Td, Tr, Link, Select } from '@chakra-ui/react'; +import { Td, Tr, Link, Select, Button } from '@chakra-ui/react'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; import { ViewIcon } from '@chakra-ui/icons'; +import { Link as LinkRouter } from 'react-router-dom'; import { getTimeSlot } from '../../lib'; import { useUpdateOrdersMutation } from '../../__data__/service/api'; import { OrderArm, Status, statuses } from '../../models/api'; -import PopoverTemplate from '../PopoverTemplate'; +import getCoordinates from '../../utils/getCoordinates'; +import { URLs } from '../../__data__/urls'; const statusColors: Record = { pending: 'yellow.100', @@ -27,6 +29,7 @@ const OrderItem = ({ master, allMasters, id, + currentDate, }: OrderArm) => { const [updateOrders] = useUpdateOrdersMutation(); const { t } = useTranslation('~', { @@ -61,6 +64,8 @@ const OrderItem = ({ (master) => master.id === masterSelectId, ); + const { lat = 55.78, lon = 49.12 } = getCoordinates(location); + return ( {carNumber} @@ -99,7 +104,12 @@ const OrderItem = ({ {phone} - } description={location} /> + ); diff --git a/src/components/Orders/Orders.tsx b/src/components/Orders/Orders.tsx index b18f4da..81d3f22 100644 --- a/src/components/Orders/Orders.tsx +++ b/src/components/Orders/Orders.tsx @@ -112,6 +112,7 @@ const Orders = () => { key={index} {...order} status={order.status as OrderArm['status']} + currentDate={currentDate} /> ))} diff --git a/src/models/api/order.ts b/src/models/api/order.ts index 012e2ba..c3ba265 100644 --- a/src/models/api/order.ts +++ b/src/models/api/order.ts @@ -56,4 +56,5 @@ export type OrderArm = { notes: ''; allMasters: Master[]; id: string; + currentDate: Date; }; diff --git a/src/utils/getCoordinates.ts b/src/utils/getCoordinates.ts new file mode 100644 index 0000000..314e617 --- /dev/null +++ b/src/utils/getCoordinates.ts @@ -0,0 +1,13 @@ +const getCoordinates = (location: string) => { + if (!location) return null; + + const [lat, lon] = location + .split(',') + .map((coord) => parseFloat(coord.trim())); + + if (isNaN(lat) || isNaN(lon)) return null; + + return { lat, lon }; +}; + +export default getCoordinates; diff --git a/stubs/json/arm-orders/success.json b/stubs/json/arm-orders/success.json index f2f2454..66a2086 100644 --- a/stubs/json/arm-orders/success.json +++ b/stubs/json/arm-orders/success.json @@ -21,7 +21,7 @@ "orderDate": "2024-11-24T07:40:46.366Z", "status": "progress", "phone": "79001234567", - "location": "55.779905316526424,49.12446113769528 Республика Татарстан (Татарстан), Казань, озеро Нижний Кабан", + "location": "55.75060416346278,48.746329576898944 Республика Татарстан (Татарстан), Верхнеуслонский район, Иннополис", "master": [], "notes": "" }