Compare commits

..

No commits in common. "48d076a829636f9e71d507c9f1f3e4cea1d18373" and "6705e74ece0a31613f8cae9da4c0058f5dde4b44" have entirely different histories.

9 changed files with 25 additions and 262 deletions

View File

@ -24,6 +24,6 @@ module.exports = {
},
},
config: {
'dry-wash.api': '/api',
'dry-wash-pl.api': '/api',
},
};

View File

@ -16,8 +16,6 @@
"dry-wash.landing.social-proof-section.heading": "We are being chosen",
"dry-wash.arm.master.add": "Add",
"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.complete": "Completed",
"dry-wash.arm.order.status.pending": "Pending",
@ -32,8 +30,6 @@
"dry-wash.arm.order.table.header.location": "Location",
"dry-wash.arm.master.title": "Masters",
"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.phone": "Phone",
"dry-wash.arm.master.table.header.actions": "Actions",

View File

@ -13,11 +13,7 @@
"dry-wash.arm.order.table.header.status": "Статус",
"dry-wash.arm.order.table.header.telephone": "Телефон",
"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.table.empty": "Список пуст",
"dry-wash.arm.master.error.title": "Ошибка при загрузке данных",
"dry-wash.arm.master.table.header.name": "Имя",
"dry-wash.arm.master.table.header.currentJob": "Актуальная занятость",
"dry-wash.arm.master.table.header.phone": "Телефон",

View File

@ -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 };

View File

@ -4,19 +4,6 @@ import { Badge, Link, Stack, Td, Tr } from '@chakra-ui/react';
import MasterActionsMenu from '../MasterActionsMenu';
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 }) => {
return (
<Tr>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import {
Box,
Heading,
@ -10,17 +10,12 @@ import {
Button,
useDisclosure,
Flex,
useToast,
Td,
Text,
Spinner,
} from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import MasterItem from '../MasterItem';
import MasterDrawer from '../MasterDrawer';
import { armService } from '../../api/arm';
import { MasterProps } from '../MasterItem/MasterItem';
import data from '../../../stubs/json/arm-masters/success.json';
const TABLE_HEADERS = [
'name' as const,
@ -31,41 +26,11 @@ const TABLE_HEADERS = [
const Masters = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const toast = useToast();
const { t } = useTranslation('~', {
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 (
<Box p='8'>
<Flex justifyContent='space-between' alignItems='center' mb='5'>
@ -83,23 +48,7 @@ const Masters = () => {
</Tr>
</Thead>
<Tbody>
{loading && (
<Tr>
<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) => (
{data.body.map((master, index) => (
<MasterItem key={index} {...master} />
))}
</Tbody>

View File

@ -1,68 +1,24 @@
import React, { useEffect, useState } from 'react';
import {
Box,
Heading,
Table,
Thead,
Tbody,
Tr,
Th,
Spinner,
Text,
Td,
useToast,
} from '@chakra-ui/react';
import React from 'react';
import { Box, Heading, Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import OrderItem from '../OrderItem';
import { OrderProps } from '../OrderItem/OrderItem';
import { armService } from '../../api/arm';
const TABLE_HEADERS = [
'carNumber' as const,
'washingTime' as const,
'orderDate' as const,
'status' as const,
'telephone' as const,
'location' as const,
];
import data from '../../../stubs/json/arm-orders/success.json';
const Orders = () => {
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.order',
});
const { fetchOrders } = armService();
const toast = useToast();
const [orders, setOrders] = useState<OrderProps[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
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]);
const TABLE_HEADERS = [
'carNumber' as const,
'washingTime' as const,
'orderDate' as const,
'status' as const,
'telephone' as const,
'location' as const,
];
return (
<Box p='8'>
@ -78,23 +34,7 @@ const Orders = () => {
</Tr>
</Thead>
<Tbody>
{loading && (
<Tr>
<Td colSpan={TABLE_HEADERS.length} textAlign='center' py='8'>
<Spinner size='lg' />
</Td>
</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) => (
{data.body.map((order, index) => (
<OrderItem
key={index}
{...order}

View File

@ -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>`;
}

View File

@ -2,37 +2,4 @@
/* eslint-disable @typescript-eslint/no-require-imports */
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;