Merge pull request 'feat: add yandex-map' (#94) from feature/maps into main

Reviewed-on: #94
This commit is contained in:
2025-03-09 11:05:52 +03:00
15 changed files with 150 additions and 7 deletions

View File

@@ -42,6 +42,18 @@ const Header = () => {
{t('master')}
</Button>
)}
{URLs.armMap.isOn && (
<Button
as={Link}
to={URLs.armMap.url}
colorScheme={isActive(URLs.armMap.url) ? 'green' : 'blue'}
variant={isActive(URLs.armMap.url) ? 'outline' : 'ghost'}
data-testid='master-button'
>
Карта заказов
</Button>
)}
</HStack>
</Flex>
</Box>

View File

@@ -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 && (
<Route path={URLs.armMaster.url} element={<Masters />} />
)}
{URLs.armMap.isOn && (
<Route path={URLs.armMap.url} element={<OrdersMap />} />
)}
</Routes>
</Box>
</Flex>

View File

@@ -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 (
<Box p='8'>
<Heading size='lg' mb='5'>
{t('title')}
</Heading>
{isLoading && (
<Flex justifyContent='center' alignItems='center'>
<Spinner size='lg' />
</Flex>
)}
{isSuccess && (
<YMaps>
<Map
defaultState={{ center: [latFromUrl, lonFromUrl], zoom: 12 }}
width='100%'
height='70vh'
modules={['geoObject.addon.balloon']}
>
{orders.map(({ id, lat, lon, carNumber, status }) => (
<Placemark
key={id}
geometry={[lat, lon]}
options={{
preset: 'islands#blueAutoIcon',
iconColor: 'blue',
balloonPanelMaxMapArea: 0,
}}
properties={{
balloonContent: `<strong>${t('carNumber')}</strong> ${carNumber}<br/><strong>${t('status')}</strong> ${status}`,
}}
/>
))}
</Map>
</YMaps>
)}
</Box>
);
};
export default OrdersMap;

View File

@@ -0,0 +1 @@
export { default } from './Map';

View File

@@ -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<Status, string> = {
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 (
<Tr>
<Td>{carNumber}</Td>
@@ -99,7 +104,12 @@ const OrderItem = ({
<Link href='tel:'>{phone}</Link>
</Td>
<Td>
<PopoverTemplate trigger={<ViewIcon />} description={location} />
<Button
as={LinkRouter}
to={URLs.armMap.getUrl({ lat, lon, currentDate })}
>
<ViewIcon />
</Button>
</Td>
</Tr>
);

View File

@@ -112,6 +112,7 @@ const Orders = () => {
key={index}
{...order}
status={order.status as OrderArm['status']}
currentDate={currentDate}
/>
))}
</Tbody>