From 5ef0d5953dab7c2c6a6544c154098f32aa4ba251 Mon Sep 17 00:00:00 2001
From: ilnaz <237x237@gmail.com>
Date: Sun, 1 Dec 2024 11:51:52 +0300
Subject: [PATCH 1/4] feat: add stub admin (#43)
---
stubs/api/index.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/stubs/api/index.js b/stubs/api/index.js
index 4a9e3a7..6a7dc94 100644
--- a/stubs/api/index.js
+++ b/stubs/api/index.js
@@ -2,4 +2,63 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const router = require('express').Router();
+const commonError = { success: false, message: 'Что то пошло не так' };
+
+const stubs = { masters: 'success', orders: 'success' };
+
+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.get('/admin', (req, res) => {
+ res.send(`
+
+
+`);
+});
+
+router.get('/admin/set/:name/:value', (req, res) => {
+ const { name, value } = req.params;
+
+ stubs[name] = value;
+
+ res.send('ok');
+});
+
module.exports = router;
--
2.45.2
From 7c157574c87429ea88fcd246a0e9b11104d61a27 Mon Sep 17 00:00:00 2001
From: RustamRu
Date: Sun, 1 Dec 2024 12:17:04 +0300
Subject: [PATCH 2/4] feat: extract admin (#43)
---
stubs/api/admin.js | 38 +++++++++++++++++++++++++++++++
stubs/api/index.js | 57 ++++++++++++----------------------------------
2 files changed, 52 insertions(+), 43 deletions(-)
create mode 100644 stubs/api/admin.js
diff --git a/stubs/api/admin.js b/stubs/api/admin.js
new file mode 100644
index 0000000..e8c5a07
--- /dev/null
+++ b/stubs/api/admin.js
@@ -0,0 +1,38 @@
+/* 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(`
+
+
+`);
+});
+
+module.exports = router;
+module.exports.STUBS = STUBS;
+
+function generateRadioInput(name, type) {
+ return ``;
+}
\ No newline at end of file
diff --git a/stubs/api/index.js b/stubs/api/index.js
index 6a7dc94..22ac104 100644
--- a/stubs/api/index.js
+++ b/stubs/api/index.js
@@ -2,63 +2,34 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const router = require('express').Router();
-const commonError = { success: false, message: 'Что то пошло не так' };
+const STUBS = require('./admin').STUBS;
-const stubs = { masters: 'success', orders: 'success' };
+const commonError = { success: false, message: 'Что-то пошло не так' };
+
+const sleep = (duration = 300) => (req, res, next) => setTimeout(next, duration);
+
+router.use(sleep());
router.get('/arm/masters', (req, res) => {
res
- .status(/error/.test(stubs.masters) ? 500 : 200)
+ .status(/error/.test(STUBS.masters) ? 500 : 200)
.send(
- /^error$/.test(stubs.masters)
+ /^error$/.test(STUBS.masters)
? commonError
- : require(`../json/arm-masters/${stubs.masters}.json`),
+ : require(`../json/arm-masters/${STUBS.masters}.json`),
);
});
router.get('/arm/orders', (req, res) => {
res
- .status(/error/.test(stubs.orders) ? 500 : 200)
+ .status(/error/.test(STUBS.orders) ? 500 : 200)
.send(
- /^error$/.test(stubs.orders)
+ /^error$/.test(STUBS.orders)
? commonError
- : require(`../json/arm-orders/${stubs.orders}.json`),
+ : require(`../json/arm-orders/${STUBS.orders}.json`),
);
});
-router.get('/admin', (req, res) => {
- res.send(`
-
-
-`);
-});
+router.use('/admin', require('./admin'));
-router.get('/admin/set/:name/:value', (req, res) => {
- const { name, value } = req.params;
-
- stubs[name] = value;
-
- res.send('ok');
-});
-
-module.exports = router;
+module.exports = router;
\ No newline at end of file
--
2.45.2
From 0b2dae79ac328cbc7ab6379b7eb37d6848b47cfb Mon Sep 17 00:00:00 2001
From: ilnaz <237x237@gmail.com>
Date: Sat, 7 Dec 2024 23:40:22 +0300
Subject: [PATCH 3/4] feat: add stub fetch admin (#44)
---
bro.config.js | 2 +-
locales/en.json | 4 +
locales/ru.json | 4 +
src/api/arm.ts | 34 +++++++++
src/components/MasterItem/MasterItem.tsx | 13 ++++
src/components/Masters/Masters.tsx | 63 ++++++++++++++--
src/components/Orders/Orders.tsx | 96 +++++++++++++++++++-----
stubs/api/index.js | 7 +-
8 files changed, 196 insertions(+), 27 deletions(-)
create mode 100644 src/api/arm.ts
diff --git a/bro.config.js b/bro.config.js
index f12638a..5cb04ae 100644
--- a/bro.config.js
+++ b/bro.config.js
@@ -24,6 +24,6 @@ module.exports = {
},
},
config: {
- 'dry-wash-pl.api': '/api',
+ 'dry-wash.api': '/api',
},
};
diff --git a/locales/en.json b/locales/en.json
index 5820580..35e36a8 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -16,6 +16,8 @@
"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",
@@ -30,6 +32,8 @@
"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",
diff --git a/locales/ru.json b/locales/ru.json
index 5c9d91c..fc04889 100644
--- a/locales/ru.json
+++ b/locales/ru.json
@@ -13,7 +13,11 @@
"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": "Телефон",
diff --git a/src/api/arm.ts b/src/api/arm.ts
new file mode 100644
index 0000000..534440d
--- /dev/null
+++ b/src/api/arm.ts
@@ -0,0 +1,34 @@
+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 };
diff --git a/src/components/MasterItem/MasterItem.tsx b/src/components/MasterItem/MasterItem.tsx
index 9895d29..825d621 100644
--- a/src/components/MasterItem/MasterItem.tsx
+++ b/src/components/MasterItem/MasterItem.tsx
@@ -4,6 +4,19 @@ 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 (
diff --git a/src/components/Masters/Masters.tsx b/src/components/Masters/Masters.tsx
index ea07603..7846fc8 100644
--- a/src/components/Masters/Masters.tsx
+++ b/src/components/Masters/Masters.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
import {
Box,
Heading,
@@ -10,12 +10,17 @@ 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 data from '../../../stubs/json/arm-masters/success.json';
+import { armService } from '../../api/arm';
+import { MasterProps } from '../MasterItem/MasterItem';
const TABLE_HEADERS = [
'name' as const,
@@ -26,11 +31,41 @@ 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([]);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(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 (
@@ -48,9 +83,25 @@ const Masters = () => {
- {data.body.map((master, index) => (
-
- ))}
+ {loading && (
+
+
+
+ |
+
+ )}
+ {!loading && masters.length === 0 && !error && (
+
+
+ {t('table.empty')}
+ |
+
+ )}
+ {!loading &&
+ !error &&
+ masters.map((master, index) => (
+
+ ))}
diff --git a/src/components/Orders/Orders.tsx b/src/components/Orders/Orders.tsx
index 10831e7..e2dd6bc 100644
--- a/src/components/Orders/Orders.tsx
+++ b/src/components/Orders/Orders.tsx
@@ -1,24 +1,68 @@
-import React from 'react';
-import { Box, Heading, Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react';
+import React, { useEffect, useState } from 'react';
+import {
+ Box,
+ Heading,
+ Table,
+ Thead,
+ Tbody,
+ Tr,
+ Th,
+ Spinner,
+ Text,
+ Td,
+ useToast,
+} from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import OrderItem from '../OrderItem';
import { OrderProps } from '../OrderItem/OrderItem';
-import data from '../../../stubs/json/arm-orders/success.json';
+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,
+];
const Orders = () => {
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.order',
});
- const TABLE_HEADERS = [
- 'carNumber' as const,
- 'washingTime' as const,
- 'orderDate' as const,
- 'status' as const,
- 'telephone' as const,
- 'location' as const,
- ];
+ const { fetchOrders } = armService();
+
+ const toast = useToast();
+
+ const [orders, setOrders] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(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]);
return (
@@ -34,13 +78,29 @@ const Orders = () => {
- {data.body.map((order, index) => (
-
- ))}
+ {loading && (
+
+
+
+ |
+
+ )}
+ {!loading && orders.length === 0 && !error && (
+
+
+ {t('table.empty')}
+ |
+
+ )}
+ {!loading &&
+ !error &&
+ orders.map((order, index) => (
+
+ ))}
diff --git a/stubs/api/index.js b/stubs/api/index.js
index 22ac104..b4df477 100644
--- a/stubs/api/index.js
+++ b/stubs/api/index.js
@@ -6,7 +6,10 @@ const STUBS = require('./admin').STUBS;
const commonError = { success: false, message: 'Что-то пошло не так' };
-const sleep = (duration = 300) => (req, res, next) => setTimeout(next, duration);
+const sleep =
+ (duration = 1000) =>
+ (req, res, next) =>
+ setTimeout(next, duration);
router.use(sleep());
@@ -32,4 +35,4 @@ router.get('/arm/orders', (req, res) => {
router.use('/admin', require('./admin'));
-module.exports = router;
\ No newline at end of file
+module.exports = router;
--
2.45.2
From e4b9aefe57fc03a1cbdaa1a5796339c463b06256 Mon Sep 17 00:00:00 2001
From: ilnaz <237x237@gmail.com>
Date: Sun, 8 Dec 2024 11:00:43 +0300
Subject: [PATCH 4/4] fix: add spaces
---
stubs/api/index.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/stubs/api/index.js b/stubs/api/index.js
index b4df477..8fe4716 100644
--- a/stubs/api/index.js
+++ b/stubs/api/index.js
@@ -8,8 +8,8 @@ const commonError = { success: false, message: 'Что-то пошло не та
const sleep =
(duration = 1000) =>
- (req, res, next) =>
- setTimeout(next, duration);
+ (req, res, next) =>
+ setTimeout(next, duration);
router.use(sleep());
--
2.45.2