Compare commits
No commits in common. "main" and "feature/landing-tests" have entirely different histories.
main
...
feature/la
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"i18n-ally.localesPaths": [
|
|
||||||
"locales"
|
|
||||||
]
|
|
||||||
}
|
|
32
Jenkinsfile
vendored
32
Jenkinsfile
vendored
@ -1,7 +1,7 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
image 'node:22'
|
image 'node:20'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,21 +30,25 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('eslint') {
|
stage('checks') {
|
||||||
steps {
|
parallel {
|
||||||
sh 'npm run eslint'
|
stage('eslint') {
|
||||||
}
|
steps {
|
||||||
}
|
sh 'npm run eslint'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('test') {
|
stage('test') {
|
||||||
steps {
|
steps {
|
||||||
sh 'npm run test'
|
sh 'npm run test'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('build') {
|
stage('build') {
|
||||||
steps {
|
steps {
|
||||||
sh 'npm run build'
|
sh 'npm run build'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,18 +19,9 @@ module.exports = {
|
|||||||
'dry-wash.arm': '/arm/*',
|
'dry-wash.arm': '/arm/*',
|
||||||
},
|
},
|
||||||
features: {
|
features: {
|
||||||
'dry-wash': {
|
'dry-wash-pl': {
|
||||||
// add your features here in the format [featureName]: { value: string }
|
// add your features here in the format [featureName]: { value: string }
|
||||||
"order-view-status-polling": {
|
'order-view-status-polling': { value: '3000' }
|
||||||
"on": true,
|
|
||||||
"value": "3000",
|
|
||||||
"key": "order-view-status-polling"
|
|
||||||
},
|
|
||||||
"car-img-upload": {
|
|
||||||
"on": true,
|
|
||||||
"value": "true",
|
|
||||||
"key": "car-img-upload"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
|
@ -6,7 +6,7 @@ test.beforeEach('check server is up', async ({ page }) => {
|
|||||||
const makeOrderText = page.getByText('Сделать заказ', { exact: true });
|
const makeOrderText = page.getByText('Сделать заказ', { exact: true });
|
||||||
await expect(makeOrderText).toBeVisible();
|
await expect(makeOrderText).toBeVisible();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('server not up', error);
|
console.error('server not up');
|
||||||
test.skip();
|
test.skip();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -50,12 +50,6 @@
|
|||||||
"dry-wash.order-view.details.location": "Where",
|
"dry-wash.order-view.details.location": "Where",
|
||||||
"dry-wash.order-view.details.datetime-range": "When",
|
"dry-wash.order-view.details.datetime-range": "When",
|
||||||
"dry-wash.order-view.details.alert": "The operator will contact you about the payment at the specified phone number",
|
"dry-wash.order-view.details.alert": "The operator will contact you about the payment at the specified phone number",
|
||||||
"dry-wash.order-view.upload-car-image.field.label": "Upload a photo of your car, and our service will quickly calculate the pre-order price!",
|
|
||||||
"dry-wash.order-view.upload-car-image.field.help": "Allowed formats: .jpg, .png. Maximum size: 5MB",
|
|
||||||
"dry-wash.order-view.upload-car-image.file-input.placeholder": "Upload a file",
|
|
||||||
"dry-wash.order-view.upload-car-image.file-input.button": "Upload",
|
|
||||||
"dry-wash.order-view.upload-car-image-query.success.title": "The car image is successfully uploaded",
|
|
||||||
"dry-wash.order-view.upload-car-image-query.error.title": "Failed to upload the car image",
|
|
||||||
"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.table.empty": "Table empty",
|
||||||
|
@ -105,12 +105,6 @@
|
|||||||
"dry-wash.order-view.details.location": "Где",
|
"dry-wash.order-view.details.location": "Где",
|
||||||
"dry-wash.order-view.details.datetime-range": "Когда",
|
"dry-wash.order-view.details.datetime-range": "Когда",
|
||||||
"dry-wash.order-view.details.alert": "С вами свяжется оператор насчет оплаты по указанному номеру телефона",
|
"dry-wash.order-view.details.alert": "С вами свяжется оператор насчет оплаты по указанному номеру телефона",
|
||||||
"dry-wash.order-view.upload-car-image.field.label": "Загрузите фото вашего автомобиля, и наш сервис быстро рассчитает предварительную стоимость заказа!",
|
|
||||||
"dry-wash.order-view.upload-car-image.field.help": "Допустимые форматы: .jpg, .png. Максимальный размер: 5МБ",
|
|
||||||
"dry-wash.order-view.upload-car-image.file-input.placeholder": "Загрузите файл",
|
|
||||||
"dry-wash.order-view.upload-car-image.file-input.button": "Загрузить",
|
|
||||||
"dry-wash.order-view.upload-car-image-query.success.title": "Изображение автомобиля успешно загружено",
|
|
||||||
"dry-wash.order-view.upload-car-image-query.error.title": "Не удалось загрузить изображение автомобиля",
|
|
||||||
"dry-wash.notFound.title": "Страница не найдена",
|
"dry-wash.notFound.title": "Страница не найдена",
|
||||||
"dry-wash.notFound.description": "К сожалению, запрашиваемая вами страница не существует.",
|
"dry-wash.notFound.description": "К сожалению, запрашиваемая вами страница не существует.",
|
||||||
"dry-wash.notFound.button.back": "Вернуться на главную",
|
"dry-wash.notFound.button.back": "Вернуться на главную",
|
||||||
|
24
package-lock.json
generated
24
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "dry-wash",
|
"name": "dry-wash",
|
||||||
"version": "0.9.1",
|
"version": "0.7.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "dry-wash",
|
"name": "dry-wash",
|
||||||
"version": "0.9.1",
|
"version": "0.7.2",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.26.7",
|
"@babel/core": "^7.26.7",
|
||||||
@ -68,7 +68,8 @@
|
|||||||
"version": "4.4.2",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz",
|
||||||
"integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==",
|
"integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
@ -3829,6 +3830,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz",
|
||||||
"integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==",
|
"integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adobe/css-tools": "^4.4.0",
|
"@adobe/css-tools": "^4.4.0",
|
||||||
"aria-query": "^5.0.0",
|
"aria-query": "^5.0.0",
|
||||||
@ -3849,6 +3851,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
},
|
},
|
||||||
@ -3864,6 +3867,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": "^4.1.0",
|
"ansi-styles": "^4.1.0",
|
||||||
"supports-color": "^7.1.0"
|
"supports-color": "^7.1.0"
|
||||||
@ -3876,13 +3880,15 @@
|
|||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
|
||||||
"integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
|
"integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@testing-library/jest-dom/node_modules/supports-color": {
|
"node_modules/@testing-library/jest-dom/node_modules/supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
},
|
},
|
||||||
@ -6080,7 +6086,8 @@
|
|||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
|
||||||
"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
|
"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@ -8816,6 +8823,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -11405,7 +11413,8 @@
|
|||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/lodash.debounce": {
|
"node_modules/lodash.debounce": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.8",
|
||||||
@ -11602,6 +11611,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
@ -13165,6 +13175,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
|
||||||
"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
|
"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"indent-string": "^4.0.0",
|
"indent-string": "^4.0.0",
|
||||||
"strip-indent": "^3.0.0"
|
"strip-indent": "^3.0.0"
|
||||||
@ -13982,6 +13993,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||||
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"min-indent": "^1.0.0"
|
"min-indent": "^1.0.0"
|
||||||
},
|
},
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "dry-wash",
|
"name": "dry-wash",
|
||||||
"version": "0.9.1",
|
"version": "0.7.2",
|
||||||
"description": "<a id=\"readme-top\"></a>",
|
"description": "<a id=\"readme-top\"></a>",
|
||||||
"main": "./src/index.tsx",
|
"main": "./src/index.tsx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest -u",
|
"test": "jest",
|
||||||
"start": "brojs server --port=8099 --with-open-browser",
|
"start": "brojs server --port=8099 --with-open-browser",
|
||||||
"build": "npm run clean && brojs build --dev",
|
"build": "npm run clean && brojs build --dev",
|
||||||
"build:prod": "npm run clean && brojs build",
|
"build:prod": "npm run clean && brojs build",
|
||||||
"clean": "rimraf dist",
|
"clean": "rimraf dist",
|
||||||
"eslint": "npx eslint src",
|
"eslint": "npx eslint .",
|
||||||
"eslint:fix": "npx eslint src --fix",
|
"eslint:fix": "npx eslint . --fix",
|
||||||
"preversion": "npm run eslint"
|
"preversion": "npm run eslint"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
import { getFeatures } from "@brojs/cli";
|
import { getFeatures } from "@brojs/cli";
|
||||||
|
|
||||||
const features = getFeatures('dry-wash');
|
const features = getFeatures('dry-wash-pl');
|
||||||
|
|
||||||
export const FEATURE = {
|
export const FEATURE = {
|
||||||
orderViewStatusPolling: {
|
orderViewStatusPolling: {
|
||||||
isOn: Boolean(features?.['order-view-status-polling']),
|
isOn: Boolean(features['order-view-status-polling']),
|
||||||
getValue: () => {
|
getValue: () => {
|
||||||
const interval = parseInt(features?.['order-view-status-polling']?.value);
|
const interval = parseInt(features['order-view-status-polling'].value);
|
||||||
if (!Number.isNaN(interval)) {
|
if (!Number.isNaN(interval)) {
|
||||||
return interval;
|
return interval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
carImageUpload: {
|
|
||||||
isOn: Boolean(features?.['car-img-upload'])
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,4 +1,4 @@
|
|||||||
import { GetOrder, CreateOrder, UploadCarImage } from "../../models/api";
|
import { GetOrder, CreateOrder } from "../../models/api";
|
||||||
|
|
||||||
import { api } from "./api";
|
import { api } from "./api";
|
||||||
import { extractBodyFromResponse, extractErrorMessageFromResponse } from "./utils";
|
import { extractBodyFromResponse, extractErrorMessageFromResponse } from "./utils";
|
||||||
@ -19,13 +19,5 @@ export const landingApi = api.injectEndpoints({
|
|||||||
transformResponse: extractBodyFromResponse<CreateOrder.Response>,
|
transformResponse: extractBodyFromResponse<CreateOrder.Response>,
|
||||||
transformErrorResponse: extractErrorMessageFromResponse,
|
transformErrorResponse: extractErrorMessageFromResponse,
|
||||||
}),
|
}),
|
||||||
uploadCarImage: mutation<UploadCarImage.Response, UploadCarImage.Params>({
|
|
||||||
query: ({ orderId, body }) => ({
|
|
||||||
url: `/order/${orderId}/upload-car-img`,
|
|
||||||
body,
|
|
||||||
method: 'POST'
|
|
||||||
}),
|
|
||||||
transformErrorResponse: extractErrorMessageFromResponse,
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FetchBaseQueryError } from '@reduxjs/toolkit/query';
|
import { FetchBaseQueryError } from "@reduxjs/toolkit/query";
|
||||||
|
|
||||||
import { BaseResponse } from '../../models/api';
|
import { BaseResponse } from "../../models/api";
|
||||||
|
|
||||||
export const extractBodyFromResponse = <Body>(response: BaseResponse<Body>) => {
|
export const extractBodyFromResponse = <Body>(response: BaseResponse<Body>) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@ -8,15 +8,8 @@ export const extractBodyFromResponse = <Body>(response: BaseResponse<Body>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const extractErrorMessageFromResponse = ({
|
export const extractErrorMessageFromResponse = ({ data }: FetchBaseQueryError) => {
|
||||||
data,
|
if (typeof data === 'object' && 'message' in data && typeof data.message === 'string') {
|
||||||
}: FetchBaseQueryError) => {
|
return data.message;
|
||||||
if (
|
|
||||||
typeof data === 'object' &&
|
|
||||||
data !== null &&
|
|
||||||
'error' in data &&
|
|
||||||
typeof data.error === 'string'
|
|
||||||
) {
|
|
||||||
return data.error;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -7,9 +7,7 @@ export const store = configureStore({
|
|||||||
[api.reducerPath]: api.reducer,
|
[api.reducerPath]: api.reducer,
|
||||||
},
|
},
|
||||||
middleware: (getDefaultMiddleware) =>
|
middleware: (getDefaultMiddleware) =>
|
||||||
getDefaultMiddleware({
|
getDefaultMiddleware().concat(api.middleware),
|
||||||
serializableCheck: false
|
|
||||||
}).concat(api.middleware),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type RootState = ReturnType<typeof store.getState>;
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, Button, Text } from '@chakra-ui/react';
|
import { Box, Button, Text } from '@chakra-ui/react';
|
||||||
import { ArrowBackIcon, ArrowForwardIcon } from '@chakra-ui/icons';
|
import { ArrowBackIcon, ArrowForwardIcon } from '@chakra-ui/icons';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
|
|
||||||
interface DateNavigatorProps {
|
interface DateNavigatorProps {
|
||||||
currentDate: Date;
|
currentDate: Date;
|
||||||
@ -20,7 +19,7 @@ const DateNavigator = ({
|
|||||||
<ArrowBackIcon />
|
<ArrowBackIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Text mx='4' fontSize='lg' fontWeight='bold'>
|
<Text mx='4' fontSize='lg' fontWeight='bold'>
|
||||||
{dayjs(currentDate).format('DD.MM.YYYY')}
|
{currentDate.toLocaleDateString()}
|
||||||
</Text>
|
</Text>
|
||||||
<Button onClick={onNextDate}>
|
<Button onClick={onNextDate}>
|
||||||
<ArrowForwardIcon />
|
<ArrowForwardIcon />
|
||||||
|
@ -33,22 +33,22 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { hasError } = this.state;
|
const { hasError } = this.state;
|
||||||
|
//TODO: добавить анимацию после залива 404 страницы
|
||||||
|
//TODO: может сделать обертку для хука, чтоб язык менялся без перезагрузки
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
return (
|
return (
|
||||||
<Center minH='100vh' data-testid='error-boundary'>
|
<Center minH='100vh'>
|
||||||
<VStack spacing={4} textAlign='center'>
|
<VStack spacing={4} textAlign='center'>
|
||||||
<Heading as='h1' size='2xl' data-testid='error-title'>
|
<Heading as='h1' size='2xl'>
|
||||||
{i18next.t('~:dry-wash.errorBoundary.title')}
|
{i18next.t('~:dry-wash.errorBoundary.title')}
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text fontSize='lg' data-testid='error-description'>
|
<Text fontSize='lg'>
|
||||||
{i18next.t('~:dry-wash.errorBoundary.description')}
|
{i18next.t('~:dry-wash.errorBoundary.description')}
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
colorScheme='teal'
|
colorScheme='teal'
|
||||||
size='lg'
|
size='lg'
|
||||||
variant='outline'
|
variant='outline'
|
||||||
data-testid='error-reload-button'
|
|
||||||
onClick={() => window.location.reload()}
|
onClick={() => window.location.reload()}
|
||||||
>
|
>
|
||||||
{i18next.t('~:dry-wash.errorBoundary.button.reload')}
|
{i18next.t('~:dry-wash.errorBoundary.button.reload')}
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import { describe, expect, it, jest } from '@jest/globals';
|
|
||||||
import { render, screen, waitFor } from '@testing-library/react';
|
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import ErrorBoundary from '../ErrorBoundary';
|
|
||||||
import { store } from '../../../__data__/store';
|
|
||||||
|
|
||||||
const ProblematicComponent = () => {
|
|
||||||
useEffect(() => {
|
|
||||||
throw new Error('Test Error');
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return <div>Этот текст не должен появиться</div>;
|
|
||||||
};
|
|
||||||
jest.mock('@brojs/cli', () => {
|
|
||||||
return {
|
|
||||||
getNavigationValue: () => '/auth/login',
|
|
||||||
getConfigValue: () => '/api',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ErrorBoundary', () => {
|
|
||||||
it('должен отобразить запасной UI при ошибке', async () => {
|
|
||||||
// Подавляем вывод ошибки в консоль во время теста
|
|
||||||
const consoleSpy = jest.spyOn(console, 'error');
|
|
||||||
consoleSpy.mockImplementation(() => {});
|
|
||||||
|
|
||||||
const { container } = render(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<BrowserRouter>
|
|
||||||
<ProblematicComponent />
|
|
||||||
</BrowserRouter>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</Provider>,
|
|
||||||
);
|
|
||||||
|
|
||||||
const button = await waitFor(() =>
|
|
||||||
screen.getByTestId('error-reload-button'),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(button).not.toBeNull();
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
|
|
||||||
// Восстанавливаем console.error после теста
|
|
||||||
consoleSpy.mockRestore();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,28 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ErrorBoundary должен отобразить запасной UI при ошибке 1`] = `
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
class="css-1o0ed15"
|
|
||||||
data-testid="error-boundary"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-zefqyp"
|
|
||||||
>
|
|
||||||
<h1
|
|
||||||
class="chakra-heading css-0"
|
|
||||||
data-testid="error-title"
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
class="chakra-text css-1ezsviu"
|
|
||||||
data-testid="error-description"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
class="chakra-button css-4xx2wk"
|
|
||||||
data-testid="error-reload-button"
|
|
||||||
type="button"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -15,13 +15,13 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import OrderItem from '../OrderItem';
|
import OrderItem from '../OrderItem';
|
||||||
|
import { OrderProps } from '../OrderItem/OrderItem';
|
||||||
import DateNavigator from '../DateNavigator';
|
import DateNavigator from '../DateNavigator';
|
||||||
import {
|
import {
|
||||||
useGetMastersQuery,
|
useGetMastersQuery,
|
||||||
useGetOrdersQuery,
|
useGetOrdersQuery,
|
||||||
} from '../../__data__/service/api';
|
} from '../../__data__/service/api';
|
||||||
import useShowToast from '../../hooks/useShowToast';
|
import useShowToast from '../../hooks/useShowToast';
|
||||||
import { OrderArm } from '../../models/api';
|
|
||||||
|
|
||||||
const TABLE_HEADERS = [
|
const TABLE_HEADERS = [
|
||||||
'carNumber' as const,
|
'carNumber' as const,
|
||||||
@ -70,6 +70,7 @@ const Orders = () => {
|
|||||||
<Heading size='lg' mb='5'>
|
<Heading size='lg' mb='5'>
|
||||||
{t('title')}
|
{t('title')}
|
||||||
</Heading>
|
</Heading>
|
||||||
|
|
||||||
<DateNavigator
|
<DateNavigator
|
||||||
currentDate={currentDate}
|
currentDate={currentDate}
|
||||||
onPreviousDate={() =>
|
onPreviousDate={() =>
|
||||||
@ -111,7 +112,7 @@ const Orders = () => {
|
|||||||
allMasters={masters}
|
allMasters={masters}
|
||||||
key={index}
|
key={index}
|
||||||
{...order}
|
{...order}
|
||||||
status={order.status as OrderArm['status']}
|
status={order.status as OrderProps['status']}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
|
@ -5,7 +5,6 @@ export const PageSpinner: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<Flex w='full' h='100vh' justifyContent='center' alignItems='center'>
|
<Flex w='full' h='100vh' justifyContent='center' alignItems='center'>
|
||||||
<Spinner
|
<Spinner
|
||||||
data-testid='spinner'
|
|
||||||
thickness='5px'
|
thickness='5px'
|
||||||
speed='0.65s'
|
speed='0.65s'
|
||||||
emptyColor='gray.200'
|
emptyColor='gray.200'
|
||||||
|
@ -47,7 +47,6 @@ const Sidebar = () => {
|
|||||||
w='100%'
|
w='100%'
|
||||||
colorScheme={isActive(URLs.armMaster.url) ? 'green' : 'blue'}
|
colorScheme={isActive(URLs.armMaster.url) ? 'green' : 'blue'}
|
||||||
variant={isActive(URLs.armMaster.url) ? 'solid' : 'ghost'}
|
variant={isActive(URLs.armMaster.url) ? 'solid' : 'ghost'}
|
||||||
data-testid='master-button'
|
|
||||||
>
|
>
|
||||||
{t('master')}
|
{t('master')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
import React, { FC, memo, useRef } from 'react';
|
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
FormControl,
|
|
||||||
FormErrorMessage,
|
|
||||||
FormHelperText,
|
|
||||||
FormLabel,
|
|
||||||
HStack,
|
|
||||||
Input,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { landingApi } from '../../../__data__/service/landing.api';
|
|
||||||
import { UploadCarImage } from '../../../models/api';
|
|
||||||
|
|
||||||
import { useHandleUploadCarImageResponse } from './helper';
|
|
||||||
|
|
||||||
type FormValues = {
|
|
||||||
carImg: File & {
|
|
||||||
fileName: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type CarImageFormProps = {
|
|
||||||
orderId: UploadCarImage.Params['orderId'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CarImageForm: FC<CarImageFormProps> = memo(function CarImageForm({
|
|
||||||
orderId,
|
|
||||||
}) {
|
|
||||||
const {
|
|
||||||
handleSubmit,
|
|
||||||
control,
|
|
||||||
formState: { errors, isSubmitting },
|
|
||||||
} = useForm<FormValues>({ shouldFocusError: true });
|
|
||||||
|
|
||||||
const [uploadCarImage, uploadCarImageMutation] =
|
|
||||||
landingApi.useUploadCarImageMutation();
|
|
||||||
useHandleUploadCarImageResponse(uploadCarImageMutation);
|
|
||||||
|
|
||||||
const onSubmit = (formData: FormValues) => {
|
|
||||||
const body = new FormData();
|
|
||||||
body.append('file', formData.carImg);
|
|
||||||
uploadCarImage({ orderId, body });
|
|
||||||
};
|
|
||||||
|
|
||||||
const fileInputRef = useRef(null);
|
|
||||||
|
|
||||||
const { t } = useTranslation('~', {
|
|
||||||
keyPrefix: 'dry-wash.order-view.upload-car-image',
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form>
|
|
||||||
<FormControl>
|
|
||||||
<FormLabel htmlFor='carImg'>{t('field.label')}</FormLabel>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name='carImg'
|
|
||||||
render={({ field: { value, onChange, ...field } }) => {
|
|
||||||
return (
|
|
||||||
<HStack gap={0}>
|
|
||||||
<Input
|
|
||||||
{...field}
|
|
||||||
ref={fileInputRef}
|
|
||||||
accept='image/png,image/jpeg'
|
|
||||||
value={value?.fileName}
|
|
||||||
onChange={(event) => {
|
|
||||||
onChange(event.target.files[0]);
|
|
||||||
handleSubmit(onSubmit)();
|
|
||||||
}}
|
|
||||||
type='file'
|
|
||||||
hidden
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
placeholder={t('file-input.placeholder')}
|
|
||||||
value={value?.name || ''}
|
|
||||||
readOnly
|
|
||||||
borderRightRadius={0}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
fileInputRef.current.click();
|
|
||||||
}}
|
|
||||||
isLoading={isSubmitting || uploadCarImageMutation.isLoading}
|
|
||||||
colorScheme='primary'
|
|
||||||
paddingInline={8}
|
|
||||||
borderLeftRadius={0}
|
|
||||||
>
|
|
||||||
{t('file-input.button')}
|
|
||||||
</Button>
|
|
||||||
</HStack>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<FormErrorMessage>{errors.carImg?.message}</FormErrorMessage>
|
|
||||||
<FormHelperText>{t('field.help')}</FormHelperText>
|
|
||||||
</FormControl>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
});
|
|
@ -1,35 +0,0 @@
|
|||||||
import { useEffect } from "react";
|
|
||||||
import { useToast } from "@chakra-ui/react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
import { isErrorMessage } from "../../../models/api";
|
|
||||||
|
|
||||||
export const useHandleUploadCarImageResponse = (query: {
|
|
||||||
isSuccess: boolean;
|
|
||||||
isError: boolean;
|
|
||||||
error?: unknown;
|
|
||||||
}) => {
|
|
||||||
const toast = useToast();
|
|
||||||
const { t } = useTranslation('~', {
|
|
||||||
keyPrefix: 'dry-wash.order-view.upload-car-image-query',
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (query.isError) {
|
|
||||||
toast({
|
|
||||||
status: 'error',
|
|
||||||
title: t('error.title'),
|
|
||||||
description: isErrorMessage(query.error) ? query.error : undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [query.isError]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (query.isSuccess) {
|
|
||||||
toast({
|
|
||||||
status: 'success',
|
|
||||||
title: t('success.title'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [query.isSuccess]);
|
|
||||||
};
|
|
@ -1 +0,0 @@
|
|||||||
export { CarImageForm } from './car-img-form';
|
|
@ -5,13 +5,11 @@ import {
|
|||||||
Heading,
|
Heading,
|
||||||
HStack,
|
HStack,
|
||||||
UnorderedList,
|
UnorderedList,
|
||||||
|
VStack,
|
||||||
ListItem,
|
ListItem,
|
||||||
Text,
|
Text,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
|
||||||
dayjs.extend(localizedFormat);
|
|
||||||
|
|
||||||
import { Order } from '../../../models/landing';
|
import { Order } from '../../../models/landing';
|
||||||
import { formatDatetime } from '../../../lib';
|
import { formatDatetime } from '../../../lib';
|
||||||
@ -43,7 +41,7 @@ export const OrderDetails: FC<OrderDetailsProps> = ({
|
|||||||
location,
|
location,
|
||||||
startWashTime,
|
startWashTime,
|
||||||
endWashTime,
|
endWashTime,
|
||||||
created
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation('~', {
|
const { t } = useTranslation('~', {
|
||||||
keyPrefix: 'dry-wash.order-view.details',
|
keyPrefix: 'dry-wash.order-view.details',
|
||||||
@ -53,7 +51,7 @@ export const OrderDetails: FC<OrderDetailsProps> = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<VStack p={4} alignItems='flex-start' gap={4} {...props}>
|
||||||
<HStack
|
<HStack
|
||||||
width='full'
|
width='full'
|
||||||
flexWrap='wrap'
|
flexWrap='wrap'
|
||||||
@ -61,7 +59,7 @@ export const OrderDetails: FC<OrderDetailsProps> = ({
|
|||||||
gap={2}
|
gap={2}
|
||||||
>
|
>
|
||||||
<Heading as='h2' size='lg'>
|
<Heading as='h2' size='lg'>
|
||||||
{t('title', { number: orderNumber })} ({dayjs(created).format('LLLL')})
|
{t('title', { number: orderNumber })}
|
||||||
</Heading>
|
</Heading>
|
||||||
<OrderStatus value={status} />
|
<OrderStatus value={status} />
|
||||||
</HStack>
|
</HStack>
|
||||||
@ -107,7 +105,7 @@ export const OrderDetails: FC<OrderDetailsProps> = ({
|
|||||||
<AlertIcon />
|
<AlertIcon />
|
||||||
{t('alert')}
|
{t('alert')}
|
||||||
</Alert>
|
</Alert>
|
||||||
</>
|
</VStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ export const isErrorMessage = (error: unknown): error is ErrorMessage => typeof
|
|||||||
|
|
||||||
type ErrorResponse = {
|
type ErrorResponse = {
|
||||||
success: false;
|
success: false;
|
||||||
error: ErrorMessage;
|
message: ErrorMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BaseResponse<Body> = SuccessResponse<Body> | ErrorResponse;
|
export type BaseResponse<Body> = SuccessResponse<Body> | ErrorResponse;
|
||||||
|
@ -21,17 +21,6 @@ export namespace CreateOrder {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace UploadCarImage {
|
|
||||||
export type Response = void;
|
|
||||||
export type Params = {
|
|
||||||
orderId: Order.Id;
|
|
||||||
/**
|
|
||||||
* @example { file: File }
|
|
||||||
*/
|
|
||||||
body: FormData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetArrItemType<ArrType> =
|
type GetArrItemType<ArrType> =
|
||||||
ArrType extends Array<infer ItemType> ? ItemType : never;
|
ArrType extends Array<infer ItemType> ? ItemType : never;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`Страница заказов должна корректно отображать список заказов после загрузки данных 1`] = `
|
exports[`Arm Page render 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="css-1yeiifd"
|
class="css-1yeiifd"
|
||||||
@ -32,7 +32,6 @@ exports[`Страница заказов должна корректно ото
|
|||||||
/>
|
/>
|
||||||
<a
|
<a
|
||||||
class="chakra-button css-1kg18wp"
|
class="chakra-button css-1kg18wp"
|
||||||
data-testid="master-button"
|
|
||||||
href="/auth/login"
|
href="/auth/login"
|
||||||
>
|
>
|
||||||
Мастера
|
Мастера
|
||||||
@ -75,7 +74,173 @@ exports[`Страница заказов должна корректно ото
|
|||||||
<p
|
<p
|
||||||
class="chakra-text css-52ukzg"
|
class="chakra-text css-52ukzg"
|
||||||
>
|
>
|
||||||
23.02.2025
|
15.02.2025
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
class="chakra-button css-ez23ye"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="chakra-icon css-onkibi"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<table
|
||||||
|
class="chakra-table css-5605sr"
|
||||||
|
>
|
||||||
|
<thead
|
||||||
|
class="css-0"
|
||||||
|
>
|
||||||
|
<tr
|
||||||
|
class="css-0"
|
||||||
|
>
|
||||||
|
<th
|
||||||
|
class="css-1szkfps"
|
||||||
|
>
|
||||||
|
Номер машины
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="css-1szkfps"
|
||||||
|
>
|
||||||
|
Дата заказа
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="css-1szkfps"
|
||||||
|
>
|
||||||
|
Статус
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="css-1szkfps"
|
||||||
|
>
|
||||||
|
Мастер
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="css-1szkfps"
|
||||||
|
>
|
||||||
|
Телефон
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="css-1szkfps"
|
||||||
|
>
|
||||||
|
Расположение
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody
|
||||||
|
class="css-0"
|
||||||
|
>
|
||||||
|
<tr
|
||||||
|
class="css-0"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
class="css-1v9gmks"
|
||||||
|
colspan="6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="chakra-spinner css-1j92705"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="css-8b45rq"
|
||||||
|
>
|
||||||
|
Loading...
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
hidden=""
|
||||||
|
id="__chakra_env"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Arm Page render 2`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="css-1yeiifd"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="css-13owfwq"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="chakra-heading css-173d1bl"
|
||||||
|
>
|
||||||
|
Сухой мастер
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="chakra-stack css-1cggwyz"
|
||||||
|
>
|
||||||
|
<hr
|
||||||
|
aria-orientation="horizontal"
|
||||||
|
class="chakra-divider css-svjswr"
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
class="chakra-button css-1kg18wp"
|
||||||
|
href="/auth/login"
|
||||||
|
>
|
||||||
|
Заказы
|
||||||
|
</a>
|
||||||
|
<hr
|
||||||
|
aria-orientation="horizontal"
|
||||||
|
class="chakra-divider css-svjswr"
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
class="chakra-button css-1kg18wp"
|
||||||
|
href="/auth/login"
|
||||||
|
>
|
||||||
|
Мастера
|
||||||
|
</a>
|
||||||
|
<hr
|
||||||
|
aria-orientation="horizontal"
|
||||||
|
class="chakra-divider css-svjswr"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="css-jiwy8d"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="css-1glkkdp"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="chakra-heading css-1xer3cv"
|
||||||
|
>
|
||||||
|
Заказы
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="css-1u3smh"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="chakra-button css-ez23ye"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="chakra-icon css-onkibi"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<p
|
||||||
|
class="chakra-text css-52ukzg"
|
||||||
|
>
|
||||||
|
15.02.2025
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
class="chakra-button css-ez23ye"
|
class="chakra-button css-ez23ye"
|
@ -1,643 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Master Page should display master list and show details when master button is clicked 1`] = `
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
class="css-1yeiifd"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="css-13owfwq"
|
|
||||||
>
|
|
||||||
<h2
|
|
||||||
class="chakra-heading css-173d1bl"
|
|
||||||
>
|
|
||||||
Сухой мастер
|
|
||||||
</h2>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-1cggwyz"
|
|
||||||
>
|
|
||||||
<hr
|
|
||||||
aria-orientation="horizontal"
|
|
||||||
class="chakra-divider css-svjswr"
|
|
||||||
/>
|
|
||||||
<a
|
|
||||||
class="chakra-button css-18yoix2"
|
|
||||||
href="/order"
|
|
||||||
>
|
|
||||||
Заказы
|
|
||||||
</a>
|
|
||||||
<hr
|
|
||||||
aria-orientation="horizontal"
|
|
||||||
class="chakra-divider css-svjswr"
|
|
||||||
/>
|
|
||||||
<a
|
|
||||||
class="chakra-button css-1kg18wp"
|
|
||||||
data-testid="master-button"
|
|
||||||
href="/master"
|
|
||||||
>
|
|
||||||
Мастера
|
|
||||||
</a>
|
|
||||||
<hr
|
|
||||||
aria-orientation="horizontal"
|
|
||||||
class="chakra-divider css-svjswr"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="css-jiwy8d"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="css-1glkkdp"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="css-sd3fvu"
|
|
||||||
>
|
|
||||||
<h2
|
|
||||||
class="chakra-heading css-1jb3vzl"
|
|
||||||
>
|
|
||||||
|
|
||||||
Мастера
|
|
||||||
</h2>
|
|
||||||
<button
|
|
||||||
class="chakra-button css-h211ee"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
+
|
|
||||||
Добавить
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<table
|
|
||||||
class="chakra-table css-5605sr"
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
class="css-0"
|
|
||||||
>
|
|
||||||
<tr
|
|
||||||
class="css-0"
|
|
||||||
>
|
|
||||||
<th
|
|
||||||
class="css-1szkfps"
|
|
||||||
>
|
|
||||||
Имя
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="css-1szkfps"
|
|
||||||
>
|
|
||||||
Актуальная занятость
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="css-1szkfps"
|
|
||||||
>
|
|
||||||
Телефон
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
class="css-1szkfps"
|
|
||||||
>
|
|
||||||
Действия
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody
|
|
||||||
class="css-0"
|
|
||||||
>
|
|
||||||
<tr
|
|
||||||
class="css-0"
|
|
||||||
>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-editable css-vtl58r"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-c2wmld"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-editable__preview css-1gasyng"
|
|
||||||
>
|
|
||||||
Иван Иванов
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="chakra-editable__input chakra-input css-2lpiar"
|
|
||||||
hidden=""
|
|
||||||
value="Иван Иванов"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="css-1l4w6pd"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label="Edit"
|
|
||||||
class="chakra-button css-1pqvhxt"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
class="chakra-text css-q9k0mw"
|
|
||||||
>
|
|
||||||
Свободен
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-editable css-vtl58r"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-c2wmld"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-editable__preview css-1gasyng"
|
|
||||||
>
|
|
||||||
+7 900 123 45 67
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="chakra-editable__input chakra-input css-2lpiar"
|
|
||||||
hidden=""
|
|
||||||
value="+7 900 123 45 67"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="css-1l4w6pd"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label="Edit"
|
|
||||||
class="chakra-button css-1pqvhxt"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-controls="menu-list-:r2:"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-haspopup="menu"
|
|
||||||
class="chakra-button chakra-menu__menu-button css-13sr8jm"
|
|
||||||
id="menu-button-:r2:"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div
|
|
||||||
class="css-ktd6ms"
|
|
||||||
style="visibility: hidden; position: absolute; min-width: max-content; inset: 0 auto auto 0;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-orientation="vertical"
|
|
||||||
class="chakra-menu__menu-list css-s5t7bz"
|
|
||||||
id="menu-list-:r2:"
|
|
||||||
role="menu"
|
|
||||||
style="transform-origin: var(--popper-transform-origin); opacity: 0; visibility: hidden; transform: scale(0.8) translateZ(0);"
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-disabled="false"
|
|
||||||
class="chakra-menu__menuitem css-y7jzs3"
|
|
||||||
data-index="0"
|
|
||||||
id="menu-list-:r2:-menuitem-:r3:"
|
|
||||||
role="menuitem"
|
|
||||||
tabindex="-1"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
Удалить мастера
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr
|
|
||||||
class="css-0"
|
|
||||||
>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-editable css-vtl58r"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-c2wmld"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-editable__preview css-1gasyng"
|
|
||||||
>
|
|
||||||
Олег Макаров
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="chakra-editable__input chakra-input css-2lpiar"
|
|
||||||
hidden=""
|
|
||||||
value="Олег Макаров"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="css-1l4w6pd"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label="Edit"
|
|
||||||
class="chakra-button css-1pqvhxt"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
class="chakra-text css-q9k0mw"
|
|
||||||
>
|
|
||||||
Свободен
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-editable css-vtl58r"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-c2wmld"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-editable__preview css-1gasyng"
|
|
||||||
>
|
|
||||||
79001234567
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="chakra-editable__input chakra-input css-2lpiar"
|
|
||||||
hidden=""
|
|
||||||
value="79001234567"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="css-1l4w6pd"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label="Edit"
|
|
||||||
class="chakra-button css-1pqvhxt"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-controls="menu-list-:r5:"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-haspopup="menu"
|
|
||||||
class="chakra-button chakra-menu__menu-button css-13sr8jm"
|
|
||||||
id="menu-button-:r5:"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div
|
|
||||||
class="css-ktd6ms"
|
|
||||||
style="visibility: hidden; position: absolute; min-width: max-content; inset: 0 auto auto 0;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-orientation="vertical"
|
|
||||||
class="chakra-menu__menu-list css-s5t7bz"
|
|
||||||
id="menu-list-:r5:"
|
|
||||||
role="menu"
|
|
||||||
style="transform-origin: var(--popper-transform-origin); opacity: 0; visibility: hidden; transform: scale(0.8) translateZ(0);"
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-disabled="false"
|
|
||||||
class="chakra-menu__menuitem css-y7jzs3"
|
|
||||||
data-index="0"
|
|
||||||
id="menu-list-:r5:-menuitem-:r6:"
|
|
||||||
role="menuitem"
|
|
||||||
tabindex="-1"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
Удалить мастера
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr
|
|
||||||
class="css-0"
|
|
||||||
>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-editable css-vtl58r"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-c2wmld"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-editable__preview css-1gasyng"
|
|
||||||
>
|
|
||||||
Иван Галкин
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="chakra-editable__input chakra-input css-2lpiar"
|
|
||||||
hidden=""
|
|
||||||
value="Иван Галкин"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="css-1l4w6pd"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label="Edit"
|
|
||||||
class="chakra-button css-1pqvhxt"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-1f0wxn3"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-badge css-1g1qw76"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="chakra-badge css-1g1qw76"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-editable css-vtl58r"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="chakra-stack css-c2wmld"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="chakra-editable__preview css-1gasyng"
|
|
||||||
>
|
|
||||||
+7 900 123 45 67
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="chakra-editable__input chakra-input css-2lpiar"
|
|
||||||
hidden=""
|
|
||||||
value="+7 900 123 45 67"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="css-1l4w6pd"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label="Edit"
|
|
||||||
class="chakra-button css-1pqvhxt"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="css-zgoslk"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-controls="menu-list-:r8:"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-haspopup="menu"
|
|
||||||
class="chakra-button chakra-menu__menu-button css-13sr8jm"
|
|
||||||
id="menu-button-:r8:"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="chakra-icon css-onkibi"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div
|
|
||||||
class="css-ktd6ms"
|
|
||||||
style="visibility: hidden; position: absolute; min-width: max-content; inset: 0 auto auto 0;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-orientation="vertical"
|
|
||||||
class="chakra-menu__menu-list css-s5t7bz"
|
|
||||||
id="menu-list-:r8:"
|
|
||||||
role="menu"
|
|
||||||
style="transform-origin: var(--popper-transform-origin); opacity: 0; visibility: hidden; transform: scale(0.8) translateZ(0);"
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-disabled="false"
|
|
||||||
class="chakra-menu__menuitem css-y7jzs3"
|
|
||||||
data-index="0"
|
|
||||||
id="menu-list-:r8:-menuitem-:r9:"
|
|
||||||
role="menuitem"
|
|
||||||
tabindex="-1"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
Удалить мастера
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
hidden=""
|
|
||||||
id="__chakra_env"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`Страница просмотра заказа отображает детали заказа после успешной загрузки 1`] = `
|
exports[`Order View page, initial load shows order details 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="chakra-container css-3n6qh3"
|
class="chakra-container css-3n6qh3"
|
||||||
@ -16,6 +16,7 @@ exports[`Страница просмотра заказа отображает
|
|||||||
</h2>
|
</h2>
|
||||||
<div
|
<div
|
||||||
class="chakra-stack css-1n38vgh"
|
class="chakra-stack css-1n38vgh"
|
||||||
|
created="2025-01-19T14:04:02.985Z"
|
||||||
data-testid="order-details"
|
data-testid="order-details"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -25,9 +26,6 @@ exports[`Страница просмотра заказа отображает
|
|||||||
class="chakra-heading css-1jb3vzl"
|
class="chakra-heading css-1jb3vzl"
|
||||||
>
|
>
|
||||||
Заказ №{{number}}
|
Заказ №{{number}}
|
||||||
(
|
|
||||||
Sunday, January 19, 2025 5:04 PM
|
|
||||||
)
|
|
||||||
</h2>
|
</h2>
|
||||||
<span
|
<span
|
||||||
class="css-6jfsiv"
|
class="css-6jfsiv"
|
||||||
@ -128,7 +126,7 @@ exports[`Страница просмотра заказа отображает
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Страница просмотра заказа отображает индикатор загрузки деталей заказа 1`] = `
|
exports[`Order View page, initial load shows order details loading 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="chakra-container css-3n6qh3"
|
class="chakra-container css-3n6qh3"
|
||||||
@ -173,7 +171,7 @@ exports[`Страница просмотра заказа отображает
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Страница просмотра заказа отображает ошибку при некорректном ID заказа 1`] = `
|
exports[`Order View page, initial load shows order error 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="chakra-container css-3n6qh3"
|
class="chakra-container css-3n6qh3"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import * as React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
describe,
|
describe,
|
||||||
it,
|
it,
|
||||||
@ -98,12 +98,16 @@ jest.mock('@brojs/cli', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Страница заказов', () => {
|
describe('Arm Page', () => {
|
||||||
beforeAll(() => server.listen());
|
beforeAll(() => server.listen());
|
||||||
afterEach(() => server.resetHandlers());
|
afterEach(() => server.resetHandlers());
|
||||||
afterAll(() => server.close());
|
afterAll(() => server.close());
|
||||||
|
|
||||||
it('должна корректно отображать список заказов после загрузки данных', async () => {
|
it('render ', async () => {
|
||||||
|
server.events.on('request:start', ({ request }) => {
|
||||||
|
console.log('Outgoing:', request.method, request.url);
|
||||||
|
});
|
||||||
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ChakraProvider theme={chakraTheme}>
|
<ChakraProvider theme={chakraTheme}>
|
||||||
@ -116,6 +120,8 @@ describe('Страница заказов', () => {
|
|||||||
</Provider>,
|
</Provider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
|
||||||
await waitFor(() => screen.getByText('A123BC'));
|
await waitFor(() => screen.getByText('A123BC'));
|
||||||
|
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
@ -1,133 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import {
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
expect,
|
|
||||||
jest,
|
|
||||||
beforeAll,
|
|
||||||
afterEach,
|
|
||||||
afterAll,
|
|
||||||
} from '@jest/globals';
|
|
||||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
||||||
import { http, HttpResponse } from 'msw';
|
|
||||||
import { setupServer } from 'msw/node';
|
|
||||||
import { ChakraProvider, theme as chakraTheme } from '@chakra-ui/react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
|
||||||
|
|
||||||
import ErrorBoundary from '../../components/ErrorBoundary';
|
|
||||||
import { store } from '../../__data__/store';
|
|
||||||
import Page from '../arm';
|
|
||||||
|
|
||||||
const server = setupServer(
|
|
||||||
http.get('/api/arm/masters', () => {
|
|
||||||
return HttpResponse.json({
|
|
||||||
success: true,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
id: '4545423234',
|
|
||||||
name: 'Иван Иванов',
|
|
||||||
phone: '+7 900 123 45 67',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Олег Макаров',
|
|
||||||
phone: '79001234567',
|
|
||||||
id: '23423442',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '345354234',
|
|
||||||
name: 'Иван Галкин',
|
|
||||||
schedule: [
|
|
||||||
{
|
|
||||||
id: 'order1',
|
|
||||||
startWashTime: '2024-11-24T10:30:00.000Z',
|
|
||||||
endWashTime: '2024-11-24T16:30:00.000Z',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'order2',
|
|
||||||
startWashTime: '2024-11-24T11:30:00.000Z',
|
|
||||||
endWashTime: '2024-11-24T17:30:00.000Z',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
phone: '+7 900 123 45 67',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
http.post('/api/arm/orders', () => {
|
|
||||||
return HttpResponse.json({
|
|
||||||
success: true,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
id: 'order1',
|
|
||||||
carNumber: 'A123BC',
|
|
||||||
startWashTime: '2024-11-24T10:30:00.000Z',
|
|
||||||
endWashTime: '2024-11-24T16:30:00.000Z',
|
|
||||||
orderDate: '2024-11-24T08:41:46.366Z',
|
|
||||||
status: 'pending',
|
|
||||||
phone: '79001234563',
|
|
||||||
location: 'Казань, ул. Баумана, 1',
|
|
||||||
master: {
|
|
||||||
name: 'Олег Макаров',
|
|
||||||
phone: '79001234567',
|
|
||||||
id: '23423442',
|
|
||||||
},
|
|
||||||
notes: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'order2',
|
|
||||||
carNumber: 'A245BC',
|
|
||||||
startWashTime: '2024-11-24T11:30:00.000Z',
|
|
||||||
endWashTime: '2024-11-24T17:30:00.000Z',
|
|
||||||
orderDate: '2024-11-24T07:40:46.366Z',
|
|
||||||
status: 'progress',
|
|
||||||
phone: '79001234567',
|
|
||||||
location: 'Казань, ул. Баумана, 43',
|
|
||||||
master: [],
|
|
||||||
notes: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
jest.mock('@brojs/cli', () => {
|
|
||||||
return {
|
|
||||||
getNavigationValue: (key: string) =>
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
||||||
require('../../../bro.config').navigations[key],
|
|
||||||
getConfigValue: () => '/api',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Master Page', () => {
|
|
||||||
beforeAll(() => server.listen());
|
|
||||||
afterEach(() => server.resetHandlers());
|
|
||||||
afterAll(() => server.close());
|
|
||||||
|
|
||||||
it('should display master list and show details when master button is clicked', async () => {
|
|
||||||
const { container } = render(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ChakraProvider theme={chakraTheme}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<BrowserRouter>
|
|
||||||
<Page mockUser={{ name: 'ilnaz' }} />
|
|
||||||
</BrowserRouter>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</ChakraProvider>
|
|
||||||
</Provider>,
|
|
||||||
);
|
|
||||||
|
|
||||||
const button = await waitFor(() => screen.getByTestId('master-button'));
|
|
||||||
fireEvent.click(button);
|
|
||||||
|
|
||||||
// Проверяем отображение всех мастеров
|
|
||||||
await waitFor(() => {
|
|
||||||
expect(screen.getByText('Иван Иванов')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('Олег Макаров')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('Иван Галкин')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
@ -11,12 +11,12 @@ jest.mock('react-router-dom', () => ({
|
|||||||
useParams: jest.fn(),
|
useParams: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('Страница просмотра заказа', () => {
|
describe('Order View page, initial load', () => {
|
||||||
beforeAll(() => server.listen());
|
beforeAll(() => server.listen());
|
||||||
afterEach(() => server.resetHandlers());
|
afterEach(() => server.resetHandlers());
|
||||||
afterAll(() => server.close());
|
afterAll(() => server.close());
|
||||||
|
|
||||||
test('отображает индикатор загрузки деталей заказа', () => {
|
test('shows order details loading', () => {
|
||||||
(useParams as jest.Mock).mockReturnValue({ orderId: 'id1' });
|
(useParams as jest.Mock).mockReturnValue({ orderId: 'id1' });
|
||||||
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
@ -33,7 +33,7 @@ describe('Страница просмотра заказа', () => {
|
|||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('отображает детали заказа после успешной загрузки', async () => {
|
test('shows order details', async () => {
|
||||||
(useParams as jest.Mock).mockReturnValue({ orderId: 'id1' });
|
(useParams as jest.Mock).mockReturnValue({ orderId: 'id1' });
|
||||||
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
@ -52,7 +52,7 @@ describe('Страница просмотра заказа', () => {
|
|||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('отображает ошибку при некорректном ID заказа', async () => {
|
test('shows order error', async () => {
|
||||||
(useParams as jest.Mock).mockReturnValue({ orderId: null });
|
(useParams as jest.Mock).mockReturnValue({ orderId: null });
|
||||||
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import {
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
jest,
|
|
||||||
beforeAll,
|
|
||||||
afterEach,
|
|
||||||
afterAll,
|
|
||||||
} from '@jest/globals';
|
|
||||||
import { render, screen, waitFor } from '@testing-library/react';
|
|
||||||
import { http, HttpResponse } from 'msw';
|
|
||||||
import { setupServer } from 'msw/node';
|
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
|
||||||
import { ChakraProvider, theme as chakraTheme } from '@chakra-ui/react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
|
|
||||||
import ErrorBoundary from '../../components/ErrorBoundary';
|
|
||||||
import { store } from '../../__data__/store';
|
|
||||||
import Page from '../arm';
|
|
||||||
|
|
||||||
const server = setupServer(
|
|
||||||
http.post('/api/arm/orders', () => {
|
|
||||||
return HttpResponse.json({
|
|
||||||
success: true,
|
|
||||||
body: [],
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
http.get('/api/arm/masters', () => {
|
|
||||||
return HttpResponse.json({
|
|
||||||
success: true,
|
|
||||||
body: [],
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
jest.mock('@brojs/cli', () => {
|
|
||||||
return {
|
|
||||||
getNavigationValue: () => '/auth/login',
|
|
||||||
getConfigValue: () => '/api',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('order page', () => {
|
|
||||||
beforeAll(() => server.listen());
|
|
||||||
afterEach(() => server.resetHandlers());
|
|
||||||
afterAll(() => server.close());
|
|
||||||
|
|
||||||
it('получение пустого списка', async () => {
|
|
||||||
render(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ChakraProvider theme={chakraTheme}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<BrowserRouter>
|
|
||||||
<Page mockUser={{ name: 'ilnaz' }} />
|
|
||||||
</BrowserRouter>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</ChakraProvider>
|
|
||||||
</Provider>,
|
|
||||||
);
|
|
||||||
|
|
||||||
await waitFor(() => screen.getByText('Список пуст'));
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,98 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import {
|
|
||||||
describe,
|
|
||||||
it,
|
|
||||||
jest,
|
|
||||||
beforeAll,
|
|
||||||
afterEach,
|
|
||||||
afterAll,
|
|
||||||
expect,
|
|
||||||
} from '@jest/globals';
|
|
||||||
import { render, screen, waitFor } from '@testing-library/react';
|
|
||||||
import { http, HttpResponse } from 'msw';
|
|
||||||
import { setupServer } from 'msw/node';
|
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
|
||||||
import { ChakraProvider, theme as chakraTheme } from '@chakra-ui/react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
|
|
||||||
import ErrorBoundary from '../../components/ErrorBoundary';
|
|
||||||
import { store } from '../../__data__/store';
|
|
||||||
import Page from '../arm';
|
|
||||||
import { PageSpinner } from '../../components';
|
|
||||||
|
|
||||||
const server = setupServer(
|
|
||||||
http.post('/api/arm/orders', () => {
|
|
||||||
return HttpResponse.json({}, { status: 500 });
|
|
||||||
}),
|
|
||||||
http.get('/api/arm/masters', () => {
|
|
||||||
return HttpResponse.json({
|
|
||||||
success: true,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
id: '4545423234',
|
|
||||||
name: 'Иван Иванов',
|
|
||||||
phone: '+7 900 123 45 67',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Олег Макаров',
|
|
||||||
phone: '79001234567',
|
|
||||||
id: '23423442',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '345354234',
|
|
||||||
name: 'Иван Галкин',
|
|
||||||
schedule: [
|
|
||||||
{
|
|
||||||
id: 'order1',
|
|
||||||
startWashTime: '2024-11-24T10:30:00.000Z',
|
|
||||||
endWashTime: '2024-11-24T16:30:00.000Z',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'order2',
|
|
||||||
startWashTime: '2024-11-24T11:30:00.000Z',
|
|
||||||
endWashTime: '2024-11-24T17:30:00.000Z',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
phone: '+7 900 123 45 67',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
jest.mock('@brojs/cli', () => {
|
|
||||||
return {
|
|
||||||
getNavigationValue: () => '/auth/login',
|
|
||||||
getConfigValue: () => '/api',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('order page', () => {
|
|
||||||
beforeAll(() => server.listen());
|
|
||||||
afterEach(() => server.resetHandlers());
|
|
||||||
afterAll(() => server.close());
|
|
||||||
|
|
||||||
it('обработка ошибки при загрузке данных', async () => {
|
|
||||||
render(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ChakraProvider theme={chakraTheme}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<BrowserRouter>
|
|
||||||
<Page mockUser={{ name: 'ilnaz' }} />
|
|
||||||
</BrowserRouter>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</ChakraProvider>
|
|
||||||
</Provider>,
|
|
||||||
);
|
|
||||||
|
|
||||||
await waitFor(() => screen.getByText('Ошибка при загрузке данных'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Routers', () => {
|
|
||||||
it('отображает PageSpinner ', async () => {
|
|
||||||
render(<PageSpinner />);
|
|
||||||
|
|
||||||
expect(await screen.findByTestId('spinner')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -21,7 +21,6 @@ import { Order } from '../../models/landing';
|
|||||||
import { landingApi } from '../../__data__/service/landing.api';
|
import { landingApi } from '../../__data__/service/landing.api';
|
||||||
import { isErrorMessage } from '../../models/api';
|
import { isErrorMessage } from '../../models/api';
|
||||||
import { FEATURE } from '../../__data__/features';
|
import { FEATURE } from '../../__data__/features';
|
||||||
import { CarImageForm } from '../../components/order-view/car-img';
|
|
||||||
|
|
||||||
const Page: FC = () => {
|
const Page: FC = () => {
|
||||||
const { t } = useTranslation('~', {
|
const { t } = useTranslation('~', {
|
||||||
@ -70,30 +69,24 @@ const Page: FC = () => {
|
|||||||
<>
|
<>
|
||||||
<>
|
<>
|
||||||
{isSuccess && (
|
{isSuccess && (
|
||||||
<VStack p={4} alignItems='flex-start' gap={4} data-testid='order-details'>
|
<OrderDetails
|
||||||
<OrderDetails
|
orderNumber={order.orderNumber}
|
||||||
orderNumber={order.orderNumber}
|
status={order.status}
|
||||||
status={order.status}
|
phone={order.phone}
|
||||||
phone={order.phone}
|
carNumber={order.carNumber}
|
||||||
carNumber={order.carNumber}
|
carBody={order.carBody}
|
||||||
carBody={order.carBody}
|
carColor={order.carColor}
|
||||||
carColor={order.carColor}
|
location={order.location}
|
||||||
location={order.location}
|
startWashTime={order.startWashTime}
|
||||||
startWashTime={order.startWashTime}
|
endWashTime={order.endWashTime}
|
||||||
endWashTime={order.endWashTime}
|
created={order.created}
|
||||||
created={order.created}
|
data-testid='order-details'
|
||||||
/>
|
/>
|
||||||
{FEATURE.carImageUpload.isOn && <CarImageForm orderId={orderId} />}
|
|
||||||
</VStack>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
<>
|
<>
|
||||||
{isError && (
|
{isError && (
|
||||||
<Alert
|
<Alert status='error' alignItems='flex-start' data-testid='error'>
|
||||||
status='error'
|
|
||||||
alignItems='flex-start'
|
|
||||||
data-testid='error'
|
|
||||||
>
|
|
||||||
<AlertIcon />
|
<AlertIcon />
|
||||||
<Box>
|
<Box>
|
||||||
<AlertTitle>
|
<AlertTitle>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/* 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 = { masters: 'success', orders: 'success', orderCreate: 'success', orderView: 'success-pending', orderCarImg: 'success' };
|
const STUBS = { masters: 'success', orders: 'success', orderCreate: 'success', orderView: 'success-pending' };
|
||||||
|
|
||||||
router.get('/set/:name/:value', (req, res) => {
|
router.get('/set/:name/:value', (req, res) => {
|
||||||
const { name, value } = req.params;
|
const { name, value } = req.params;
|
||||||
@ -15,34 +15,28 @@ router.get('/set/:name/:value', (req, res) => {
|
|||||||
router.get('/', (req, res) => {
|
router.get('/', (req, res) => {
|
||||||
res.send(`<div>
|
res.send(`<div>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Мастера</legend>
|
<legend>Мастера</legend>
|
||||||
${generateRadioInput('masters', 'success')}
|
${generateRadioInput('masters', 'success')}
|
||||||
${generateRadioInput('masters', 'error')}
|
${generateRadioInput('masters', 'error')}
|
||||||
${generateRadioInput('masters', 'empty')}
|
${generateRadioInput('masters', 'empty')}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Заказы</legend>
|
<legend>Заказы</legend>
|
||||||
${generateRadioInput('orders', 'success')}
|
${generateRadioInput('orders', 'success')}
|
||||||
${generateRadioInput('orders', 'error')}
|
${generateRadioInput('orders', 'error')}
|
||||||
${generateRadioInput('orders', 'empty')}
|
${generateRadioInput('orders', 'empty')}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Лендинг - Сделать заказ</legend>
|
<legend>Лендинг - Сделать заказ</legend>
|
||||||
${generateRadioInput('orderCreate', 'success')}
|
${generateRadioInput('orderCreate', 'success')}
|
||||||
${generateRadioInput('orderCreate', 'error')}
|
${generateRadioInput('orderCreate', 'error')}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Лендинг - Детали заказа</legend>
|
<legend>Лендинг - Детали заказа</legend>
|
||||||
${generateRadioInput('orderView', 'success-pending')}
|
${generateRadioInput('orderView', 'success-pending')}
|
||||||
${generateRadioInput('orderView', 'success-working')}
|
${generateRadioInput('orderView', 'success-working')}
|
||||||
${generateRadioInput('orderView', 'error')}
|
${generateRadioInput('orderView', 'error')}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
|
||||||
<legend>Лендинг - Детали заказа, фото машины</legend>
|
|
||||||
${generateRadioInput('orderCarImg', 'success')}
|
|
||||||
${generateRadioInput('orderCarImg', 'error-file-type')}
|
|
||||||
${generateRadioInput('orderCarImg', 'error-file-size')}
|
|
||||||
</fieldset>
|
|
||||||
</div>`);
|
</div>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -98,22 +98,6 @@ router.post('/order/create', (req, res) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/order/:orderId/upload-car-img', (req, res) => {
|
|
||||||
const { orderId } = req.params;
|
|
||||||
const stubName = `${orderId}-${STUBS.orderCarImg}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
res
|
|
||||||
.status(/error/.test(stubName) ? 500 : 200)
|
|
||||||
.send(require(`../json/landing-order-car-image-upload/${stubName}.json`));
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
res
|
|
||||||
.status(500)
|
|
||||||
.send(commonError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.use('/admin', require('./admin'));
|
router.use('/admin', require('./admin'));
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "Invalid car image file size. Limit is 5MB"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "Invalid car image file type. Allowed types: jpg, png"
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"success": true
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"success": false,
|
"success": false,
|
||||||
"error": "Не удалось создать заказ"
|
"message": "Не удалось создать заказ"
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"success": false,
|
"success": false,
|
||||||
"error": "Не удалось загрузить детали заказа"
|
"message": "Не удалось загрузить детали заказа"
|
||||||
}
|
}
|
@ -21,5 +21,5 @@
|
|||||||
"**/*.test.ts",
|
"**/*.test.ts",
|
||||||
"**/*.test.tsx",
|
"**/*.test.tsx",
|
||||||
"node_modules/@types/jest"
|
"node_modules/@types/jest"
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user