test (access && tariffs) create
This commit is contained in:
parent
3920ccebfd
commit
ec148d261e
11
cypress.config.ts
Normal file
11
cypress.config.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { defineConfig } from "cypress";
|
||||
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
viewportWidth: 1200,
|
||||
viewportHeight: 800,
|
||||
fixturesFolder: "tests/e2e/fixtures",
|
||||
supportFile: false,
|
||||
defaultCommandTimeout: 100,
|
||||
},
|
||||
});
|
110
cypress/e2e/access.cy.ts
Normal file
110
cypress/e2e/access.cy.ts
Normal file
@ -0,0 +1,110 @@
|
||||
describe("Форма Входа", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("http://localhost:3000");
|
||||
});
|
||||
|
||||
it("должна успешно входить с правильными учетными данными", () => {
|
||||
const email = "valid_user@example.com";
|
||||
const password = "valid_password";
|
||||
|
||||
cy.get('input[name="email"]').type(email);
|
||||
cy.get('input[name="password"]').type(password);
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.url().should("include", "http://localhost:3000/users");
|
||||
});
|
||||
|
||||
it("должна отображать сообщение об ошибке при неверном формате электронной почты", () => {
|
||||
const invalidEmail = "invalid_email";
|
||||
|
||||
cy.get('input[name="email"]').type(invalidEmail);
|
||||
cy.get('input[name="password"]').type("valid_password");
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.contains("Неверный формат эл. почты");
|
||||
});
|
||||
|
||||
it("должна отображать сообщение об ошибке при отсутствии пароля", () => {
|
||||
cy.get('input[name="email"]').type("valid_email@example.com");
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.contains("Введите пароль");
|
||||
});
|
||||
|
||||
it("должна отображать сообщение об ошибке для недопустимого пароля", () => {
|
||||
const invalidPassword = "short";
|
||||
|
||||
cy.get('input[name="email"]').type("valid_email@example.com");
|
||||
cy.get('input[name="password"]').type(invalidPassword);
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.contains("Invalid password");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Форма регистрации", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("http://localhost:3000/signup");
|
||||
});
|
||||
|
||||
it("должна регистрировать нового пользователя с правильными данными", () => {
|
||||
const email = Cypress._.random(1000) + "@example.com";
|
||||
const password = "valid_password";
|
||||
|
||||
cy.get('input[name="email"]').type(email);
|
||||
cy.get('input[name="password"]').type(password);
|
||||
cy.get('input[name="repeatPassword"]').type(password);
|
||||
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.wait(5000);
|
||||
|
||||
cy.url().should("include", "http://localhost:3000/users");
|
||||
});
|
||||
|
||||
it("должна отображать ошибку при неверном формате электронной почты", () => {
|
||||
const invalidEmail = "invalid_email";
|
||||
|
||||
cy.get('input[name="email"]').type(invalidEmail);
|
||||
cy.get('input[name="password"]').type("valid_password");
|
||||
cy.get('input[name="repeatPassword"]').type("valid_password");
|
||||
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.contains("Неверный формат эл. почты");
|
||||
});
|
||||
|
||||
it("должна отображать ошибку при отсутствии пароля", () => {
|
||||
cy.get('input[name="email"]').type("valid_email@example.com");
|
||||
cy.get('input[name="repeatPassword"]').type("valid_password");
|
||||
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.contains("Обязательное поле").should("have.length", 1);
|
||||
});
|
||||
|
||||
it("должна отображать ошибку при несовпадении паролей", () => {
|
||||
cy.get('input[name="email"]').type("valid_email@example.com");
|
||||
cy.get('input[name="password"]').type("valid_password");
|
||||
cy.get('input[name="repeatPassword"]').type("different_password");
|
||||
|
||||
cy.get('button[type="submit"]').click();
|
||||
|
||||
cy.contains("Пароли не совпадают");
|
||||
});
|
||||
|
||||
it("попытка отправки запроса при уже зарегистрированном пользователе", () => {
|
||||
const email = "users@gmail.com";
|
||||
const password = "12344321";
|
||||
|
||||
cy.get('input[name="email"]').type(email);
|
||||
cy.get('input[name="password"]').type(password);
|
||||
cy.get('input[name="repeatPassword"]').type(password);
|
||||
|
||||
cy.intercept("POST", "https://admin.pena.digital/auth/register").as("registerRequest");
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.wait("@registerRequest");
|
||||
|
||||
cy.wait(5000);
|
||||
cy.contains("user with this login is exist");
|
||||
});
|
||||
});
|
195
cypress/e2e/tariffs.cy.ts
Normal file
195
cypress/e2e/tariffs.cy.ts
Normal file
@ -0,0 +1,195 @@
|
||||
describe("Форма Создания Тарифа", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("http://localhost:3000");
|
||||
cy.get('input[name="email"]').type("valid_user@example.com");
|
||||
cy.get('input[name="password"]').type("valid_password");
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.wait(3000);
|
||||
cy.url().should("include", "http://localhost:3000/users");
|
||||
cy.visit("http://localhost:3000/tariffs");
|
||||
});
|
||||
|
||||
it("должна отображать сообщение об ошибке при пустом названии тарифа", () => {
|
||||
cy.get('input[id="tariff-amount"]').type("10");
|
||||
|
||||
// Выбрать первую привилегию с нужным текстом из выпадающего списка
|
||||
cy.get("#privilege-select").click();
|
||||
|
||||
cy.get(`[data-cy = "select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click();
|
||||
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.contains("Пустое название тарифа");
|
||||
});
|
||||
|
||||
it("должна отображать сообщение об ошибке при отсутствии выбора привилегии", () => {
|
||||
cy.get('input[id="tariff-name"]').type("Тестовый Тариф");
|
||||
cy.get('input[id="tariff-amount"]').type("10");
|
||||
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.contains("Не выбрана привилегия");
|
||||
});
|
||||
|
||||
it("Создание трех тарифов", () => {
|
||||
cy.get('input[id="tariff-name"]').type("Тестовый Тариф 1");
|
||||
cy.get('input[id="tariff-amount"]').type("10");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.get(`[data-cy="select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 2");
|
||||
cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("15");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.wait(800);
|
||||
cy.get(`[data-cy="select-option-Количество дней, в течении которых пользование сервисом безлимитно"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 3");
|
||||
cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("20");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.wait(800);
|
||||
cy.get(`[data-cy="select-option-Обьём ПенаДиска для хранения шаблонов и результатов шаблонизации"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe("Форма Создания Тарифа", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("http://localhost:3000");
|
||||
cy.get('input[name="email"]').type("valid_user@example.com");
|
||||
cy.get('input[name="password"]').type("valid_password");
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.wait(3000);
|
||||
cy.url().should("include", "http://localhost:3000/users");
|
||||
cy.visit("http://localhost:3000/tariffs");
|
||||
});
|
||||
|
||||
it("Удаление тарифа единично, одного за другим ", () => {
|
||||
const tariffNamesToFind = ["Тестовый Тариф 1", "Тестовый Тариф 2", "Тестовый Тариф 3"];
|
||||
|
||||
// Поиск каждого тарифа в DataGrid
|
||||
cy.wait(3000);
|
||||
tariffNamesToFind.forEach((tariffName) => {
|
||||
cy.get(".tariffs-data-grid").scrollIntoView().contains(tariffName).should("be.visible");
|
||||
});
|
||||
|
||||
const deleteTariffs = () => {
|
||||
let tariffsFound = true;
|
||||
|
||||
cy.get(".tariffs-data-grid .MuiDataGrid-row").then(($rows) => {
|
||||
const rowCount = $rows.length;
|
||||
|
||||
if (rowCount === 1) {
|
||||
cy.log("Тарифы не найдены. Тест завершен.");
|
||||
tariffsFound = false;
|
||||
}
|
||||
|
||||
cy.wrap($rows).each(($row) => {
|
||||
// Шаг 2: В каждом элементе найдите все дивы вложенные внутрь и выберите последний див
|
||||
cy.wrap($row).find("div").last().scrollIntoView().get(".delete-tariff-button").last().click({ force: true });
|
||||
});
|
||||
|
||||
cy.wait(2000);
|
||||
cy.contains("Да")
|
||||
.click()
|
||||
.then(() => {
|
||||
if (!tariffsFound) {
|
||||
return;
|
||||
}
|
||||
|
||||
cy.wait(5000);
|
||||
deleteTariffs();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
deleteTariffs();
|
||||
|
||||
// Проверяем что Дата грид тарифов пустой
|
||||
cy.wait(2000);
|
||||
cy.get(".tariffs-data-grid .MuiDataGrid-row").should("not.exist");
|
||||
});
|
||||
|
||||
describe("Форма Создания Тарифа", () => {});
|
||||
|
||||
it("Удаление тарифов массово через DataGrid", () => {
|
||||
// Добавляем 3 тариффа
|
||||
cy.get('input[id="tariff-name"]').type("Тестовый Тариф 1");
|
||||
cy.get('input[id="tariff-amount"]').type("10");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.get(`[data-cy="select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 2");
|
||||
cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("15");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.wait(800);
|
||||
cy.get(`[data-cy="select-option-Количество дней, в течении которых пользование сервисом безлимитно"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 3");
|
||||
cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("20");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.wait(800);
|
||||
cy.get(`[data-cy="select-option-Обьём ПенаДиска для хранения шаблонов и результатов шаблонизации"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
// Добавляем 3 тариффа
|
||||
|
||||
cy.wait(3000);
|
||||
cy.get(".tariffs-data-grid .PrivateSwitchBase-input").first().click({ multiple: true });
|
||||
|
||||
// Проверить, что кнопка "Удалить" появилась
|
||||
cy.wait(2000);
|
||||
cy.contains("Удаление").should("be.visible");
|
||||
|
||||
// Нажать на кнопку "Удалить"
|
||||
cy.contains("Удаление").click();
|
||||
|
||||
// Подтверждение удаления (если нужно)
|
||||
cy.contains("Да").click();
|
||||
|
||||
// Проверяем что Дата грид тарифов пустой
|
||||
cy.wait(2000);
|
||||
cy.get(".tariffs-data-grid .MuiDataGrid-row").should("not.exist");
|
||||
});
|
||||
|
||||
it("Добавление тарифом в корзину", () => {
|
||||
// Добавляем 3 тариффа
|
||||
|
||||
cy.get('input[id="tariff-name"]').type("Тестовый Тариф 1");
|
||||
cy.get('input[id="tariff-amount"]').type("10");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.get(`[data-cy="select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 2");
|
||||
cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("15");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.wait(800);
|
||||
cy.get(`[data-cy="select-option-Количество дней, в течении которых пользование сервисом безлимитно"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
|
||||
cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 3");
|
||||
cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("20");
|
||||
cy.get("#privilege-select").click();
|
||||
cy.wait(800);
|
||||
cy.get(`[data-cy="select-option-Обьём ПенаДиска для хранения шаблонов и результатов шаблонизации"]`).click();
|
||||
cy.get(".btn_createTariffBackend").click({ force: true });
|
||||
// Добавляем 3 тариффа
|
||||
|
||||
cy.wait(3000);
|
||||
cy.get(".tariffs-data-grid .PrivateSwitchBase-input").first().click({ multiple: true });
|
||||
|
||||
// Проверить, что кнопка "Удалить" появилась
|
||||
cy.wait(2000);
|
||||
cy.contains("рассчитать").should("be.visible");
|
||||
|
||||
// Нажать на кнопку "Удалить"
|
||||
cy.contains("рассчитать").click();
|
||||
|
||||
// смотрим что в корзине ровно столько тарифом, сколько мы добовляли
|
||||
cy.wait(5000);
|
||||
cy.get(".MuiTable-root tbody tr").its("length").should("eq", 3);
|
||||
});
|
||||
});
|
@ -24,6 +24,7 @@
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"axios": "^1.3.4",
|
||||
"craco": "^0.0.3",
|
||||
"cypress": "^12.17.2",
|
||||
"dayjs": "^1.11.5",
|
||||
"formik": "^2.2.9",
|
||||
"immer": "^10.0.2",
|
||||
@ -37,6 +38,7 @@
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"reconnecting-eventsource": "^1.6.2",
|
||||
"start-server-and-test": "^2.0.0",
|
||||
"styled-components": "^5.3.5",
|
||||
"typescript": "^4.8.2",
|
||||
"web-vitals": "^2.1.4",
|
||||
@ -47,6 +49,8 @@
|
||||
"build": "craco build",
|
||||
"test": "craco test",
|
||||
"test:cart": "craco test src/kitUI/Cart --watchAll=false",
|
||||
"test:cypress": "start-server-and-test start http://localhost:3000 cypress",
|
||||
"cypress": "cypress open",
|
||||
"eject": "craco eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { styled } from "@mui/material/styles";
|
||||
import { TextField} from "@mui/material";
|
||||
import { TextField } from "@mui/material";
|
||||
export default styled(TextField)(({ theme }) => ({
|
||||
color: theme.palette.grayLight.main,
|
||||
"& .MuiInputLabel-root": {
|
||||
color: theme.palette.grayLight.main,
|
||||
},
|
||||
"& .MuiFilledInput-root": {
|
||||
border: theme.palette.grayLight.main+" 1px solid",
|
||||
border: theme.palette.grayLight.main + " 1px solid",
|
||||
borderRadius: "0",
|
||||
backgroundColor: theme.palette.hover.main,
|
||||
color: theme.palette.grayLight.main,
|
||||
}
|
||||
},
|
||||
|
||||
"& .MuiFilledInput-root.Mui-error": {
|
||||
fontSize: "8px",
|
||||
},
|
||||
}));
|
@ -19,11 +19,13 @@ function validate(values: Values) {
|
||||
const errors = {} as any;
|
||||
|
||||
if (!values.email) {
|
||||
errors.email = "Required";
|
||||
errors.email = "Обязательное поле";
|
||||
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) {
|
||||
errors.email = "Неверный формат эл. почты";
|
||||
}
|
||||
|
||||
if (!values.password) {
|
||||
errors.password = "Required";
|
||||
errors.password = "Введите пароль";
|
||||
}
|
||||
|
||||
if (values.password && !/^[\S]{8,25}$/i.test(values.password)) {
|
||||
@ -107,11 +109,34 @@ const SigninForm = () => {
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", marginTop: "15px", "> *": { marginRight: "10px" } }}>
|
||||
<EmailOutlinedIcon htmlColor={theme.palette.golden.main} />
|
||||
<Field as={OutlinedInput} name="email" variant="filled" label="Эл. почта" />
|
||||
<Field
|
||||
as={OutlinedInput}
|
||||
name="email"
|
||||
variant="filled"
|
||||
label="Эл. почта"
|
||||
error={props.touched.email && !!props.errors.email}
|
||||
helperText={
|
||||
<Typography sx={{ fontSize: "12px", width: "200px" }}>
|
||||
{props.touched.email && props.errors.email}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", marginTop: "15px", "> *": { marginRight: "10px" } }}>
|
||||
<LockOutlinedIcon htmlColor={theme.palette.golden.main} />
|
||||
<Field as={OutlinedInput} type="password" name="password" variant="filled" label="Пароль" />
|
||||
<Field
|
||||
as={OutlinedInput}
|
||||
type="password"
|
||||
name="password"
|
||||
variant="filled"
|
||||
label="Пароль"
|
||||
error={props.touched.password && !!props.errors.password}
|
||||
helperText={
|
||||
<Typography sx={{ fontSize: "12px", width: "200px" }}>
|
||||
{props.touched.password && props.errors.password}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
component="article"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { enqueueSnackbar, useSnackbar } from "notistack";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { Formik, Field, Form } from "formik";
|
||||
@ -10,30 +10,39 @@ import Logo from "@pages/Logo/index";
|
||||
import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined";
|
||||
import LockOutlinedIcon from "@mui/icons-material/LockOutlined";
|
||||
import { authStore } from "@root/stores/auth";
|
||||
|
||||
interface Values {
|
||||
email: string;
|
||||
password: string;
|
||||
repeatPassword: string;
|
||||
}
|
||||
|
||||
function validate(values: Values) {
|
||||
const errors = {} as any;
|
||||
const errors: Partial<Values> = {};
|
||||
|
||||
if (!values.email) {
|
||||
errors.login = "Required";
|
||||
errors.email = "Обязательное поле";
|
||||
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) {
|
||||
errors.email = "Неверный формат эл. почты";
|
||||
}
|
||||
|
||||
if (!values.password) {
|
||||
errors.password = "Required";
|
||||
errors.password = "Обязательное поле";
|
||||
} else if (!/^[\S]{8,25}$/i.test(values.password)) {
|
||||
errors.password = "Invalid password";
|
||||
errors.password = "Неверный пароль";
|
||||
}
|
||||
if (values.password !== values.repeatPassword) {
|
||||
errors.repeatPassword = "Passwords do not match";
|
||||
errors.repeatPassword = "Пароли не совпадают";
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
const SignUp = () => {
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
const { makeRequest } = authStore();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
return (
|
||||
<Formik
|
||||
@ -61,14 +70,16 @@ const SignUp = () => {
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
enqueueSnackbar(
|
||||
e.response && e.response.data && e.response.data.message ? e.response.data.message : `Unknown error`
|
||||
e.response && e.response.data && e.response.data.message ? e.response.data.message : `Unknown error`,
|
||||
{ variant: "error" } // Устанавливаем вариант уведомления на "error"
|
||||
);
|
||||
}).finally(() => {
|
||||
})
|
||||
.finally(() => {
|
||||
formikHelpers.setSubmitting(false);
|
||||
});
|
||||
}}
|
||||
>
|
||||
{props =>
|
||||
{(props) => (
|
||||
<Form>
|
||||
<Box
|
||||
component="section"
|
||||
@ -111,11 +122,37 @@ const SignUp = () => {
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", marginTop: "15px", "> *": { marginRight: "10px" } }}>
|
||||
<EmailOutlinedIcon htmlColor={theme.palette.golden.main} />
|
||||
<Field as={OutlinedInput} name="email" variant="filled" label="Эл. почта" />
|
||||
<Field
|
||||
as={OutlinedInput}
|
||||
name="email"
|
||||
variant="filled"
|
||||
label="Эл. почта"
|
||||
id="email"
|
||||
error={props.touched.email && !!props.errors.email}
|
||||
helperText={
|
||||
<Typography sx={{ fontSize: "12px", width: "200px" }}>
|
||||
{props.touched.email && props.errors.email}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", marginTop: "15px", "> *": { marginRight: "10px" } }}>
|
||||
<LockOutlinedIcon htmlColor={theme.palette.golden.main} />
|
||||
<Field as={OutlinedInput} type="password" name="password" variant="filled" label="Пароль" />
|
||||
<Field
|
||||
sx={{}}
|
||||
as={OutlinedInput}
|
||||
type="password"
|
||||
name="password"
|
||||
variant="filled"
|
||||
label="Пароль"
|
||||
id="password"
|
||||
error={props.touched.password && !!props.errors.password}
|
||||
helperText={
|
||||
<Typography sx={{ fontSize: "12px", width: "200px" }}>
|
||||
{props.touched.password && props.errors.password}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", marginTop: "15px", "> *": { marginRight: "10px" } }}>
|
||||
<LockOutlinedIcon htmlColor={theme.palette.golden.main} />
|
||||
@ -125,6 +162,13 @@ const SignUp = () => {
|
||||
name="repeatPassword"
|
||||
variant="filled"
|
||||
label="Повторите пароль"
|
||||
id="repeatPassword"
|
||||
error={props.touched.repeatPassword && !!props.errors.repeatPassword}
|
||||
helperText={
|
||||
<Typography sx={{ fontSize: "12px", width: "200px" }}>
|
||||
{props.touched.repeatPassword && props.errors.repeatPassword}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Button
|
||||
@ -136,14 +180,16 @@ const SignUp = () => {
|
||||
padding: "20px 30px",
|
||||
fontSize: 18,
|
||||
}}
|
||||
>Войти</Button>
|
||||
>
|
||||
Войти
|
||||
</Button>
|
||||
<Link to="/signin" style={{ textDecoration: "none" }}>
|
||||
<Typography color={theme.palette.golden.main}>У меня уже есть аккаунт</Typography>
|
||||
</Link>
|
||||
</Box>
|
||||
</Box>
|
||||
</Form>
|
||||
}
|
||||
)}
|
||||
</Formik>
|
||||
);
|
||||
};
|
||||
|
@ -1,25 +1,12 @@
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Typography,
|
||||
Container,
|
||||
Button,
|
||||
Select,
|
||||
MenuItem,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
useTheme,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
import { Typography, Container, Button, Select, MenuItem, FormControl, InputLabel, useTheme, Box } from "@mui/material";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
import { CustomTextField } from "@root/kitUI/CustomTextField";
|
||||
import { requestTariffs } from "@root/services/tariffs.service";
|
||||
|
||||
import { authStore } from "@root/stores/auth";
|
||||
import {
|
||||
findPrivilegeById,
|
||||
usePrivilegeStore,
|
||||
} from "@root/stores/privilegesStore";
|
||||
import { findPrivilegeById, usePrivilegeStore } from "@root/stores/privilegesStore";
|
||||
|
||||
import type { Privilege_BACKEND } from "@root/model/tariff";
|
||||
|
||||
@ -30,10 +17,7 @@ type CreateTariffBackendRequest = {
|
||||
privilegies: Omit<Privilege_BACKEND, "_id" | "updatedAt">[];
|
||||
};
|
||||
|
||||
const baseUrl =
|
||||
process.env.NODE_ENV === "production"
|
||||
? "/strator"
|
||||
: "https://admin.pena.digital/strator";
|
||||
const baseUrl = process.env.NODE_ENV === "production" ? "/strator" : "https://admin.pena.digital/strator";
|
||||
|
||||
export default function CreateTariff() {
|
||||
const { makeRequest } = authStore();
|
||||
@ -170,7 +154,11 @@ export default function CreateTariff() {
|
||||
inputProps={{ sx: { pt: "12px" } }}
|
||||
>
|
||||
{privileges.map((privilege) => (
|
||||
<MenuItem key={privilege.description} value={privilege.id}>
|
||||
<MenuItem
|
||||
data-cy={`select-option-${privilege.description}`}
|
||||
key={privilege.description}
|
||||
value={privilege.id}
|
||||
>
|
||||
{privilege.description}
|
||||
</MenuItem>
|
||||
))}
|
||||
@ -218,6 +206,8 @@ export default function CreateTariff() {
|
||||
type="number"
|
||||
/>
|
||||
<Button
|
||||
className="btn_createTariffBackend"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
createTariffBackend();
|
||||
}}
|
||||
|
@ -26,17 +26,9 @@ type EditTariffBackendRequest = {
|
||||
privilegies: Omit<Privilege_BACKEND, "_id" | "updatedAt">[];
|
||||
};
|
||||
|
||||
const baseUrl =
|
||||
process.env.NODE_ENV === "production"
|
||||
? "/strator"
|
||||
: "https://admin.pena.digital/strator";
|
||||
const baseUrl = process.env.NODE_ENV === "production" ? "/strator" : "https://admin.pena.digital/strator";
|
||||
|
||||
const editTariff = ({
|
||||
tarifIid,
|
||||
tariffName,
|
||||
tariffPrice,
|
||||
privilege,
|
||||
}: EditProps): Promise<unknown> => {
|
||||
const editTariff = ({ tarifIid, tariffName, tariffPrice, privilege }: EditProps): Promise<unknown> => {
|
||||
const { makeRequest } = authStore.getState();
|
||||
|
||||
return makeRequest<EditTariffBackendRequest>({
|
||||
@ -87,12 +79,7 @@ export default function EditModal({ tariff = undefined }: Props) {
|
||||
p: 4,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
id="modal-modal-title"
|
||||
variant="h6"
|
||||
component="h2"
|
||||
sx={{ whiteSpace: "nowrap" }}
|
||||
>
|
||||
<Typography id="modal-modal-title" variant="h6" component="h2" sx={{ whiteSpace: "nowrap" }}>
|
||||
Редактирование тариффа
|
||||
</Typography>
|
||||
|
||||
@ -106,9 +93,7 @@ export default function EditModal({ tariff = undefined }: Props) {
|
||||
value={name}
|
||||
sx={{ marginBottom: "10px" }}
|
||||
/>
|
||||
<Typography>
|
||||
Цена за единицу: {currentTariff.pricePerUnit}
|
||||
</Typography>
|
||||
<Typography>Цена за единицу: {currentTariff.pricePerUnit}</Typography>
|
||||
<TextField
|
||||
onChange={(event) => setPrice(event.target.value)}
|
||||
label="Цена за единицу"
|
||||
@ -119,9 +104,7 @@ export default function EditModal({ tariff = undefined }: Props) {
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (!currentTariff.isFront) {
|
||||
const privilege = findPrivilegeById(
|
||||
currentTariff.privilegeId
|
||||
);
|
||||
const privilege = findPrivilegeById(currentTariff.privilegeId);
|
||||
privilege.privilegeId = privilege.id;
|
||||
console.log(privilege);
|
||||
|
||||
@ -136,11 +119,7 @@ export default function EditModal({ tariff = undefined }: Props) {
|
||||
editTariff({
|
||||
tarifIid: currentTariff.id,
|
||||
tariffName: name ? name : currentTariff.name,
|
||||
tariffPrice: price
|
||||
? Number(price)
|
||||
: currentTariff.price
|
||||
? currentTariff.price
|
||||
: privilege.price,
|
||||
tariffPrice: price ? Number(price) : currentTariff.price ? currentTariff.price : privilege.price,
|
||||
isDeleted: currentTariff.isDeleted,
|
||||
customPricePerUnit: currentTariff.price,
|
||||
privilege: privilege,
|
||||
|
@ -22,10 +22,7 @@ interface Props {
|
||||
handleSelectionChange: (selectionModel: GridSelectionModel) => void;
|
||||
}
|
||||
|
||||
export default function TariffsDG({
|
||||
selectedTariffs,
|
||||
handleSelectionChange,
|
||||
}: Props) {
|
||||
export default function TariffsDG({ selectedTariffs, handleSelectionChange }: Props) {
|
||||
const tariffs = useTariffStore((state) => state.tariffs);
|
||||
const [openDeleteModal, setOpenDeleteModal] = useState(false);
|
||||
const [changingTariff, setChangingTariff] = useState<Tariff | undefined>();
|
||||
@ -39,15 +36,10 @@ export default function TariffsDG({
|
||||
return {
|
||||
id: tariff.id,
|
||||
name: tariff.name,
|
||||
serviceName:
|
||||
privilege?.serviceKey == "templategen"
|
||||
? "Шаблонизатор"
|
||||
: privilege?.serviceKey,
|
||||
serviceName: privilege?.serviceKey == "templategen" ? "Шаблонизатор" : privilege?.serviceKey,
|
||||
privilegeName: privilege?.name,
|
||||
amount: tariff.amount,
|
||||
pricePerUnit: tariff.isCustom
|
||||
? (tariff.customPricePerUnit || 0) / 100
|
||||
: (tariff?.price || 0) / 100,
|
||||
pricePerUnit: tariff.isCustom ? (tariff.customPricePerUnit || 0) / 100 : (tariff?.price || 0) / 100,
|
||||
type:
|
||||
findPrivilegeById(tariff.privilegeId)?.value === "шаблон"
|
||||
? "штука"
|
||||
@ -67,8 +59,6 @@ export default function TariffsDG({
|
||||
setGridData(data);
|
||||
}, [tariffs]);
|
||||
|
||||
console.log(selectedTariffs);
|
||||
|
||||
const closeDeleteModal = () => {
|
||||
setOpenDeleteModal(false);
|
||||
};
|
||||
@ -102,6 +92,7 @@ export default function TariffsDG({
|
||||
renderCell: ({ row }) => {
|
||||
return (
|
||||
<IconButton
|
||||
className="delete-tariff-button"
|
||||
onClick={() => {
|
||||
setOpenDeleteModal(row.id);
|
||||
}}
|
||||
@ -113,8 +104,6 @@ export default function TariffsDG({
|
||||
},
|
||||
];
|
||||
|
||||
// console.log(gridData)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="обновить список тарифов">
|
||||
@ -123,6 +112,7 @@ export default function TariffsDG({
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<DataGrid
|
||||
className="tariffs-data-grid"
|
||||
disableSelectionOnClick={true}
|
||||
checkboxSelection={true}
|
||||
rows={gridData}
|
||||
@ -141,10 +131,7 @@ export default function TariffsDG({
|
||||
mb: "30px",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
onClick={() => setOpenDeleteModal(true)}
|
||||
sx={{ mr: "20px", zIndex: "10000" }}
|
||||
>
|
||||
<Button onClick={() => setOpenDeleteModal(true)} sx={{ mr: "20px", zIndex: "10000" }}>
|
||||
Удаление
|
||||
</Button>
|
||||
</Box>
|
||||
|
@ -2,11 +2,7 @@
|
||||
"extends": "./tsconfig.extend.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
@ -19,9 +15,10 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
"jsx": "react-jsx",
|
||||
"types": ["node"],
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
"include": ["src", "**/*.ts"]
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user