feat: change sidebar to header, fix wizard update, delete unnecessary statuses #91

Open
237x237 wants to merge 17 commits from fix/arm-orders into main
12 changed files with 111 additions and 83 deletions
Showing only changes of commit d312445bf2 - Show all commits

View File

@ -58,7 +58,7 @@
"dry-wash.arm.order.status.complete": "Completed",
"dry-wash.arm.order.status.pending": "Pending",
"dry-wash.arm.order.status.working": "Working",
"dry-wash.arm.order.status.canceled": "Canceled",
"dry-wash.arm.order.status.cancelled": "Canceled",
"dry-wash.arm.order.status.placeholder": "Select status",
"dry-wash.arm.order.master.placeholder": "Select master",
"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.pending": "В ожидании",
"dry-wash.arm.order.status.working": "В работе",
"dry-wash.arm.order.status.canceled": "Отменено",
"dry-wash.arm.order.status.cancelled": "Отменено",
"dry-wash.arm.order.status.placeholder": "Выберите статус",
"dry-wash.arm.order.master.placeholder": "Выберите мастера",
"dry-wash.arm.order.table.header.carNumber": "Номер машины",

View File

@ -0,0 +1,51 @@
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

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

View File

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

View File

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

View File

@ -0,0 +1,35 @@
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

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

View File

@ -1,61 +0,0 @@
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

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

View File

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

View File

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