Compare commits

..

19 Commits

Author SHA1 Message Date
RustamRu
351420bc62 0.9.1
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-23 12:37:44 +03:00
RustamRu
61b042eee6 fix: image input accept, i18n (#88)
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-23 12:37:04 +03:00
RustamRu
ac006267a2 0.9.0
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-23 12:11:20 +03:00
RustamRu
63d9d069c0 feat: add car image feature
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-23 12:08:50 +03:00
c83ebf02bc Merge pull request 'feature/upload-car-image' (#90) from feature/upload-car-image into main
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
Reviewed-on: #90
2025-02-23 12:02:39 +03:00
RustamRu
1968df7bb3 fix: getOrder test (#88)
All checks were successful
it-academy/dry-wash-pl/pipeline/pr-main This commit looks good
2025-02-23 11:58:56 +03:00
RustamRu
811e0e3f24 Merge remote-tracking branch 'origin/main' into feature/upload-car-image
Some checks failed
it-academy/dry-wash-pl/pipeline/pr-main There was a failure building this commit
2025-02-23 11:47:04 +03:00
a2ffd6f38f Merge pull request 'fix tests error' (#89) from debug into main
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
Reviewed-on: #89
2025-02-23 11:32:09 +03:00
RustamRu
20017cad3c feat: upload car img form (#88)
Some checks failed
it-academy/dry-wash-pl/pipeline/head There was a failure building this commit
it-academy/dry-wash-pl/pipeline/pr-main There was a failure building this commit
2025-02-22 19:46:27 +03:00
RustamRu
de54ac6669 feat: api upload car img (#88) 2025-02-22 18:56:37 +03:00
RustamRu
eda869622e fix: error body message -> error (#88) 2025-02-22 18:56:20 +03:00
Primakov Alexandr Alexandrovich
7b3889aa02 run last one
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
it-academy/dry-wash-pl/pipeline/pr-main This commit looks good
2025-02-20 14:15:25 +03:00
Primakov Alexandr Alexandrovich
cee124fca5 other 2
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-20 14:10:46 +03:00
Primakov Alexandr Alexandrovich
b77eccc8e8 test: улучшены описания тестов страницы просмотра заказа
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
- Добавлены более информативные описания тестовых сценариев
- Улучшена читаемость тестов за счет детальных названий на русском языке
2025-02-20 14:04:32 +03:00
Primakov Alexandr Alexandrovich
ebfaa7ea8f orders page
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-20 14:00:34 +03:00
Primakov Alexandr Alexandrovich
0027cc09b1 masters test
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-20 13:55:05 +03:00
Primakov Alexandr Alexandrovich
dd612d662c debug
All checks were successful
it-academy/dry-wash-pl/pipeline/head This commit looks good
2025-02-20 13:44:38 +03:00
Primakov Alexandr Alexandrovich
69251745fa try fix
Some checks failed
it-academy/dry-wash-pl/pipeline/head There was a failure building this commit
2025-02-20 13:32:39 +03:00
Primakov Alexandr Alexandrovich
253e3b3856 try skip one test
Some checks failed
it-academy/dry-wash-pl/pipeline/head There was a failure building this commit
2025-02-20 13:26:35 +03:00
12 changed files with 83 additions and 111 deletions

View File

@ -64,7 +64,7 @@
"dry-wash.arm.order.status.complete": "Completed", "dry-wash.arm.order.status.complete": "Completed",
"dry-wash.arm.order.status.pending": "Pending", "dry-wash.arm.order.status.pending": "Pending",
"dry-wash.arm.order.status.working": "Working", "dry-wash.arm.order.status.working": "Working",
"dry-wash.arm.order.status.cancelled": "Canceled", "dry-wash.arm.order.status.canceled": "Canceled",
"dry-wash.arm.order.status.placeholder": "Select status", "dry-wash.arm.order.status.placeholder": "Select status",
"dry-wash.arm.order.master.placeholder": "Select master", "dry-wash.arm.order.master.placeholder": "Select master",
"dry-wash.arm.order.table.header.carNumber": "Car Number", "dry-wash.arm.order.table.header.carNumber": "Car Number",

View File

@ -5,7 +5,7 @@
"dry-wash.arm.order.status.complete": "Завершено", "dry-wash.arm.order.status.complete": "Завершено",
"dry-wash.arm.order.status.pending": "В ожидании", "dry-wash.arm.order.status.pending": "В ожидании",
"dry-wash.arm.order.status.working": "В работе", "dry-wash.arm.order.status.working": "В работе",
"dry-wash.arm.order.status.cancelled": "Отменено", "dry-wash.arm.order.status.canceled": "Отменено",
"dry-wash.arm.order.status.placeholder": "Выберите статус", "dry-wash.arm.order.status.placeholder": "Выберите статус",
"dry-wash.arm.order.master.placeholder": "Выберите мастера", "dry-wash.arm.order.master.placeholder": "Выберите мастера",
"dry-wash.arm.order.table.header.carNumber": "Номер машины", "dry-wash.arm.order.table.header.carNumber": "Номер машины",

View File

@ -1,51 +0,0 @@
import { Box, Button, Heading, HStack, Divider, Flex } from '@chakra-ui/react';
import React from 'react';
import { useLocation, Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { URLs } from '../../__data__/urls';
const Header = () => {
const location = useLocation();
const isActive = (keyword: string) => location.pathname.includes(keyword);
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.master.sideBar',
});
return (
<Box as='header' bg='gray.50' boxShadow='md' px={6} py={4} w='100%'>
<Flex gap={50} align='center'>
<Heading color='green' size='lg'>
{t('title')}
</Heading>
<HStack spacing={4}>
{URLs.armOrder.isOn && (
<Button
as={Link}
to={URLs.armOrder.url}
colorScheme={isActive(URLs.armOrder.url) ? 'green' : 'blue'}
variant={isActive(URLs.armOrder.url) ? 'outline' : 'ghost'}
>
{t('orders')}
</Button>
)}
<Divider orientation='vertical' height='30px' />
{URLs.armMaster.isOn && (
<Button
as={Link}
to={URLs.armMaster.url}
colorScheme={isActive(URLs.armMaster.url) ? 'green' : 'blue'}
variant={isActive(URLs.armMaster.url) ? 'outline' : 'ghost'}
data-testid='master-button'
>
{t('master')}
</Button>
)}
</HStack>
</Flex>
</Box>
);
};
export default Header;

View File

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

View File

@ -2,10 +2,10 @@ import { Box, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom'; import { Navigate, Route, Routes } from 'react-router-dom';
import Sidebar from '../Sidebar';
import Orders from '../Orders'; import Orders from '../Orders';
import Masters from '../Masters'; import Masters from '../Masters';
import { URLs } from '../../__data__/urls'; import { URLs } from '../../__data__/urls';
import Header from '../Header';
const LayoutArm = () => { const LayoutArm = () => {
let defaultRedirect = null; let defaultRedirect = null;
@ -17,8 +17,8 @@ const LayoutArm = () => {
} }
return ( return (
<Flex flexDirection='column' h='100vh'> <Flex h='100vh'>
<Header /> <Sidebar />
<Box flex='1' bg='gray.50'> <Box flex='1' bg='gray.50'>
<Routes> <Routes>
<Route index element={<Navigate to={defaultRedirect} replace />} /> <Route index element={<Navigate to={defaultRedirect} replace />} />

View File

@ -2,17 +2,16 @@ import React, { ChangeEvent, useState } from 'react';
import { Td, Tr, Link, Select } from '@chakra-ui/react'; import { Td, Tr, Link, Select } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { ViewIcon } from '@chakra-ui/icons';
import { getTimeSlot } from '../../lib'; import { getTimeSlot } from '../../lib';
import { useUpdateOrdersMutation } from '../../__data__/service/api'; import { useUpdateOrdersMutation } from '../../__data__/service/api';
import { OrderArm, Status, statuses } from '../../models/api'; import { OrderArm, Status, statuses } from '../../models/api';
import PopoverTemplate from '../PopoverTemplate';
const statusColors: Record<Status, string> = { const statusColors: Record<Status, string> = {
pending: 'yellow.100', pending: 'yellow.100',
progress: 'blue.100', progress: 'blue.100',
cancelled: 'red.100', working: 'orange.100',
canceled: 'red.100',
complete: 'green.100', complete: 'green.100',
}; };
@ -35,7 +34,7 @@ const OrderItem = ({
const [statusSelect, setStatus] = useState(status); const [statusSelect, setStatus] = useState(status);
const bgColor = statusColors[statusSelect]; const bgColor = statusColors[statusSelect];
const [masterSelectId, setMasterSelectId] = useState(master); const [masterSelect, setMaster] = useState(master?.name);
const handelChangeMasters = (e: ChangeEvent<HTMLSelectElement>) => { const handelChangeMasters = (e: ChangeEvent<HTMLSelectElement>) => {
const masterName = e.target.value; const masterName = e.target.value;
@ -44,7 +43,7 @@ const OrderItem = ({
); );
if (selectedMaster) { if (selectedMaster) {
setMasterSelectId(selectedMaster.id); setMaster(masterName);
updateOrders({ id, master: selectedMaster.id }); updateOrders({ id, master: selectedMaster.id });
} else { } else {
console.error('Master not found'); console.error('Master not found');
@ -57,10 +56,6 @@ const OrderItem = ({
setStatus(status); setStatus(status);
}; };
const masterSelectChange = allMasters.find(
(master) => master.id === masterSelectId,
);
return ( return (
<Tr> <Tr>
<Td>{carNumber}</Td> <Td>{carNumber}</Td>
@ -84,7 +79,7 @@ const OrderItem = ({
</Td> </Td>
<Td> <Td>
<Select <Select
value={masterSelectChange?.name} value={masterSelect}
onChange={handelChangeMasters} onChange={handelChangeMasters}
placeholder={t(`master.placeholder`)} placeholder={t(`master.placeholder`)}
> >
@ -98,9 +93,7 @@ const OrderItem = ({
<Td> <Td>
<Link href='tel:'>{phone}</Link> <Link href='tel:'>{phone}</Link>
</Td> </Td>
<Td> <Td>{location}</Td>
<PopoverTemplate trigger={<ViewIcon />} description={location} />
</Td>
</Tr> </Tr>
); );
}; };

View File

@ -1,35 +0,0 @@
import React from 'react';
import {
Button,
Popover,
PopoverArrow,
PopoverBody,
PopoverCloseButton,
PopoverContent,
PopoverHeader,
PopoverTrigger,
} from '@chakra-ui/react';
interface Props {
title?: string;
description: string;
trigger?: React.ReactNode;
}
const PopoverTemplate = ({ title, description, trigger }: Props) => {
return (
<Popover>
<PopoverTrigger>
<Button>{trigger}</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
{title && <PopoverHeader>{title}!</PopoverHeader>}
<PopoverBody mr={5}>{description}</PopoverBody>
</PopoverContent>
</Popover>
);
};
export default PopoverTemplate;

View File

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

View File

@ -0,0 +1,61 @@
import { Box, Button, Heading, VStack, Divider } from '@chakra-ui/react';
import React from 'react';
import { useLocation, Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { URLs } from '../../__data__/urls';
const Sidebar = () => {
const location = useLocation();
const isActive = (keyword: string) => location.pathname.includes(keyword);
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.master.sideBar',
});
return (
<Box
borderRight='1px solid black'
bg='gray.50'
color='white'
w='250px'
p='5'
pt='8'
>
<Heading color='green' size='lg' mb='5'>
{t('title')}
</Heading>
<VStack align='start' spacing='4'>
<Divider />
{URLs.armOrder.isOn && (
<Button
as={Link}
to={URLs.armOrder.url}
w='100%'
colorScheme={isActive(URLs.armOrder.url) ? 'green' : 'blue'}
variant={isActive(URLs.armOrder.url) ? 'solid' : 'ghost'}
>
{t('orders')}
</Button>
)}
<Divider />
{URLs.armMaster.isOn && (
<Button
as={Link}
to={URLs.armMaster.url}
w='100%'
colorScheme={isActive(URLs.armMaster.url) ? 'green' : 'blue'}
variant={isActive(URLs.armMaster.url) ? 'solid' : 'ghost'}
data-testid='master-button'
>
{t('master')}
</Button>
)}
<Divider />
</VStack>
</Box>
);
};
export default Sidebar;

View File

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

View File

@ -38,7 +38,8 @@ type GetArrItemType<ArrType> =
export const statuses = [ export const statuses = [
'pending' as const, 'pending' as const,
'progress' as const, 'progress' as const,
'cancelled' as const, 'working' as const,
'canceled' as const,
'complete' as const, 'complete' as const,
]; ];
@ -52,7 +53,7 @@ export type OrderArm = {
status?: GetArrItemType<typeof statuses>; status?: GetArrItemType<typeof statuses>;
phone?: string; phone?: string;
location?: string; location?: string;
master: string | []; master: Master;
notes: ''; notes: '';
allMasters: Master[]; allMasters: Master[];
id: string; id: string;

View File

@ -9,8 +9,12 @@
"orderDate": "2024-11-24T08:41:46.366Z", "orderDate": "2024-11-24T08:41:46.366Z",
"status": "pending", "status": "pending",
"phone": "79001234563", "phone": "79001234563",
"location": "55.779905316526424,49.12446113769528 Республика Татарстан (Татарстан),н Казань, ул. Баумана, 1", "location": "Казань, ул. Баумана, 1",
"master": "4545423234", "master": {
"name": "Олег Макаров",
"phone": "79001234567",
"id": "23423442"
},
"notes": "" "notes": ""
}, },
{ {
@ -21,7 +25,7 @@
"orderDate": "2024-11-24T07:40:46.366Z", "orderDate": "2024-11-24T07:40:46.366Z",
"status": "progress", "status": "progress",
"phone": "79001234567", "phone": "79001234567",
"location": "55.779905316526424,49.12446113769528 Республика Татарстан (Татарстан), Казань, озеро Нижний Кабан", "location": "Казань, ул. Баумана, 43",
"master": [], "master": [],
"notes": "" "notes": ""
} }