Compare commits
No commits in common. "48d076a829636f9e71d507c9f1f3e4cea1d18373" and "6705e74ece0a31613f8cae9da4c0058f5dde4b44" have entirely different histories.
48d076a829
...
6705e74ece
@ -24,6 +24,6 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
'dry-wash.api': '/api',
|
'dry-wash-pl.api': '/api',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
"dry-wash.landing.social-proof-section.heading": "We are being chosen",
|
"dry-wash.landing.social-proof-section.heading": "We are being chosen",
|
||||||
"dry-wash.arm.master.add": "Add",
|
"dry-wash.arm.master.add": "Add",
|
||||||
"dry-wash.arm.order.title": "Orders",
|
"dry-wash.arm.order.title": "Orders",
|
||||||
"dry-wash.arm.order.table.empty": "Table empty",
|
|
||||||
"dry-wash.arm.order.error.title": "Error loading data",
|
|
||||||
"dry-wash.arm.order.status.progress": "In Progress",
|
"dry-wash.arm.order.status.progress": "In Progress",
|
||||||
"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",
|
||||||
@ -32,8 +30,6 @@
|
|||||||
"dry-wash.arm.order.table.header.location": "Location",
|
"dry-wash.arm.order.table.header.location": "Location",
|
||||||
"dry-wash.arm.master.title": "Masters",
|
"dry-wash.arm.master.title": "Masters",
|
||||||
"dry-wash.arm.master.table.header.name": "Name",
|
"dry-wash.arm.master.table.header.name": "Name",
|
||||||
"dry-wash.arm.master.table.empty": "Table empty",
|
|
||||||
"dry-wash.arm.master.error.title": "Error loading data",
|
|
||||||
"dry-wash.arm.master.table.header.currentJob": "Current Job",
|
"dry-wash.arm.master.table.header.currentJob": "Current Job",
|
||||||
"dry-wash.arm.master.table.header.phone": "Phone",
|
"dry-wash.arm.master.table.header.phone": "Phone",
|
||||||
"dry-wash.arm.master.table.header.actions": "Actions",
|
"dry-wash.arm.master.table.header.actions": "Actions",
|
||||||
|
@ -13,11 +13,7 @@
|
|||||||
"dry-wash.arm.order.table.header.status": "Статус",
|
"dry-wash.arm.order.table.header.status": "Статус",
|
||||||
"dry-wash.arm.order.table.header.telephone": "Телефон",
|
"dry-wash.arm.order.table.header.telephone": "Телефон",
|
||||||
"dry-wash.arm.order.table.header.location": "Расположение",
|
"dry-wash.arm.order.table.header.location": "Расположение",
|
||||||
"dry-wash.arm.order.table.empty": "Список пуст",
|
|
||||||
"dry-wash.arm.order.error.title": "Ошибка при загрузке данных",
|
|
||||||
"dry-wash.arm.master.title": "Мастера",
|
"dry-wash.arm.master.title": "Мастера",
|
||||||
"dry-wash.arm.master.table.empty": "Список пуст",
|
|
||||||
"dry-wash.arm.master.error.title": "Ошибка при загрузке данных",
|
|
||||||
"dry-wash.arm.master.table.header.name": "Имя",
|
"dry-wash.arm.master.table.header.name": "Имя",
|
||||||
"dry-wash.arm.master.table.header.currentJob": "Актуальная занятость",
|
"dry-wash.arm.master.table.header.currentJob": "Актуальная занятость",
|
||||||
"dry-wash.arm.master.table.header.phone": "Телефон",
|
"dry-wash.arm.master.table.header.phone": "Телефон",
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
import { getConfigValue } from '@brojs/cli';
|
|
||||||
|
|
||||||
enum ArmEndpoints {
|
|
||||||
ORDERS = '/arm/orders',
|
|
||||||
MASTERS = '/arm/masters',
|
|
||||||
}
|
|
||||||
|
|
||||||
const armService = () => {
|
|
||||||
const endpoint = getConfigValue('dry-wash.api');
|
|
||||||
|
|
||||||
const fetchOrders = async () => {
|
|
||||||
const response = await fetch(`${endpoint}${ArmEndpoints.ORDERS}`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to fetch orders: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await response.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchMasters = async () => {
|
|
||||||
const response = await fetch(`${endpoint}${ArmEndpoints.MASTERS}`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to fetch masters: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await response.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
return { fetchOrders, fetchMasters };
|
|
||||||
};
|
|
||||||
|
|
||||||
export { armService, ArmEndpoints };
|
|
@ -4,19 +4,6 @@ import { Badge, Link, Stack, Td, Tr } from '@chakra-ui/react';
|
|||||||
import MasterActionsMenu from '../MasterActionsMenu';
|
import MasterActionsMenu from '../MasterActionsMenu';
|
||||||
import { getTimeSlot } from '../../lib/date-helpers';
|
import { getTimeSlot } from '../../lib/date-helpers';
|
||||||
|
|
||||||
export interface Schedule {
|
|
||||||
id: string;
|
|
||||||
startWashTime: string;
|
|
||||||
endWashTime: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type MasterProps = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
schedule: Schedule[];
|
|
||||||
phone: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const MasterItem = ({ name, schedule, phone }) => {
|
const MasterItem = ({ name, schedule, phone }) => {
|
||||||
return (
|
return (
|
||||||
<Tr>
|
<Tr>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Heading,
|
Heading,
|
||||||
@ -10,17 +10,12 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
Flex,
|
Flex,
|
||||||
useToast,
|
|
||||||
Td,
|
|
||||||
Text,
|
|
||||||
Spinner,
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import MasterItem from '../MasterItem';
|
import MasterItem from '../MasterItem';
|
||||||
import MasterDrawer from '../MasterDrawer';
|
import MasterDrawer from '../MasterDrawer';
|
||||||
import { armService } from '../../api/arm';
|
import data from '../../../stubs/json/arm-masters/success.json';
|
||||||
import { MasterProps } from '../MasterItem/MasterItem';
|
|
||||||
|
|
||||||
const TABLE_HEADERS = [
|
const TABLE_HEADERS = [
|
||||||
'name' as const,
|
'name' as const,
|
||||||
@ -31,41 +26,11 @@ const TABLE_HEADERS = [
|
|||||||
|
|
||||||
const Masters = () => {
|
const Masters = () => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const toast = useToast();
|
|
||||||
const { t } = useTranslation('~', {
|
const { t } = useTranslation('~', {
|
||||||
keyPrefix: 'dry-wash.arm.master',
|
keyPrefix: 'dry-wash.arm.master',
|
||||||
});
|
});
|
||||||
|
|
||||||
const [masters, setMasters] = useState<MasterProps[]>([]);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
|
|
||||||
const { fetchMasters } = armService();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const loadMasters = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = await fetchMasters();
|
|
||||||
setMasters(data.body);
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.message);
|
|
||||||
toast({
|
|
||||||
title: t('error.title'),
|
|
||||||
status: 'error',
|
|
||||||
duration: 5000,
|
|
||||||
isClosable: true,
|
|
||||||
position: 'bottom-right',
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
loadMasters();
|
|
||||||
}, [toast, t]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box p='8'>
|
<Box p='8'>
|
||||||
<Flex justifyContent='space-between' alignItems='center' mb='5'>
|
<Flex justifyContent='space-between' alignItems='center' mb='5'>
|
||||||
@ -83,25 +48,9 @@ const Masters = () => {
|
|||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody>
|
||||||
{loading && (
|
{data.body.map((master, index) => (
|
||||||
<Tr>
|
<MasterItem key={index} {...master} />
|
||||||
<Td colSpan={TABLE_HEADERS.length} textAlign='center' py='8'>
|
))}
|
||||||
<Spinner size='lg' />
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
)}
|
|
||||||
{!loading && masters.length === 0 && !error && (
|
|
||||||
<Tr>
|
|
||||||
<Td colSpan={TABLE_HEADERS.length}>
|
|
||||||
<Text>{t('table.empty')}</Text>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
)}
|
|
||||||
{!loading &&
|
|
||||||
!error &&
|
|
||||||
masters.map((master, index) => (
|
|
||||||
<MasterItem key={index} {...master} />
|
|
||||||
))}
|
|
||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
<MasterDrawer isOpen={isOpen} onClose={onClose} />
|
<MasterDrawer isOpen={isOpen} onClose={onClose} />
|
||||||
|
@ -1,68 +1,24 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import {
|
import { Box, Heading, Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react';
|
||||||
Box,
|
|
||||||
Heading,
|
|
||||||
Table,
|
|
||||||
Thead,
|
|
||||||
Tbody,
|
|
||||||
Tr,
|
|
||||||
Th,
|
|
||||||
Spinner,
|
|
||||||
Text,
|
|
||||||
Td,
|
|
||||||
useToast,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import OrderItem from '../OrderItem';
|
import OrderItem from '../OrderItem';
|
||||||
import { OrderProps } from '../OrderItem/OrderItem';
|
import { OrderProps } from '../OrderItem/OrderItem';
|
||||||
import { armService } from '../../api/arm';
|
import data from '../../../stubs/json/arm-orders/success.json';
|
||||||
|
|
||||||
const TABLE_HEADERS = [
|
|
||||||
'carNumber' as const,
|
|
||||||
'washingTime' as const,
|
|
||||||
'orderDate' as const,
|
|
||||||
'status' as const,
|
|
||||||
'telephone' as const,
|
|
||||||
'location' as const,
|
|
||||||
];
|
|
||||||
|
|
||||||
const Orders = () => {
|
const Orders = () => {
|
||||||
const { t } = useTranslation('~', {
|
const { t } = useTranslation('~', {
|
||||||
keyPrefix: 'dry-wash.arm.order',
|
keyPrefix: 'dry-wash.arm.order',
|
||||||
});
|
});
|
||||||
|
|
||||||
const { fetchOrders } = armService();
|
const TABLE_HEADERS = [
|
||||||
|
'carNumber' as const,
|
||||||
const toast = useToast();
|
'washingTime' as const,
|
||||||
|
'orderDate' as const,
|
||||||
const [orders, setOrders] = useState<OrderProps[]>([]);
|
'status' as const,
|
||||||
const [loading, setLoading] = useState(false);
|
'telephone' as const,
|
||||||
const [error, setError] = useState<string | null>(null);
|
'location' as const,
|
||||||
|
];
|
||||||
useEffect(() => {
|
|
||||||
const loadOrders = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = await fetchOrders();
|
|
||||||
setOrders(data.body);
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.message);
|
|
||||||
toast({
|
|
||||||
title: t('error.title'),
|
|
||||||
status: 'error',
|
|
||||||
duration: 5000,
|
|
||||||
isClosable: true,
|
|
||||||
position: 'bottom-right',
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
loadOrders();
|
|
||||||
}, [toast, t]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box p='8'>
|
<Box p='8'>
|
||||||
@ -78,29 +34,13 @@ const Orders = () => {
|
|||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody>
|
||||||
{loading && (
|
{data.body.map((order, index) => (
|
||||||
<Tr>
|
<OrderItem
|
||||||
<Td colSpan={TABLE_HEADERS.length} textAlign='center' py='8'>
|
key={index}
|
||||||
<Spinner size='lg' />
|
{...order}
|
||||||
</Td>
|
status={order.status as OrderProps['status']}
|
||||||
</Tr>
|
/>
|
||||||
)}
|
))}
|
||||||
{!loading && orders.length === 0 && !error && (
|
|
||||||
<Tr>
|
|
||||||
<Td colSpan={TABLE_HEADERS.length}>
|
|
||||||
<Text>{t('table.empty')}</Text>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
)}
|
|
||||||
{!loading &&
|
|
||||||
!error &&
|
|
||||||
orders.map((order, index) => (
|
|
||||||
<OrderItem
|
|
||||||
key={index}
|
|
||||||
{...order}
|
|
||||||
status={order.status as OrderProps['status']}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
/* eslint-disable no-undef */
|
|
||||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
||||||
const router = require('express').Router();
|
|
||||||
|
|
||||||
const STUBS = { masters: 'success', orders: 'success' };
|
|
||||||
|
|
||||||
router.get('/set/:name/:value', (req, res) => {
|
|
||||||
const { name, value } = req.params;
|
|
||||||
|
|
||||||
STUBS[name] = value;
|
|
||||||
|
|
||||||
res.send('ok');
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/', (req, res) => {
|
|
||||||
res.send(`<div>
|
|
||||||
<fieldset>
|
|
||||||
<legend>Мастера</legend>
|
|
||||||
${generateRadioInput('masters', 'success')}
|
|
||||||
${generateRadioInput('masters', 'error')}
|
|
||||||
</fieldset>
|
|
||||||
<fieldset>
|
|
||||||
<legend>Заказы</legend>
|
|
||||||
${generateRadioInput('orders', 'success')}
|
|
||||||
${generateRadioInput('orders', 'error')}
|
|
||||||
</fieldset>
|
|
||||||
</div>`);
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
module.exports.STUBS = STUBS;
|
|
||||||
|
|
||||||
function generateRadioInput(name, type) {
|
|
||||||
return `<label>
|
|
||||||
<input ${STUBS[name] === type ? 'checked' : ''} onclick="fetch('/api/admin/set/${name}/${type}')" type="radio" name="${name}">
|
|
||||||
${type}
|
|
||||||
</label>`;
|
|
||||||
}
|
|
@ -2,37 +2,4 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
const router = require('express').Router();
|
const router = require('express').Router();
|
||||||
|
|
||||||
const STUBS = require('./admin').STUBS;
|
|
||||||
|
|
||||||
const commonError = { success: false, message: 'Что-то пошло не так' };
|
|
||||||
|
|
||||||
const sleep =
|
|
||||||
(duration = 1000) =>
|
|
||||||
(req, res, next) =>
|
|
||||||
setTimeout(next, duration);
|
|
||||||
|
|
||||||
router.use(sleep());
|
|
||||||
|
|
||||||
router.get('/arm/masters', (req, res) => {
|
|
||||||
res
|
|
||||||
.status(/error/.test(STUBS.masters) ? 500 : 200)
|
|
||||||
.send(
|
|
||||||
/^error$/.test(STUBS.masters)
|
|
||||||
? commonError
|
|
||||||
: require(`../json/arm-masters/${STUBS.masters}.json`),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/arm/orders', (req, res) => {
|
|
||||||
res
|
|
||||||
.status(/error/.test(STUBS.orders) ? 500 : 200)
|
|
||||||
.send(
|
|
||||||
/^error$/.test(STUBS.orders)
|
|
||||||
? commonError
|
|
||||||
: require(`../json/arm-orders/${STUBS.orders}.json`),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.use('/admin', require('./admin'));
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
Loading…
Reference in New Issue
Block a user