diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0bfacb3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +/build +Makefile +README.md +compose.yml +/.git diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..72a3692 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,38 @@ +include: + - project: "devops/pena-continuous-integration" + file: "/templates/docker/build-template.gitlab-ci.yml" + - project: "devops/pena-continuous-integration" + file: "/templates/docker/clean-template.gitlab-ci.yml" + - project: "devops/pena-continuous-integration" + file: "/templates/docker/deploy-template.gitlab-ci.yml" +stages: + - clean + - build + - deploy + +clear-old-images: + extends: .clean_template + variables: + STAGING_BRANCH: "main" + PRODUCTION_BRANCH: "main" + image: + name: docker/compose:1.28.0 + entrypoint: [""] + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker images + script: + - docker system prune -af +build-app: + extends: .build_template + variables: + DOCKER_BUILD_PATH: "./Dockerfile" + STAGING_BRANCH: "main" + PRODUCTION_BRANCH: "main" + +deploy-to-staging: + extends: .deploy_template + variables: + DEPLOY_TO: "staging" + BRANCH: "main" + diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 842b505..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "typescript.enablePromptUseWorkspaceTsdk": true, - "typescript.tsdk": "node_modules/typescript/lib" - } \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9a55e55 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM node:20.10-alpine3.18 as build + +RUN apk update && rm -rf /var/cache/apk/* +WORKDIR /usr/app +COPY . . + +RUN yarn install --ignore-scripts --non-interactive --frozen-lockfile && yarn cache clean +RUN yarn build + + +FROM nginx:latest as result +WORKDIR /usr/share/nginx/html +COPY --from=build /usr/app/build/ /usr/share/nginx/html +COPY hub.conf /etc/nginx/conf.d/default.conf diff --git a/README.md b/README.md deleted file mode 100644 index c55262d..0000000 --- a/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# SquzAnswerer - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://penahub.gitlab.yandexcloud.net/frontend/squzanswerer.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://penahub.gitlab.yandexcloud.net/frontend/squzanswerer/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/craco.config.js b/craco.config.js old mode 100644 new mode 100755 diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 0000000..87067ad --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from "cypress"; + +export default defineConfig({ + e2e: { + baseUrl: 'http://localhost:3000', + viewportWidth: 1440, + viewportHeight: 900, + supportFile: false, + }, +}); diff --git a/deployments/staging/docker-compose.yaml b/deployments/staging/docker-compose.yaml new file mode 100644 index 0000000..4a851e2 --- /dev/null +++ b/deployments/staging/docker-compose.yaml @@ -0,0 +1,13 @@ +services: + squiz: + container_name: squiz + restart: unless-stopped + image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID + networks: + - marketplace_penahub_frontend + hostname: squiz + tty: true +networks: + marketplace_penahub_frontend: + external: true + diff --git a/hub.conf b/hub.conf new file mode 100644 index 0000000..a3a8e51 --- /dev/null +++ b/hub.conf @@ -0,0 +1,12 @@ +server { + listen 80; + server_name _; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + root /usr/share/nginx/html; +} diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 01e7eea..a650129 --- a/package.json +++ b/package.json @@ -1,53 +1,63 @@ { - "name": "squzanswerer", - "version": "1.0.0", - "private": true, - "repository": "git@penahub.gitlab.yandexcloud.net:frontend/squzanswerer.git", - "author": "ryletd", - "license": "MIT", - "dependencies": { - "@craco/craco": "^7.1.0", - "@emotion/react": "^11.11.1", - "@emotion/styled": "^11.11.0", - "@frontend/kitui": "^1.0.54", - "@mui/icons-material": "^5.15.0", - "@mui/material": "^5.15.0", - "@mui/x-date-pickers": "^6.18.4", - "axios": "^1.6.2", - "dayjs": "^1.11.10", - "notistack": "^3.0.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-rnd": "^10.4.1", - "react-router-dom": "^6.21.0", - "react-scripts": "^5.0.1", - "swr": "^2.2.4", - "typescript": "^5.3.3", - "use-debounce": "^10.0.0", - "zustand": "^4.4.7" - }, - "devDependencies": { - "@emoji-mart/data": "^1.1.2", - "@emoji-mart/react": "^1.1.1", - "@types/node": "^20.10.4", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.18", - "craco-alias": "^3.0.1" - }, - "scripts": { - "start": "craco start", - "build": "craco build" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } + "name": "squidward", + "version": "0.1.0", + "private": true, + "dependencies": { + "@craco/craco": "^7.0.0", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@frontend/kitui": "^1.0.54", + "@mui/icons-material": "^5.10.14", + "@mui/material": "^5.10.14", + "@mui/x-date-pickers": "^6.16.1", + "@types/node": "^16.7.13", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "axios": "^1.5.1", + "dayjs": "^1.11.10", + "emoji-mart": "^5.5.2", + "formik": "^2.4.5", + "immer": "^10.0.3", + "nanoid": "^5.0.3", + "notistack": "^3.0.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.11", + "react-router-dom": "^6.6.2", + "react-scripts": "5.0.1", + "swr": "^2.2.4", + "typescript": "^5.2.2", + "use-debounce": "^9.0.4", + "web-vitals": "^2.1.0", + "yup": "^1.3.2", + "zustand": "^4.3.8" + }, + "scripts": { + "start": "craco start", + "build": "craco build", + "test": "craco test", + "eject": "craco eject", + "cypress:open": "cypress open" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@emoji-mart/data": "^1.1.2", + "@emoji-mart/react": "^1.1.1", + "@types/cytoscape-popper": "^2.0.4", + "@types/react-beautiful-dnd": "^13.1.4", + "@types/react-cytoscapejs": "^1.2.4", + "craco-alias": "^3.0.1", + "cypress": "^13.6.1" + } } diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..acfcce7 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..4c931fd Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..90e31de Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..b3930d0 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..5aae9e7 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..8e6907d Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/index.html b/public/index.html old mode 100644 new mode 100755 diff --git a/public/manifest.json b/public/manifest.json old mode 100644 new mode 100755 diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png new file mode 100644 index 0000000..2db962c Binary files /dev/null and b/public/mstile-150x150.png differ diff --git a/public/robots.txt b/public/robots.txt old mode 100644 new mode 100755 diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg new file mode 100644 index 0000000..d2af8af --- /dev/null +++ b/public/safari-pinned-tab.svg @@ -0,0 +1,48 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + diff --git a/src/App.tsx b/src/App.tsx index adb64bf..f3b5172 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,43 +1,10 @@ -import dayjs from "dayjs"; -import "dayjs/locale/ru"; import { ViewPage } from "./pages/ViewPublicationPage"; -import { BrowserRouter, Route, Routes } from "react-router-dom"; -import "./index.css"; - -import { - clearAuthToken, - getMessageFromFetchError, - useUserFetcher, -} from "@frontend/kitui"; -import { clearUserData, setUser, useUserStore } from "@root/user"; -import { enqueueSnackbar } from "notistack"; +import dayjs from "dayjs"; dayjs.locale("ru"); + export default function App() { - const userId = useUserStore((state) => state.userId); - useUserFetcher({ - url: `https://hub.pena.digital/user/${userId}`, - userId, - onNewUser: setUser, - onError: (error) => { - const errorMessage = getMessageFromFetchError(error); - if (errorMessage) { - enqueueSnackbar(errorMessage); - clearUserData(); - clearAuthToken(); - } - }, - }); - - return ( - <> - - - } /> - - - - ); + return ; } diff --git a/src/api/contactForm.ts b/src/api/contactForm.ts deleted file mode 100644 index 463bdaa..0000000 --- a/src/api/contactForm.ts +++ /dev/null @@ -1,17 +0,0 @@ -import axios from "axios"; - -const domen = window.location.hostname === "localhost" ? "squiz.pena.digital" : window.location.hostname - -export function sendContactFormRequest(body: { - - contact: string; - whoami: string; -}) { - return axios(`https://${domen}/feedback/callme`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - data: body, - }); -} \ No newline at end of file diff --git a/src/api/question.ts b/src/api/question.ts deleted file mode 100644 index e70b4cc..0000000 --- a/src/api/question.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { makeRequest } from "@frontend/kitui"; -import { CreateQuestionRequest } from "model/question/create"; -import { RawQuestion } from "model/question/question"; -import { GetQuestionListRequest, GetQuestionListResponse } from "@model/question/getList"; -import { EditQuestionRequest, EditQuestionResponse } from "@model/question/edit"; -import { DeleteQuestionRequest, DeleteQuestionResponse } from "@model/question/delete"; -import { CopyQuestionRequest, CopyQuestionResponse } from "@model/question/copy"; - - -const baseUrl = process.env.NODE_ENV === "production" ? "/squiz" : "https://squiz.pena.digital/squiz"; - -function createQuestion(body: CreateQuestionRequest) { - return makeRequest({ - url: `${baseUrl}/question/create`, - body, - method: "POST", - }); -} - -async function getQuestionList(body?: Partial) { - console.log("body" , body) - if (!body?.quiz_id) return null; - - const response = await makeRequest({ - url: `${baseUrl}/question/getList`, - body: { ...defaultGetQuestionListBody, ...body }, - method: "POST", - }); - - return response.items; -} - -function editQuestion(body: EditQuestionRequest, signal?: AbortSignal) { - return makeRequest({ - url: `${baseUrl}/question/edit`, - body, - method: "PATCH", - signal, - }); -} - -function copyQuestion(questionId: number, quizId: number) { - return makeRequest({ - url: `${baseUrl}/question/copy`, - body: { id: questionId, quiz_id: quizId }, - method: "POST", - }); -} - -function deleteQuestion(id: number) { - return makeRequest({ - url: `${baseUrl}/question/delete`, - body: { id }, - method: "DELETE", - }); -} - -export const questionApi = { - create: createQuestion, - getList: getQuestionList, - edit: editQuestion, - copy: copyQuestion, - delete: deleteQuestion, -}; - - -const defaultGetQuestionListBody: GetQuestionListRequest = { - "limit": 100, - "offset": 0, - "type": "", -}; diff --git a/src/api/quiz.ts b/src/api/quiz.ts deleted file mode 100644 index 140aab1..0000000 --- a/src/api/quiz.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { makeRequest } from "@frontend/kitui"; -import { defaultQuizConfig } from "@model/quizSettings"; -import { CopyQuizRequest, CopyQuizResponse } from "model/quiz/copy"; -import { CreateQuizRequest } from "model/quiz/create"; -import { DeleteQuizRequest, DeleteQuizResponse } from "model/quiz/delete"; -import { EditQuizRequest, EditQuizResponse } from "model/quiz/edit"; -import { GetQuizRequest, GetQuizResponse } from "model/quiz/get"; -import { GetQuizListRequest, GetQuizListResponse } from "model/quiz/getList"; -import { RawQuiz } from "model/quiz/quiz"; - - -const baseUrl = process.env.NODE_ENV === "production" ? "/squiz" : "https://squiz.pena.digital/squiz"; -const imagesUrl = process.env.NODE_ENV === "production" ? "/squizstorer" : "https://squiz.pena.digital/squizstorer"; - -function createQuiz(body?: Partial) { - return makeRequest({ - url: `${baseUrl}/quiz/create`, - body: { ...defaultCreateQuizBody, ...body }, - method: "POST", - }); -} - -async function getQuizList(body?: Partial) { - const response = await makeRequest({ - url: `${baseUrl}/quiz/getList`, - body: { ...defaultGetQuizListBody, ...body }, - method: "POST", - }); - - return response.items; -} - -function getQuiz(body?: Partial) { - return makeRequest({ - url: `${baseUrl}/quiz/get`, - body: { ...defaultGetQuizBody, ...body }, - method: "GET", - }); -} - -async function editQuiz(body: EditQuizRequest, signal?: AbortSignal) { - return makeRequest({ - url: `${baseUrl}/quiz/edit`, - body, - method: "PATCH", - signal, - }); -} - -function copyQuiz(id: number) { - return makeRequest({ - url: `${baseUrl}/quiz/copy`, - body: { id }, - method: "POST", - }); -} - -function deleteQuiz(id: number) { - return makeRequest({ - url: `${baseUrl}/quiz/delete`, - body: { id }, - method: "DELETE", - }); -} - -function addQuizImages(quizId: number, image: Blob) { - const formData = new FormData(); - - formData.append("quiz", quizId.toString()); - formData.append("image", image); - - return makeRequest({ - url: `${imagesUrl}/quiz/putImages`, - body: formData, - method: "PUT", - }); -} - -export const quizApi = { - create: createQuiz, - getList: getQuizList, - get: getQuiz, - edit: editQuiz, - copy: copyQuiz, - delete: deleteQuiz, - addImages: addQuizImages, -}; - - -const defaultCreateQuizBody: CreateQuizRequest = { - "fingerprinting": true, - "repeatable": true, - "note_prevented": true, - "mail_notifications": false, - "unique_answers": true, - "name": "", - "description": "", - "config": JSON.stringify(defaultQuizConfig), - "status": "stop", - "limit": 0, - "due_to": 0, - "time_of_passing": 0, - "pausable": false, - "super": false, - "group_id": 0, -}; - -const defaultGetQuizBody: GetQuizRequest = { - "quiz_id": "string", - "limit": 0, - "page": 0, - "need_config": true, -}; - -const defaultGetQuizListBody: GetQuizListRequest = { - "limit": 100, - "offset": 0, -}; diff --git a/src/assets/card-1.png b/src/assets/card-1.png old mode 100644 new mode 100755 diff --git a/src/assets/card-2.png b/src/assets/card-2.png old mode 100644 new mode 100755 diff --git a/src/assets/card-3.png b/src/assets/card-3.png old mode 100644 new mode 100755 diff --git a/src/assets/icons/AlignLeftIcon.tsx b/src/assets/icons/AlignLeftIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/AlignRightIcon.tsx b/src/assets/icons/AlignRightIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/ArrowDownIcon.tsx b/src/assets/icons/ArrowDownIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/BackArrowIcon.tsx b/src/assets/icons/BackArrowIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/ChartIcon.tsx b/src/assets/icons/ChartIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/ChartPieIcon.tsx b/src/assets/icons/ChartPieIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/CollapseMenuIcon.tsx b/src/assets/icons/CollapseMenuIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/ContactBookIcon.tsx b/src/assets/icons/ContactBookIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/ExpandIcon.tsx b/src/assets/icons/ExpandIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/EyeIcon.tsx b/src/assets/icons/EyeIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/FlowArrowIcon.tsx b/src/assets/icons/FlowArrowIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/GearIcon.tsx b/src/assets/icons/GearIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/InfoIcon.tsx b/src/assets/icons/InfoIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LayoutCenteredIcon.tsx b/src/assets/icons/LayoutCenteredIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LayoutExpandedIcon.tsx b/src/assets/icons/LayoutExpandedIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LayoutIcon.tsx b/src/assets/icons/LayoutIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LayoutIconBig.tsx b/src/assets/icons/LayoutIconBig.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LayoutStandartIcon.tsx b/src/assets/icons/LayoutStandartIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LinkIcon.tsx b/src/assets/icons/LinkIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/LogoutIcon.tsx b/src/assets/icons/LogoutIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/MegaphoneIcon.tsx b/src/assets/icons/MegaphoneIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/MobilePhoneIcon.tsx b/src/assets/icons/MobilePhoneIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/PencilCircleIcon.tsx b/src/assets/icons/PencilCircleIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/PencilIcon.tsx b/src/assets/icons/PencilIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/PuzzlePieceIcon.tsx b/src/assets/icons/PuzzlePieceIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/QuestionIcon.tsx b/src/assets/icons/QuestionIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/SearchIcon.tsx b/src/assets/icons/SearchIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/SendIcon.tsx b/src/assets/icons/SendIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/TagIcon.tsx b/src/assets/icons/TagIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/UploadIcon.tsx b/src/assets/icons/UploadIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/WalletIcon.tsx b/src/assets/icons/WalletIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/CopyIcon.tsx b/src/assets/icons/questionsPage/CopyIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/OneIcon.tsx b/src/assets/icons/questionsPage/OneIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/PointsIcon.tsx b/src/assets/icons/questionsPage/PointsIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/addPlus.tsx b/src/assets/icons/questionsPage/addPlus.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/answer.tsx b/src/assets/icons/questionsPage/answer.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/arrowLeft.tsx b/src/assets/icons/questionsPage/arrowLeft.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/branching.tsx b/src/assets/icons/questionsPage/branching.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/clue.tsx b/src/assets/icons/questionsPage/clue.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/date.tsx b/src/assets/icons/questionsPage/date.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/deleteIcon.tsx b/src/assets/icons/questionsPage/deleteIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/download.tsx b/src/assets/icons/questionsPage/download.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/drop_down.tsx b/src/assets/icons/questionsPage/drop_down.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/emoji.tsx b/src/assets/icons/questionsPage/emoji.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/enterIcon.tsx b/src/assets/icons/questionsPage/enterIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/hideIcon.tsx b/src/assets/icons/questionsPage/hideIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/imgIcon.tsx b/src/assets/icons/questionsPage/imgIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/input.tsx b/src/assets/icons/questionsPage/input.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/options_and_pict.tsx b/src/assets/icons/questionsPage/options_and_pict.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/options_pict.tsx b/src/assets/icons/questionsPage/options_pict.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/page.tsx b/src/assets/icons/questionsPage/page.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/rating.tsx b/src/assets/icons/questionsPage/rating.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/settingIcon.tsx b/src/assets/icons/questionsPage/settingIcon.tsx old mode 100644 new mode 100755 diff --git a/src/assets/icons/questionsPage/slider.tsx b/src/assets/icons/questionsPage/slider.tsx old mode 100644 new mode 100755 diff --git a/src/assets/quiz-creation-1.png b/src/assets/quiz-creation-1.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-creation-2.png b/src/assets/quiz-creation-2.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-template-1.png b/src/assets/quiz-template-1.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-template-2.png b/src/assets/quiz-template-2.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-template-3.png b/src/assets/quiz-template-3.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-template-4.png b/src/assets/quiz-template-4.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-template-5.png b/src/assets/quiz-template-5.png old mode 100644 new mode 100755 diff --git a/src/assets/quiz-template-6.png b/src/assets/quiz-template-6.png old mode 100644 new mode 100755 diff --git a/src/constants/base.ts b/src/constants/base.ts deleted file mode 100644 index 77feb97..0000000 --- a/src/constants/base.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { QuizQuestionBase, QuestionBranchingRuleMain } from "../model/questionTypes/shared"; - - -export const QUIZ_QUESTION_BASE: Omit = { - quizId: 0, - description: "", - page: 0, - title: "", - expanded: true, - openedModalSettings: false, - deleted: false, - deleteTimeoutId: 0, - content: { - id: "", - hint: { - text: "", - video: "", - }, - rule: { - children: [], - main: [] as QuestionBranchingRuleMain[], - parentId: "", - default: "" - }, - back: "", - originalBack: "", - autofill: false, - }, -}; diff --git a/src/constants/date.ts b/src/constants/date.ts deleted file mode 100644 index 6455fac..0000000 --- a/src/constants/date.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionDate } from "../model/questionTypes/date"; - -export const QUIZ_QUESTION_DATE: Omit = { - ...QUIZ_QUESTION_BASE, - type: "date", - content: { - ...QUIZ_QUESTION_BASE.content, - required: false, - innerNameCheck: false, - innerName: "", - dateRange: false, - time: false, - }, -}; diff --git a/src/constants/default.ts b/src/constants/default.ts deleted file mode 100644 index f3bcd48..0000000 --- a/src/constants/default.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { QuestionType } from "@model/question/question"; -import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; -import { QUIZ_QUESTION_DATE } from "./date"; -import { QUIZ_QUESTION_EMOJI } from "./emoji"; -import { QUIZ_QUESTION_FILE } from "./file"; -import { QUIZ_QUESTION_IMAGES } from "./images"; -import { QUIZ_QUESTION_NUMBER } from "./number"; -import { QUIZ_QUESTION_PAGE } from "./page"; -import { QUIZ_QUESTION_RATING } from "./rating"; -import { QUIZ_QUESTION_SELECT } from "./select"; -import { QUIZ_QUESTION_TEXT } from "./text"; -import { QUIZ_QUESTION_VARIANT } from "./variant"; -import { QUIZ_QUESTION_VARIMG } from "./varimg"; -import { QUIZ_QUESTION_RESULT } from "./result"; - - -export const defaultQuestionByType: Record> = { - "date": QUIZ_QUESTION_DATE, - "emoji": QUIZ_QUESTION_EMOJI, - "file": QUIZ_QUESTION_FILE, - "images": QUIZ_QUESTION_IMAGES, - "number": QUIZ_QUESTION_NUMBER, - "page": QUIZ_QUESTION_PAGE, - "rating": QUIZ_QUESTION_RATING, - "select": QUIZ_QUESTION_SELECT, - "text": QUIZ_QUESTION_TEXT, - "variant": QUIZ_QUESTION_VARIANT, - "varimg": QUIZ_QUESTION_VARIMG, - "result": QUIZ_QUESTION_RESULT, -} as const; diff --git a/src/constants/emoji.ts b/src/constants/emoji.ts deleted file mode 100644 index fea13ba..0000000 --- a/src/constants/emoji.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionEmoji } from "../model/questionTypes/emoji"; -import { nanoid } from "nanoid"; - -export const QUIZ_QUESTION_EMOJI: Omit = { - ...QUIZ_QUESTION_BASE, - type: "emoji", - content: { - ...QUIZ_QUESTION_BASE.content, - multi: false, - own: false, - innerNameCheck: false, - innerName: "", - required: false, - variants: [ - { - id: nanoid(), - answer: "", - extendedText: "", - hints: "", - originalImageUrl: "", - }, - ], - }, -}; diff --git a/src/constants/file.ts b/src/constants/file.ts deleted file mode 100644 index 8e36b23..0000000 --- a/src/constants/file.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionFile } from "../model/questionTypes/file"; - -export const QUIZ_QUESTION_FILE: Omit = { - ...QUIZ_QUESTION_BASE, - type: "file", - content: { - ...QUIZ_QUESTION_BASE.content, - required: false, - innerNameCheck: false, - innerName: "", - type: "picture", - }, -}; diff --git a/src/constants/images.ts b/src/constants/images.ts deleted file mode 100644 index dd92dc9..0000000 --- a/src/constants/images.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionImages } from "../model/questionTypes/images"; -import { nanoid } from "nanoid"; - -export const QUIZ_QUESTION_IMAGES: Omit = { - ...QUIZ_QUESTION_BASE, - type: "images", - content: { - ...QUIZ_QUESTION_BASE.content, - own: false, - multi: false, - xy: "1:1", - innerNameCheck: false, - innerName: "", - large: false, - format: "carousel", - required: false, - variants: [ - { - id: nanoid(), - answer: "", - extendedText: "", - originalImageUrl: "", - hints: "" - }, - ], - largeCheck: false, - }, -}; diff --git a/src/constants/number.ts b/src/constants/number.ts deleted file mode 100644 index 96cbd5a..0000000 --- a/src/constants/number.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionNumber } from "../model/questionTypes/number"; - -export const QUIZ_QUESTION_NUMBER: Omit = { - ...QUIZ_QUESTION_BASE, - type: "number", - content: { - ...QUIZ_QUESTION_BASE.content, - required: false, - innerNameCheck: false, - innerName: "", - range: "1—100", - defaultValue: 0, - step: 1, - steps: 5, - start: 50, - chooseRange: false, - form: "star", - }, -}; diff --git a/src/constants/page.ts b/src/constants/page.ts deleted file mode 100644 index 5fbb296..0000000 --- a/src/constants/page.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionPage } from "../model/questionTypes/page"; - -export const QUIZ_QUESTION_PAGE: Omit = { - ...QUIZ_QUESTION_BASE, - type: "page", - content: { - ...QUIZ_QUESTION_BASE.content, - innerNameCheck: false, - innerName: "", - text: "", - picture: "", - originalPicture: "", - video: "", - }, -}; diff --git a/src/constants/rating.ts b/src/constants/rating.ts deleted file mode 100644 index cef8bc2..0000000 --- a/src/constants/rating.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionRating } from "../model/questionTypes/rating"; - -export const QUIZ_QUESTION_RATING: Omit = { - ...QUIZ_QUESTION_BASE, - type: "rating", - content: { - ...QUIZ_QUESTION_BASE.content, - required: false, - innerNameCheck: false, - innerName: "", - steps: 5, - ratingExpanded: false, - form: "star", - ratingNegativeDescription: "", - ratingPositiveDescription: "", - }, -}; diff --git a/src/constants/result.ts b/src/constants/result.ts deleted file mode 100644 index b9f4015..0000000 --- a/src/constants/result.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionResult } from "../model/questionTypes/result"; -import { nanoid } from "nanoid"; - -export const QUIZ_QUESTION_RESULT: Omit = { - ...QUIZ_QUESTION_BASE, - type: "result", - content: { - ...QUIZ_QUESTION_BASE.content, - video: "", - innerName: "", - text: "", - price: [0], - useImage: true - }, -}; diff --git a/src/constants/select.ts b/src/constants/select.ts deleted file mode 100644 index ff8de24..0000000 --- a/src/constants/select.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionSelect } from "../model/questionTypes/select"; -import { nanoid } from "nanoid"; - -export const QUIZ_QUESTION_SELECT: Omit = { - ...QUIZ_QUESTION_BASE, - type: "select", - content: { - ...QUIZ_QUESTION_BASE.content, - multi: false, - required: false, - innerNameCheck: false, - innerName: "", - default: "", - variants: [{ id: nanoid(), answer: "", extendedText: "", hints: "", originalImageUrl: "" }], - }, -}; diff --git a/src/constants/text.ts b/src/constants/text.ts deleted file mode 100644 index a64c4f9..0000000 --- a/src/constants/text.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionText } from "../model/questionTypes/text"; - -export const QUIZ_QUESTION_TEXT: Omit = { - ...QUIZ_QUESTION_BASE, - type: "text", - content: { - ...QUIZ_QUESTION_BASE.content, - placeholder: "", - innerNameCheck: false, - innerName: "", - required: false, - answerType: "single", - onlyNumbers: false, - }, -}; diff --git a/src/constants/variant.ts b/src/constants/variant.ts deleted file mode 100644 index eaca719..0000000 --- a/src/constants/variant.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionVariant } from "../model/questionTypes/variant"; -import { nanoid } from "nanoid"; - -export const QUIZ_QUESTION_VARIANT: Omit = { - ...QUIZ_QUESTION_BASE, - type: "variant", - content: { - ...QUIZ_QUESTION_BASE.content, - largeCheck: false, - multi: false, - own: false, - innerNameCheck: false, - required: false, - innerName: "", - variants: [{ id: nanoid(), answer: "", extendedText: "", hints: "", originalImageUrl: "" }], - }, -}; diff --git a/src/constants/varimg.ts b/src/constants/varimg.ts deleted file mode 100644 index ef97133..0000000 --- a/src/constants/varimg.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { QUIZ_QUESTION_BASE } from "./base"; - -import type { QuizQuestionVarImg } from "../model/questionTypes/varimg"; -import { nanoid } from "nanoid"; - -export const QUIZ_QUESTION_VARIMG: Omit = { - ...QUIZ_QUESTION_BASE, - type: "varimg", - content: { - ...QUIZ_QUESTION_BASE.content, - own: false, - innerNameCheck: false, - innerName: "", - required: false, - variants: [{ id: nanoid(), answer: "", hints: "", extendedText: "", originalImageUrl: "" }], - largeCheck: false, - replText: "", - }, -}; diff --git a/src/index.css b/src/index.css old mode 100644 new mode 100755 diff --git a/src/index.tsx b/src/index.tsx old mode 100644 new mode 100755 index 604a3d2..20b0030 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,44 +1,43 @@ import { CssBaseline, ThemeProvider } from "@mui/material"; import { LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; -import { ruRU } from "@mui/x-date-pickers/locales"; +import { ruRU } from '@mui/x-date-pickers/locales'; import App from "./App"; import dayjs from "dayjs"; import "dayjs/locale/ru"; -import { SnackbarProvider } from "notistack"; +import { SnackbarProvider } from 'notistack'; import { createRoot } from "react-dom/client"; import "./index.css"; import lightTheme from "./utils/themes/light"; import { SWRConfig } from "swr"; +import {BrowserRouter} from "react-router-dom"; + + dayjs.locale("ru"); -const localeText = - ruRU.components.MuiLocalizationProvider.defaultProps.localeText; +const localeText = ruRU.components.MuiLocalizationProvider.defaultProps.localeText; const root = createRoot(document.getElementById("root")!); root.render( - - - - - - - - - - + + + + + + + + + + + + + ); diff --git a/src/model/question/copy.ts b/src/model/question/copy.ts deleted file mode 100644 index 834f245..0000000 --- a/src/model/question/copy.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface CopyQuestionRequest { - id: number; - quiz_id: number; -} - -export interface CopyQuestionResponse { - updated: number; -} diff --git a/src/model/question/create.ts b/src/model/question/create.ts deleted file mode 100644 index 89190b6..0000000 --- a/src/model/question/create.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { QuestionType } from "./question"; - - -export interface CreateQuestionRequest { - /** id of quiz for what question is creating */ - quiz_id: number; - /** title of question. max length 512 */ - title: string; - /** description of question. html/text */ - description: string; - /** type of question. allow only text, select, file, variant, images, varimg, emoji, date, number, page, rating */ - type: QuestionType; - /** set true if user MUST answer this question */ - required: boolean; - /** page of question */ - page: number; - /** json serialized of question content settings */ - content: string; -} diff --git a/src/model/question/delete.ts b/src/model/question/delete.ts deleted file mode 100644 index 441bacf..0000000 --- a/src/model/question/delete.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface DeleteQuestionRequest { - id: number; -} - -export interface DeleteQuestionResponse { - deactivated: number; -} diff --git a/src/model/question/edit.ts b/src/model/question/edit.ts deleted file mode 100644 index 498e652..0000000 --- a/src/model/question/edit.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; -import { QuestionType } from "./question"; - - -export interface EditQuestionRequest { - id: number; - title?: string; - desc?: string; - type?: QuestionType; - required?: boolean; - page?: number; - content: string; -} - -export interface EditQuestionResponse { - updated: number; -} - -export function questionToEditQuestionRequest(question: AnyTypedQuizQuestion): EditQuestionRequest { - return { - id: question.backendId, - title: question.title, - desc: question.description, - type: question.type, - required: "required" in question.content ? question.content.required : false, - page: question.page, - content: JSON.stringify(question.content), - }; -} diff --git a/src/model/question/getList.ts b/src/model/question/getList.ts deleted file mode 100644 index a0af41b..0000000 --- a/src/model/question/getList.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { QuestionType, RawQuestion } from "./question"; - - -export interface GetQuestionListRequest { - /** max items on page */ - limit?: number; - /** page number */ - offset?: number; - /** start time of time period. timestamp in seconds */ - from?: number; - /** end time of time period. timestamp in seconds */ - to?: number; - /** string for fulltext search in titles of questions */ - search?: string; - /** allow only - text, select, file, variant, images, varimg, emoji, date, number, page, rating or empty string */ - type: "" | QuestionType; - /** get deleted quizes */ - deleted?: boolean; - /** get only require questions */ - required?: boolean; - /** relation to quiz */ - quiz_id?: number; -} - -export interface GetQuestionListResponse { - count: number; - items: RawQuestion[] | null; -} diff --git a/src/model/question/question.ts b/src/model/question/question.ts deleted file mode 100644 index 0a61942..0000000 --- a/src/model/question/question.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; -import { defaultQuestionByType } from "../../constants/default"; -import { nanoid } from "nanoid"; - - -export type QuestionType = - | "variant" - | "images" - | "varimg" - | "emoji" - | "text" - | "select" - | "date" - | "number" - | "file" - | "page" - | "rating" - | "result"; - -/** Type that comes from server */ -export interface RawQuestion { - /** Id of created question */ - id: number; - /** relation to quiz */ - quiz_id: number; - /** title of question. max 512 length */ - title: string; - /** description of question */ - description: string; - /** status of question. allow only text, select, file, variant, images, varimg, emoji, date, number, page, rating */ - type: QuestionType; - /** user must pass this question */ - required: boolean; - /** true if question is deleted */ - deleted: boolean; - /** page if question */ - page: number; - /** serialized json of created question */ - content: string; - /** version of quiz */ - version: number; - /** array of previous versions of quiz */ - parent_ids: number[]; - created_at: string; - updated_at: string; -} - -export function rawQuestionToQuestion(rawQuestion: RawQuestion): AnyTypedQuizQuestion { - let content = defaultQuestionByType[rawQuestion.type].content; - const frontId = nanoid() - - try { - content = JSON.parse(rawQuestion.content); - if (content.id.length === 0 || content.id.length === undefined) content.id = frontId - } catch (error) { - console.warn("Cannot parse question content from string, using default content", error); - } - - return { - backendId: rawQuestion.id, - id: frontId, - description: rawQuestion.description, - page: rawQuestion.page, - quizId: rawQuestion.quiz_id, - required: rawQuestion.required, - title: rawQuestion.title, - type: rawQuestion.type, - expanded: true, - openedModalSettings: false, - deleted: false, - deleteTimeoutId: 0, - content, - } as AnyTypedQuizQuestion; -} diff --git a/src/model/questionTypes/date.ts b/src/model/questionTypes/date.ts index 651550e..2b905e8 100644 --- a/src/model/questionTypes/date.ts +++ b/src/model/questionTypes/date.ts @@ -7,7 +7,6 @@ import type { export interface QuizQuestionDate extends QuizQuestionBase { type: "date"; content: { - id: string; /** Чекбокс "Необязательный вопрос" */ required: boolean; /** Чекбокс "Внутреннее название вопроса" */ diff --git a/src/model/questionTypes/emoji.ts b/src/model/questionTypes/emoji.ts index 7fa34a1..4a9f7ef 100644 --- a/src/model/questionTypes/emoji.ts +++ b/src/model/questionTypes/emoji.ts @@ -8,7 +8,6 @@ import type { export interface QuizQuestionEmoji extends QuizQuestionBase { type: "emoji"; content: { - id: string; /** Чекбокс "Можно несколько" */ multi: boolean; /** Чекбокс "Вариант "свой ответ"" */ diff --git a/src/model/questionTypes/file.ts b/src/model/questionTypes/file.ts index 51a748a..d1a6981 100644 --- a/src/model/questionTypes/file.ts +++ b/src/model/questionTypes/file.ts @@ -17,7 +17,6 @@ export type UploadFileType = keyof typeof UPLOAD_FILE_TYPES_MAP; export interface QuizQuestionFile extends QuizQuestionBase { type: "file"; content: { - id: string; /** Чекбокс "Необязательный вопрос" */ required: boolean; /** Чекбокс "Внутреннее название вопроса" */ diff --git a/src/model/questionTypes/images.ts b/src/model/questionTypes/images.ts index 8ed2a33..a65f6ba 100644 --- a/src/model/questionTypes/images.ts +++ b/src/model/questionTypes/images.ts @@ -6,32 +6,31 @@ import type { } from "./shared"; export interface QuizQuestionImages extends QuizQuestionBase { - type: "images"; - content: { - id: string; - /** Чекбокс "Вариант "свой ответ"" */ - own: boolean; - /** Чекбокс "Можно несколько" */ - multi: boolean; - /** Пропорции */ - xy: "1:1" | "1:2" | "2:1"; - /** Чекбокс "Внутреннее название вопроса" */ - innerNameCheck: boolean; - /** Поле "Внутреннее название вопроса" */ - innerName: string; - /** Чекбокс "Большие картинки" */ - large: boolean; - /** Форма */ - format: "carousel" | "masonry"; - /** Чекбокс "Необязательный вопрос" */ - required: boolean; - /** Варианты (картинки) */ - variants: QuestionVariant[]; - hint: QuestionHint; - rule: QuestionBranchingRule; - back: string; - originalBack: string; - autofill: boolean; - largeCheck: boolean; - }; + type: "images"; + content: { + /** Чекбокс "Вариант "свой ответ"" */ + own: boolean; + /** Чекбокс "Можно несколько" */ + multi: boolean; + /** Пропорции */ + xy: "1:1" | "1:2" | "2:1"; + /** Чекбокс "Внутреннее название вопроса" */ + innerNameCheck: boolean; + /** Поле "Внутреннее название вопроса" */ + innerName: string; + /** Чекбокс "Большие картинки" */ + large: boolean; + /** Форма */ + format: "carousel" | "masonry"; + /** Чекбокс "Необязательный вопрос" */ + required: boolean; + /** Варианты (картинки) */ + variants: QuestionVariant[]; + hint: QuestionHint; + rule: QuestionBranchingRule; + back: string; + originalBack: string; + autofill: boolean; + largeCheck: boolean; + }; } diff --git a/src/model/questionTypes/number.ts b/src/model/questionTypes/number.ts index 530db03..68f1370 100644 --- a/src/model/questionTypes/number.ts +++ b/src/model/questionTypes/number.ts @@ -7,7 +7,6 @@ import type { export interface QuizQuestionNumber extends QuizQuestionBase { type: "number"; content: { - id: string; /** Чекбокс "Необязательный вопрос" */ required: boolean; /** Чекбокс "Внутреннее название вопроса" */ diff --git a/src/model/questionTypes/page.ts b/src/model/questionTypes/page.ts index 6b1d559..9f829c8 100644 --- a/src/model/questionTypes/page.ts +++ b/src/model/questionTypes/page.ts @@ -7,7 +7,6 @@ import type { export interface QuizQuestionPage extends QuizQuestionBase { type: "page"; content: { - id: string; /** Чекбокс "Внутреннее название вопроса" */ innerNameCheck: boolean; /** Поле "Внутреннее название вопроса" */ diff --git a/src/model/questionTypes/rating.ts b/src/model/questionTypes/rating.ts index 2626077..2f73ef1 100644 --- a/src/model/questionTypes/rating.ts +++ b/src/model/questionTypes/rating.ts @@ -7,7 +7,6 @@ import type { export interface QuizQuestionRating extends QuizQuestionBase { type: "rating"; content: { - id: string; /** Чекбокс "Необязательный вопрос" */ required: boolean; /** Чекбокс "Внутреннее название вопроса" */ diff --git a/src/model/questionTypes/result.ts b/src/model/questionTypes/result.ts index 7636bd3..782ed0d 100644 --- a/src/model/questionTypes/result.ts +++ b/src/model/questionTypes/result.ts @@ -7,7 +7,6 @@ import type { export interface QuizQuestionResult extends QuizQuestionBase { type: "result"; content: { - id: string; back: string; originalBack: string; video: string; diff --git a/src/model/questionTypes/select.ts b/src/model/questionTypes/select.ts index 3145b80..f74cfdb 100644 --- a/src/model/questionTypes/select.ts +++ b/src/model/questionTypes/select.ts @@ -8,7 +8,6 @@ import type { export interface QuizQuestionSelect extends QuizQuestionBase { type: "select"; content: { - id: string; /** Чекбокс "Можно несколько" */ multi: boolean; /** Чекбокс "Необязательный вопрос" */ diff --git a/src/model/questionTypes/shared.ts b/src/model/questionTypes/shared.ts index 2d95ac3..85b563e 100644 --- a/src/model/questionTypes/shared.ts +++ b/src/model/questionTypes/shared.ts @@ -1,4 +1,3 @@ -import { QuestionType } from "@model/question/question"; import type { QuizQuestionDate } from "./date"; import type { QuizQuestionEmoji } from "./emoji"; import type { QuizQuestionFile } from "./file"; @@ -49,8 +48,21 @@ export type QuestionVariant = { originalImageUrl: string; }; +export type QuestionType = + | "variant" + | "images" + | "varimg" + | "emoji" + | "text" + | "select" + | "date" + | "number" + | "file" + | "page" + | "rating" + | "result"; + export interface QuizQuestionBase { - backendId: number; /** Stable id, generated on client */ id: string; quizId: number; @@ -61,9 +73,9 @@ export interface QuizQuestionBase { expanded: boolean; openedModalSettings: boolean; deleted: boolean; + required: boolean; deleteTimeoutId: number; content: { - id: string; hint: QuestionHint; rule: QuestionBranchingRule; back: string; @@ -72,15 +84,6 @@ export interface QuizQuestionBase { }; } -export interface UntypedQuizQuestion { - type: null; - id: string; - quizId: number; - title: string; - description: string; - expanded: boolean; - deleted: boolean; -} export type AnyTypedQuizQuestion = | QuizQuestionVariant @@ -96,6 +99,8 @@ export type AnyTypedQuizQuestion = | QuizQuestionRating | QuizQuestionResult; + + type FilterQuestionsWithVariants = T extends { content: { variants: QuestionVariant[]; }; } ? T : never; diff --git a/src/model/questionTypes/text.ts b/src/model/questionTypes/text.ts index 610bad5..351f732 100644 --- a/src/model/questionTypes/text.ts +++ b/src/model/questionTypes/text.ts @@ -7,7 +7,7 @@ import type { export interface QuizQuestionText extends QuizQuestionBase { type: "text"; content: { - id: string; + id: number; placeholder: string; /** Чекбокс "Внутреннее название вопроса" */ innerNameCheck: boolean; diff --git a/src/model/questionTypes/variant.ts b/src/model/questionTypes/variant.ts index 54f457d..32c0c4b 100644 --- a/src/model/questionTypes/variant.ts +++ b/src/model/questionTypes/variant.ts @@ -8,7 +8,6 @@ import type { export interface QuizQuestionVariant extends QuizQuestionBase { type: "variant"; content: { - id: string; /** Чекбокс "Длинный текстовый ответ" */ largeCheck: boolean; /** Чекбокс "Можно несколько" */ diff --git a/src/model/questionTypes/varimg.ts b/src/model/questionTypes/varimg.ts index 6d274d3..dd51c8d 100644 --- a/src/model/questionTypes/varimg.ts +++ b/src/model/questionTypes/varimg.ts @@ -8,7 +8,6 @@ import type { export interface QuizQuestionVarImg extends QuizQuestionBase { type: "varimg"; content: { - id: string; /** Чекбокс "Вариант "свой ответ"" */ own: boolean; /** Чекбокс "Внутреннее название вопроса" */ diff --git a/src/model/quiz/copy.ts b/src/model/quiz/copy.ts deleted file mode 100644 index 804777c..0000000 --- a/src/model/quiz/copy.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface CopyQuizRequest { - id: number; -} - -export interface CopyQuizResponse { - updated: number; -} diff --git a/src/model/quiz/create.ts b/src/model/quiz/create.ts deleted file mode 100644 index c4271a7..0000000 --- a/src/model/quiz/create.ts +++ /dev/null @@ -1,34 +0,0 @@ -export interface CreateQuizRequest { - /** set true for save deviceId */ - fingerprinting: boolean; - /** set true for allow user to repeat quiz */ - repeatable: boolean; - /** set true for save statistic of incomplete quiz passing */ - note_prevented: boolean; - /** set true for mail notification for each quiz passing */ - mail_notifications: boolean; - /** set true for save statistics only for unique quiz passing */ - unique_answers: boolean; - /** name of quiz. max 280 length */ - name: string; - /** description of quiz */ - description: string; - /** config of quiz. serialized json for rules of quiz flow */ - config: string; - /** status of quiz. allow only '', 'draft', 'template', 'stop', 'start' */ - status: "draft" | "template" | "stop" | "start"; - /** limit is count of max quiz passing */ - limit: number; - /** last time when quiz is valid. timestamp in seconds */ - due_to: number; - /** seconds to pass quiz */ - time_of_passing: number; - /** true if it is allowed for pause quiz */ - pausable: boolean; - /** count of questions */ - question_cnt?: number; - /** set true if squiz realize group functionality */ - super: boolean; - /** group of new quiz */ - group_id: number; -} diff --git a/src/model/quiz/delete.ts b/src/model/quiz/delete.ts deleted file mode 100644 index 3cc0717..0000000 --- a/src/model/quiz/delete.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface DeleteQuizRequest { - id: number; -} - -export interface DeleteQuizResponse { - deactivated: number; -} diff --git a/src/model/quiz/edit.ts b/src/model/quiz/edit.ts deleted file mode 100644 index a548a38..0000000 --- a/src/model/quiz/edit.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Quiz } from "./quiz"; - - -export interface EditQuizRequest { - /** id of question for update */ - id: number; - /** set true for storing fingerprints */ - fp: boolean; - /** set true for allow to repeat quiz after passing */ - rep: boolean; - /** set true for store unfinished passing */ - note_prevented: boolean; - /** set true if we should send passing result on every passing */ - mailing: boolean; - /** set true if we allow only one user quiz passing */ - uniq: boolean; - /** new name of the quiz */ - name?: string; - /** new descriptions of the quiz */ - desc?: string; - /** new config of the quiz */ - conf?: string; - /** new status. only draft,template,stop,start allowed */ - status?: string; - /** max amount of quiz passing */ - limit: number; - /** max time of quiz passing */ - due_to: number; - /** max time to pass quiz */ - time_of_passing: number; - /** allow to pause quiz to user */ - pausable: boolean; - /** count of questions */ - question_cnt?: number; - /** set true if squiz realize group functionality */ - super?: boolean; - /** group of new quiz */ - group_id?: number; -} - -export interface EditQuizResponse { - /** id of new version of question */ - updated: number; -} - -export function quizToEditQuizRequest(quiz: Quiz): EditQuizRequest { - return { - id: quiz.backendId, - fp: quiz.fingerprinting, - rep: quiz.repeatable, - note_prevented: quiz.note_prevented, - mailing: quiz.mail_notifications, - uniq: quiz.unique_answers, - name: quiz.name, - desc: quiz.description, - conf: JSON.stringify(quiz.config), - status: quiz.status, - limit: quiz.limit, - due_to: quiz.due_to, - time_of_passing: quiz.time_of_passing, - pausable: quiz.pausable, - question_cnt: quiz.question_cnt, - super: quiz.super, - group_id: quiz.group_id, - }; -} diff --git a/src/model/quiz/get.ts b/src/model/quiz/get.ts deleted file mode 100644 index 29988c7..0000000 --- a/src/model/quiz/get.ts +++ /dev/null @@ -1,29 +0,0 @@ -export interface GetQuizRequest { - quiz_id: string; - limit: number; - page: number; - need_config: boolean; -} - -export interface GetQuizResponse { - cnt: number; - settings: { - fp: boolean; - rep: boolean; - name: string; - cfg: string; - lim: number; - due: number; - delay: number; - pausable: boolean; - }; - items: { - id: number; - title: string; - desc: string; - typ: string; - req: boolean; - p: number; - c: string; - }[]; -} diff --git a/src/model/quiz/getList.ts b/src/model/quiz/getList.ts deleted file mode 100644 index 3abed8a..0000000 --- a/src/model/quiz/getList.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RawQuiz } from "./quiz"; - -export interface GetQuizListRequest { - /** max items on page */ - limit?: number; - /** page number */ - offset?: number; - /** start time of time period. timestamp in seconds */ - from?: number; - /** end time of time period. timestamp in seconds */ - to?: number; - /** string for fulltext search in titles of quizes */ - search?: string; - /** allow only - draft, template, timeout, stop, start, offlimit */ - status?: "" | "draft" | "template" | "timeout" | "stop" | "start" | "offlimit"; - /** get deleted quizes */ - deleted?: boolean; - /** get archived quizes */ - archived?: boolean; - /** set true if squiz realize group functionality */ - super?: boolean; - /** group of new quiz */ - group_id?: number; -} - -export interface GetQuizListResponse { - count: number; - items: RawQuiz[]; -} diff --git a/src/model/quiz/quiz.ts b/src/model/quiz/quiz.ts deleted file mode 100644 index 0de02cd..0000000 --- a/src/model/quiz/quiz.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { QuizConfig, defaultQuizConfig } from "@model/quizSettings"; -import { nanoid } from "nanoid"; - - -export interface Quiz { - /** Stable id, generated on client */ - id: string; - /** Id of created quiz */ - backendId: number; - /** string id for customers */ - qid: string; - /** true if quiz deleted */ - deleted: boolean; - /** true if quiz archived */ - archived: boolean; - /** set true for save deviceId */ - fingerprinting: boolean; - /** set true for allow user to repeat quiz */ - repeatable: boolean; - /** set true for save statistic of incomplete quiz passing */ - note_prevented: boolean; - /** set true for mail notification for each quiz passing */ - mail_notifications: boolean; - /** set true for save statistics only for unique quiz passing */ - unique_answers: boolean; - /** name of quiz. max 280 length */ - name: string; - /** description of quiz */ - description: string; - /** quiz config*/ - config: QuizConfig; - /** status of quiz. allow only '', 'draft', 'template', 'stop', 'start' */ - status: string; - /** limit is count of max quiz passing */ - limit: number; - /** last time when quiz is valid. timestamp in seconds */ - due_to: number; - /** seconds to pass quiz */ - time_of_passing: number; - /** true if it is allowed for pause quiz */ - pausable: boolean; - /** version of quiz */ - version: number; - /** version comment to version of quiz */ - version_comment: string; - /** array of previous versions of quiz */ - parent_ids: number[]; - created_at: string; - updated_at: string; - /** count of questions */ - question_cnt: number; - /** count passings */ - passed_count: number; - /** average time of passing */ - average_time: number; - /** set true if squiz realize group functionality */ - super: boolean; - /** group of new quiz */ - group_id: number; -} - -/** Type that comes from server */ -export interface RawQuiz { - /** Id of created quiz */ - id: number; - /** string id for customers */ - qid: string; - /** true if quiz deleted */ - deleted: boolean; - /** true if quiz archived */ - archived: boolean; - /** set true for save deviceId */ - fingerprinting: boolean; - /** set true for allow user to repeat quiz */ - repeatable: boolean; - /** set true for save statistic of incomplete quiz passing */ - note_prevented: boolean; - /** set true for mail notification for each quiz passing */ - mail_notifications: boolean; - /** set true for save statistics only for unique quiz passing */ - unique_answers: boolean; - /** name of quiz. max 280 length */ - name: string; - /** description of quiz */ - description: string; - /** config of quiz. serialized json for rules of quiz flow */ - config: string; - /** status of quiz. allow only '', 'draft', 'template', 'stop', 'start' */ - status: string; - /** limit is count of max quiz passing */ - limit: number; - /** last time when quiz is valid. timestamp in seconds */ - due_to: number; - /** seconds to pass quiz */ - time_of_passing: number; - /** true if it is allowed for pause quiz */ - pausable: boolean; - /** version of quiz */ - version: number; - /** version comment to version of quiz */ - version_comment: string; - /** array of previous versions of quiz */ - parent_ids: number[]; - created_at: string; - updated_at: string; - /** count of questions */ - question_cnt: number; - /** count passings */ - passed_count: number; - /** average time of passing */ - average_time: number; - /** set true if squiz realize group functionality */ - super: boolean; - /** group of new quiz */ - group_id: number; -} - -export function rawQuizToQuiz(rawQuiz: RawQuiz): Quiz { - let config = defaultQuizConfig; - - try { - config = JSON.parse(rawQuiz.config); - } catch (error) { - console.warn("Cannot parse quiz config from string, using default config", error); - } - - return { - ...rawQuiz, - config, - backendId: rawQuiz.id, - id: nanoid(), - }; -} diff --git a/src/model/quizSettings.ts b/src/model/quizSettings.ts index 7be9e19..db37e5c 100644 --- a/src/model/quizSettings.ts +++ b/src/model/quizSettings.ts @@ -14,7 +14,7 @@ export const quizSetupSteps = [ // { stepperText: "Оценка графа карты вопросов", sidebarText: "Карта вопросов", sidebarIcon: QuestionsMapIcon }, { stepperText: "Настройте форму контактов", sidebarText: "Форма контактов", sidebarIcon: ContactBookIcon }, { stepperText: "Установите квиз", sidebarText: "Установка квиза", sidebarIcon: FlowArrowIcon }, - { stepperText: "Запустите рекламу", sidebarText: "Запуск рекламы", sidebarIcon: MegaphoneIcon }, + // { stepperText: "Запустите рекламу", sidebarText: "Запуск рекламы", sidebarIcon: MegaphoneIcon }, ] as const; export const maxQuizSetupSteps = quizSetupSteps.length; @@ -40,7 +40,7 @@ export interface QuizConfig { theme: string, reply: string, replname: string, - } + } startpage: { description: string; button: string; @@ -58,6 +58,16 @@ export interface QuizConfig { cycle: boolean; }; }; + formContact: { + title: string; + desc: string; + name: FCField; + email: FCField; + phone: FCField; + text: FCField; + address: FCField; + button: string + }; info: { phonenumber: string; clickable: boolean; @@ -68,6 +78,14 @@ export interface QuizConfig { meta: string; } +type FCField = { + text: string + innerText: string + key: string + required: boolean + used: boolean +} + export const defaultQuizConfig: QuizConfig = { type: null, noStartPage: false, @@ -81,7 +99,7 @@ export const defaultQuizConfig: QuizConfig = { theme: "", reply: "", replname: "", - }, + }, startpage: { description: "", button: "", @@ -106,5 +124,45 @@ export const defaultQuizConfig: QuizConfig = { site: "", law: "", }, + formContact: { + title: "", + desc: "", + name: { + text: "", + innerText: "", + key: "", + required: false, + used: true + }, + email: { + text: "", + innerText: "", + key: "", + required: false, + used: true + }, + phone: { + text: "", + innerText: "", + key: "", + required: false, + used: true + }, + text: { + text: "", + innerText: "", + key: "", + required: false, + used: false + }, + address: { + text: "", + innerText: "", + key: "", + required: false, + used: false + }, + button: "" + }, meta: "", }; diff --git a/src/mui.d.ts b/src/mui.d.ts old mode 100644 new mode 100755 diff --git a/src/pages/ViewPublicationPage/ApologyPage.tsx b/src/pages/ViewPublicationPage/ApologyPage.tsx new file mode 100644 index 0000000..b9357d0 --- /dev/null +++ b/src/pages/ViewPublicationPage/ApologyPage.tsx @@ -0,0 +1,21 @@ +import { Box, Typography } from "@mui/material"; + +export const ApologyPage = ({message}:{message: string}) => { + return ( + + {message || "что-то пошло не так"} + + + + ) +} \ No newline at end of file diff --git a/src/pages/ViewPublicationPage/ContactForm.tsx b/src/pages/ViewPublicationPage/ContactForm.tsx index d511f67..b47a93b 100644 --- a/src/pages/ViewPublicationPage/ContactForm.tsx +++ b/src/pages/ViewPublicationPage/ContactForm.tsx @@ -1,7 +1,13 @@ -import { Box, Typography, Button } from "@mui/material"; +import { Box, Typography, Button, Paper, TextField, Link, InputAdornment } from "@mui/material"; +import NameIcon from "@icons/ContactFormIcon/NameIcon"; +import EmailIcon from "@icons/ContactFormIcon/EmailIcon"; +import PhoneIcon from "@icons/ContactFormIcon/PhoneIcon"; +import TextIcon from "@icons/ContactFormIcon/TextIcon"; +import AddressIcon from "@icons/ContactFormIcon/AddressIcon"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import { useQuestionsStore } from "@root/questions/store"; +import CustomCheckbox from "@ui_kit/CustomCheckbox"; +import { useState } from "react"; +import { useQuestionsStore } from "@root/quizData/store"; import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared"; @@ -12,36 +18,158 @@ type ContactFormProps = { setShowResultForm: (show: boolean) => void; }; +const icons = [ + { type: "name", icon: NameIcon, defaultText: "Введите имя", defaultTitle: "имя" }, + { type: "email", icon: EmailIcon, defaultText: "Введите Email", defaultTitle: "Email" }, + { type: "phone", icon: PhoneIcon, defaultText: "Введите номер телефона", defaultTitle: "номер телефона" }, + { type: "text", icon: TextIcon, defaultText: "Введите фамилию", defaultTitle: "фамилию" }, + { type: "address", icon: AddressIcon, defaultText: "Введите адрес", defaultTitle: "адрес" }, +] + export const ContactForm = ({ currentQuestion, showResultForm, setShowContactForm, setShowResultForm, }: ContactFormProps) => { - const quiz = useCurrentQuiz(); - const { questions } = useQuestionsStore(); + const { settings } = useQuestionsStore() + + const [ready, setReady] = useState(false) const followNextForm = () => { setShowContactForm(false); setShowResultForm(true); }; - const resultQuestion = questions.find( - (question) => - question.type === "result" && - question.content.rule.parentId === currentQuestion.content.id - ); - return ( - - Форма контактов - {!showResultForm && - resultQuestion && - quiz?.config.resultInfo.when === "after" && ( - - )} - + + + + + + {settings.cfg.formContact.title || "Заполните форму, чтобы получить результаты теста"} + + + { + settings.cfg.formContact.desc && + + {settings.cfg.formContact.desc} + + } + + + + + + + + + + + { + ( + + )} + + + { setReady(target.checked) }} checked={ready} /> + + С + Положением об обработке персональных данных + и + Политикой конфиденциальности + ознакомлен + + + + + + ); }; + +const Inputs = () => { + const { settings } = useQuestionsStore() + + let someUsed:any = [] + + const Icons = icons.map((data) => { + //@ts-ignore + const FC:any = settings.cfg.formContact[data.type] + if (FC.used) someUsed.push() + return + }) + + if (someUsed.length) { + return <>{someUsed} + } else { + return <> + {Icons[0]} + {Icons[1]} + {Icons[2]} + + } +} + +const CustomInput = ({ title, desc, Icon }: any) => { + return + {title} + , + }} + /> + +} diff --git a/src/pages/ViewPublicationPage/Footer.tsx b/src/pages/ViewPublicationPage/Footer.tsx index a6708f3..c4177af 100644 --- a/src/pages/ViewPublicationPage/Footer.tsx +++ b/src/pages/ViewPublicationPage/Footer.tsx @@ -1,15 +1,13 @@ import { useState, useEffect } from "react"; import { Box, Button, useTheme } from "@mui/material"; -import { useQuizViewStore } from "@root/quizView"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import { useQuestionsStore } from "@root/questions/store"; - import type { AnyTypedQuizQuestion, QuizQuestionBase, } from "../../model/questionTypes/shared"; -import { getQuestionByContentId } from "@root/questions/actions"; +import { useQuestionsStore } from "@root/quizData/store"; +import { getQuestionById } from "@root/quizData/actions"; +import { useQuizViewStore } from "@root/quizView/store"; import { enqueueSnackbar } from "notistack"; type FooterProps = { @@ -25,23 +23,24 @@ export const Footer = ({ setShowContactForm, setShowResultForm, }: FooterProps) => { - const [disablePreviousButton, setDisablePreviousButton] = - useState(false); - const [disableNextButton, setDisableNextButton] = useState(false); - const quiz = useCurrentQuiz(); - const { answers } = useQuizViewStore(); - const questions = useQuestionsStore().questions as AnyTypedQuizQuestion[]; const theme = useTheme(); - const linear = !questions.find( + + const { settings, items } = useQuestionsStore(); + const { answers } = useQuizViewStore(); + + const [disablePreviousButton, setDisablePreviousButton] = useState(false); + const [disableNextButton, setDisableNextButton] = useState(false); + + const linear = !items.find( ({ content }) => content.rule.parentId === "root" ); useEffect(() => { // Логика для аргумента disabled у кнопки "Назад" if (linear) { - const questionIndex = questions.findIndex(({ id }) => id === question.id); + const questionIndex = items.findIndex(({ id }) => id === question.id); - const previousQuestion = questions[questionIndex - 1]; + const previousQuestion = items[questionIndex - 1]; if (previousQuestion) { setDisablePreviousButton(false); @@ -58,7 +57,7 @@ export const Footer = ({ // Логика для аргумента disabled у кнопки "Далее" const answer = answers.find( - ({ questionId }) => questionId === question.content.id + ({ questionId }) => questionId === question.id ); if ("required" in question.content && question.content.required && answer) { @@ -85,7 +84,7 @@ export const Footer = ({ if (nextQuestionId) { setDisableNextButton(false); } else { - const nextQuestion = getQuestionByContentId( + const nextQuestion = getQuestionById( question.content.rule.default ); @@ -95,13 +94,11 @@ export const Footer = ({ } }, [question, answers]); - const showResult = () => { - const resultQuestion = questions.find( - ({ type, content }) => - type === "result" && content.rule.parentId === question.content.id - ); + const showResult = (nextQuestion:any) => { - if (quiz?.config.resultInfo.when !== "after" && resultQuestion) { + console.log(nextQuestion) + + if (nextQuestion && settings.cfg.resultInfo.when === "before") { setShowResultForm(true); } else { setShowContactForm(true); @@ -111,7 +108,7 @@ export const Footer = ({ const getNextQuestionId = () => { if (answers.length) { const answer = answers.find( - ({ questionId }) => questionId === question.content.id + ({ questionId }) => questionId === question.id ); let readyBeNextQuestion = ""; @@ -155,9 +152,9 @@ export const Footer = ({ const followPreviousStep = () => { if (linear) { - const questionIndex = questions.findIndex(({ id }) => id === question.id); + const questionIndex = items.findIndex(({ id }) => id === question.id); - const previousQuestion = questions[questionIndex - 1]; + const previousQuestion = items[questionIndex - 1]; if (previousQuestion) { setCurrentQuestion(previousQuestion); @@ -167,7 +164,7 @@ export const Footer = ({ } if (question?.content.rule.parentId !== "root") { - const parent = getQuestionByContentId(question?.content.rule.parentId); + const parent = getQuestionById(question?.content.rule.parentId); if (parent?.type) { setCurrentQuestion(parent); } else { @@ -180,13 +177,14 @@ export const Footer = ({ const followNextStep = () => { if (linear) { - const questionIndex = questions.findIndex(({ id }) => id === question.id); - const nextQuestion = questions[questionIndex + 1]; + const questionIndex = items.findIndex(({ id }) => id === question.id); + const nextQuestion = items[questionIndex + 1]; + console.log(nextQuestion) if (nextQuestion && nextQuestion.type !== "result") { setCurrentQuestion(nextQuestion); } else { - showResult(); + showResult(nextQuestion); } return; @@ -195,7 +193,7 @@ export const Footer = ({ const nextQuestionId = getNextQuestionId(); if (nextQuestionId) { - const nextQuestion = getQuestionByContentId(nextQuestionId); + const nextQuestion = getQuestionById(nextQuestionId); if (nextQuestion?.type && nextQuestion.type !== "result") { setCurrentQuestion(nextQuestion); @@ -204,13 +202,13 @@ export const Footer = ({ enqueueSnackbar("не могу получить последующий вопрос"); } } else { - const nextQuestion = getQuestionByContentId( + const nextQuestion = getQuestionById( question.content.rule.default ); if (nextQuestion?.type && nextQuestion.type !== "result") { setCurrentQuestion(nextQuestion); } else { - showResult(); + showResult(undefined); } } }; @@ -260,7 +258,7 @@ export const Footer = ({ {/* */} {/* Из - {questions.length} + {items.length} */} - )} - - ); -}; + if (resultQuestion === null || resultQuestion === undefined) { + + followNextForm() + return <> + + } else { + + return ( + + + + { +//@ts-ignore + !resultQuestion?.content.useImage && + //@ts-ignore + resultQuestion.content.video && + + } + { +//@ts-ignore + resultQuestion?.content.useImage && + resultQuestion.content.back && + + + } + {resultQuestion.description !== "" && resultQuestion.description !== " " && {resultQuestion.description}} + + {resultQuestion.title || "Форма результатов"} + + + + + { + settings.cfg.resultInfo.when === "before" && + + + + } + + ); + } +}; \ No newline at end of file diff --git a/src/pages/ViewPublicationPage/StartPageViewPublication.tsx b/src/pages/ViewPublicationPage/StartPageViewPublication.tsx index 2754f88..2940e87 100644 --- a/src/pages/ViewPublicationPage/StartPageViewPublication.tsx +++ b/src/pages/ViewPublicationPage/StartPageViewPublication.tsx @@ -8,32 +8,33 @@ import { useMediaQuery, useTheme, } from "@mui/material"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import YoutubeEmbedIframe from "../../ui_kit/StartPagePreview/YoutubeEmbedIframe"; +import YoutubeEmbedIframe from "./tools/YoutubeEmbedIframe"; import { QuizStartpageAlignType, QuizStartpageType } from "@model/quizSettings"; import { notReachable } from "../../utils/notReachable"; import { useUADevice } from "../../utils/hooks/useUADevice"; +import { useQuestionsStore } from "@root/quizData/store"; interface Props { - setVisualStartPage: (a:boolean) => void + setVisualStartPage: (a: boolean) => void } -export const StartPageViewPublication = ({setVisualStartPage}:Props) => { +export const StartPageViewPublication = ({ setVisualStartPage }: Props) => { const theme = useTheme(); - const quiz = useCurrentQuiz(); const { isMobileDevice } = useUADevice(); - if (!quiz) return null; + const { settings } = useQuestionsStore() + + if (!settings) return null; const handleCopyNumber = () => { - navigator.clipboard.writeText(quiz.config.info.phonenumber); + navigator.clipboard.writeText(settings.cfg.info.phonenumber); }; - const background = quiz.config.startpage.background.type === "image" - ? quiz.config.startpage.background.desktop + const background = settings.cfg.startpage.background.type === "image" + ? settings.cfg.startpage.background.desktop ? ( { /> ) : null - : quiz.config.startpage.background.type === "video" - ? quiz.config.startpage.background.video + : settings.cfg.startpage.background.type === "video" + ? settings.cfg.startpage.background.video ? ( - { { gap: "20px", mb: "7px" }}> - {quiz.config.startpage.logo && ( + {settings.cfg.startpage.logo && ( { /> )} - {quiz.config.info.orgname} + {settings.cfg.info.orgname} - + - {quiz.config.info.site} + {settings.cfg.info.site} } @@ -115,11 +116,11 @@ export const StartPageViewPublication = ({setVisualStartPage}:Props) => { display: "flex", flexDirection: "column", justifyContent: "center", - alignItems: quiz.config.startpageType === "centered" ? "center" : - quiz.config.startpageType === "expanded" - ? quiz.config.startpage.position === "center" ? - "center" - : "start": "start", + alignItems: settings.cfg.startpageType === "centered" ? "center" : + settings.cfg.startpageType === "expanded" + ? settings.cfg.startpage.position === "center" ? + "center" + : "start" : "start", mt: "28px", width: "100%" }}> @@ -129,24 +130,24 @@ export const StartPageViewPublication = ({setVisualStartPage}:Props) => { fontStyle: "normal", fontStretch: "normal", lineHeight: "1.2", - }}>{quiz.name} + }}>{settings.name} - {quiz.config.startpage.description} + {settings.cfg.startpage.description} - + @@ -155,33 +156,33 @@ export const StartPageViewPublication = ({setVisualStartPage}:Props) => { mt: "46px" }} > - {quiz.config.info.clickable ? ( + {settings.cfg.info.clickable ? ( isMobileDevice ? ( - + - {quiz.config.info.phonenumber} + {settings.cfg.info.phonenumber} ) : ( - {quiz.config.info.phonenumber} + {settings.cfg.info.phonenumber} ) ) : ( - {quiz.config.info.phonenumber} + {settings.cfg.info.phonenumber} )} - {quiz.config.info.law} + {settings.cfg.info.law} } backgroundBlock={background} - startpageType={quiz.config.startpageType} - alignType={quiz.config.startpage.position} + startpageType={settings.cfg.startpageType} + alignType={settings.cfg.startpage.position} /> ); diff --git a/src/pages/ViewPublicationPage/index.tsx b/src/pages/ViewPublicationPage/index.tsx index 4322bba..4bb8b77 100644 --- a/src/pages/ViewPublicationPage/index.tsx +++ b/src/pages/ViewPublicationPage/index.tsx @@ -1,69 +1,46 @@ import { useEffect, useState } from "react"; -import { Box } from "@mui/material"; +import { Box, Skeleton } from "@mui/material"; import { StartPageViewPublication } from "./StartPageViewPublication"; import { Question } from "./Question"; -import { useQuestions } from "@root/questions/hooks"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import useSWR from "swr"; -import { quizApi } from "@api/quiz"; -import { setQuizes } from "@root/quizes/actions"; -import { isAxiosError } from "axios"; -import { devlog } from "@frontend/kitui"; -import { useQuizStore } from "@root/quizes/store"; +import { ApologyPage } from "./ApologyPage" -import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared"; -import { enqueueSnackbar } from "notistack"; -import { useQuestionsStore } from "@root/questions/store"; -import { setQuestions } from "@root/questions/actions"; -import { questionApi } from "@api/question"; +import { useQuestionsStore } from "@root/quizData/store" + +import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; export const ViewPage = () => { - const quiz = useCurrentQuiz(); - const { editQuizId } = useQuizStore(); - const { questions } = useQuestionsStore(); - - useEffect(() => { - const getData = async () => { - const quizes = await quizApi.getList(); - setQuizes(quizes); - - if (!editQuizId) { - return; - } - - const questions = await questionApi.getList({ quiz_id: editQuizId }); - setQuestions(questions); - }; - getData(); - }, []); - useEffect(() => { - setVisualStartPage(quiz?.config.noStartPage); - }, [questions]); + const { settings, cnt, items } = useQuestionsStore() const [visualStartPage, setVisualStartPage] = useState(); useEffect(() => { - const link = document.querySelector('link[rel="icon"]'); - if (link && quiz?.config.startpage.favIcon) { - link.setAttribute("href", quiz.config.startpage.favIcon); + const link = document.querySelector('link[rel="icon"]'); + if (link && settings.cfg.startpage.favIcon) { + link.setAttribute("href", settings.cfg.startpage.favIcon); } - }, [quiz?.config.startpage.favIcon]); + + setVisualStartPage(!settings.cfg.noStartPage); + }, [settings]); + + const filteredQuestions = ( - questions.filter(({ type }) => type) as AnyTypedQuizQuestion[] + items.filter(({ type }) => type) as AnyTypedQuizQuestion[] ).sort((previousItem, item) => previousItem.page - item.page); - console.log("visualStartPage ", visualStartPage); - if (visualStartPage === undefined) return <>; + + if (visualStartPage === undefined) return ; + if (cnt === 0) return return ( - {!visualStartPage ? ( - - ) : ( - - )} + { + visualStartPage ? + + : + + } ); }; diff --git a/src/pages/ViewPublicationPage/questions/Date.tsx b/src/pages/ViewPublicationPage/questions/Date.tsx index 0f33e19..199e71e 100644 --- a/src/pages/ViewPublicationPage/questions/Date.tsx +++ b/src/pages/ViewPublicationPage/questions/Date.tsx @@ -2,7 +2,7 @@ import dayjs from "dayjs"; import { DatePicker } from "@mui/x-date-pickers"; import { Box, Typography } from "@mui/material"; -import { useQuizViewStore, updateAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import type { QuizQuestionDate } from "../../../model/questionTypes/date"; import CalendarIcon from "@icons/CalendarIcon"; @@ -14,7 +14,7 @@ type DateProps = { export const Date = ({ currentQuestion }: DateProps) => { const { answers } = useQuizViewStore(); const answer = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id )?.answer as string; const [day, month, year] = answer?.split(".") || []; @@ -44,7 +44,7 @@ export const Date = ({ currentQuestion }: DateProps) => { } updateAnswer( - currentQuestion.content.id, + currentQuestion.id, String( new window.Date(date.toDate()).toLocaleDateString("ru-RU", { year: "numeric", diff --git a/src/pages/ViewPublicationPage/questions/Emoji.tsx b/src/pages/ViewPublicationPage/questions/Emoji.tsx index 42b69f6..a75dee5 100644 --- a/src/pages/ViewPublicationPage/questions/Emoji.tsx +++ b/src/pages/ViewPublicationPage/questions/Emoji.tsx @@ -8,7 +8,7 @@ import { FormControl, } from "@mui/material"; -import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store"; import RadioCheck from "@ui_kit/RadioCheck"; import RadioIcon from "@ui_kit/RadioIcon"; @@ -24,20 +24,20 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => { const theme = useTheme(); const { answer } = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id ) ?? {}; return ( {currentQuestion.title} answer === id )} onChange={({ target }) => updateAnswer( - currentQuestion.content.id, + currentQuestion.id, currentQuestion.content.variants[Number(target.value)].id ) } @@ -98,12 +98,12 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => { event.preventDefault(); updateAnswer( - currentQuestion.content.id, + currentQuestion.id, currentQuestion.content.variants[index].id ); if (answer === currentQuestion.content.variants[index].id) { - deleteAnswer(currentQuestion.content.id); + deleteAnswer(currentQuestion.id); } }} control={ diff --git a/src/pages/ViewPublicationPage/questions/File.tsx b/src/pages/ViewPublicationPage/questions/File.tsx index e107e9a..2a6acfd 100644 --- a/src/pages/ViewPublicationPage/questions/File.tsx +++ b/src/pages/ViewPublicationPage/questions/File.tsx @@ -5,7 +5,7 @@ import { useTheme, IconButton, } from "@mui/material"; -import { useQuizViewStore, updateAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import { UPLOAD_FILE_TYPES_MAP } from "@ui_kit/QuizPreview/QuizPreviewQuestionTypes/File"; import UploadIcon from "@icons/UploadIcon"; @@ -40,7 +40,7 @@ export const UPLOAD_FILE_DESCRIPTIONS_MAP: Record< export const File = ({ currentQuestion }: FileProps) => { const { answers } = useQuizViewStore(); const answer = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id )?.answer as string; const theme = useTheme(); const uploadFile = ({ target }: ChangeEvent) => { @@ -48,7 +48,7 @@ export const File = ({ currentQuestion }: FileProps) => { if (file) { updateAnswer( - currentQuestion.content.id, + currentQuestion.id, `${file.name}|${URL.createObjectURL(file)}` ); } @@ -84,7 +84,7 @@ export const File = ({ currentQuestion }: FileProps) => { { - updateAnswer(currentQuestion.content.id, ""); + updateAnswer(currentQuestion.id, ""); }} > diff --git a/src/pages/ViewPublicationPage/questions/Images.tsx b/src/pages/ViewPublicationPage/questions/Images.tsx index 7789c2a..4817c61 100644 --- a/src/pages/ViewPublicationPage/questions/Images.tsx +++ b/src/pages/ViewPublicationPage/questions/Images.tsx @@ -8,7 +8,7 @@ import { useMediaQuery, } from "@mui/material"; -import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store"; import RadioCheck from "@ui_kit/RadioCheck"; import RadioIcon from "@ui_kit/RadioIcon"; @@ -23,7 +23,7 @@ export const Images = ({ currentQuestion }: ImagesProps) => { const theme = useTheme(); const { answer } = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id ) ?? {}; const isTablet = useMediaQuery(theme.breakpoints.down(1000)); const isMobile = useMediaQuery(theme.breakpoints.down(500)); @@ -32,7 +32,7 @@ export const Images = ({ currentQuestion }: ImagesProps) => { {currentQuestion.title} answer === id )} @@ -68,12 +68,12 @@ export const Images = ({ currentQuestion }: ImagesProps) => { event.preventDefault(); updateAnswer( - currentQuestion.content.id, + currentQuestion.id, currentQuestion.content.variants[index].id ); if (answer === currentQuestion.content.variants[index].id) { - deleteAnswer(currentQuestion.content.id); + deleteAnswer(currentQuestion.id); } }} > diff --git a/src/pages/ViewPublicationPage/questions/Number.tsx b/src/pages/ViewPublicationPage/questions/Number.tsx index 28936e8..714f5e8 100644 --- a/src/pages/ViewPublicationPage/questions/Number.tsx +++ b/src/pages/ViewPublicationPage/questions/Number.tsx @@ -5,7 +5,7 @@ import { useDebouncedCallback } from "use-debounce"; import CustomTextField from "@ui_kit/CustomTextField"; import { CustomSlider } from "@ui_kit/CustomSlider"; -import { useQuizViewStore, updateAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import type { QuizQuestionNumber } from "../../../model/questionTypes/number"; @@ -23,16 +23,16 @@ export const Number = ({ currentQuestion }: NumberProps) => { setMinRange(maxRange); } - updateAnswer(currentQuestion.content.id, value); + updateAnswer(currentQuestion.id, value); }, 1000); const updateMaxRangeDebounced = useDebouncedCallback((value, crowded = false) => { if (crowded) { setMaxRange(minRange); } - updateAnswer(currentQuestion.content.id, value); + updateAnswer(currentQuestion.id, value); }, 1000); - const answer = answers.find(({ questionId }) => questionId === currentQuestion.content.id)?.answer as string; + const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string; const min = window.Number(currentQuestion.content.range.split("—")[0]); const max = window.Number(currentQuestion.content.range.split("—")[1]); @@ -75,7 +75,7 @@ export const Number = ({ currentQuestion }: NumberProps) => { step={currentQuestion.content.step || 1} onChange={(_, value) => { const range = String(value).replace(",", "—"); - updateAnswer(currentQuestion.content.id, range); + updateAnswer(currentQuestion.id, range); }} onChangeCommitted={(_, value) => { if (currentQuestion.content.chooseRange) { @@ -93,7 +93,7 @@ export const Number = ({ currentQuestion }: NumberProps) => { value={answer} onChange={({ target }) => { updateAnswer( - currentQuestion.content.id, + currentQuestion.id, window.Number(target.value) > max ? String(max) : window.Number(target.value) < min diff --git a/src/pages/ViewPublicationPage/questions/Page.tsx b/src/pages/ViewPublicationPage/questions/Page.tsx index 619aea4..049b28a 100644 --- a/src/pages/ViewPublicationPage/questions/Page.tsx +++ b/src/pages/ViewPublicationPage/questions/Page.tsx @@ -1,6 +1,6 @@ import { Box, Typography } from "@mui/material"; -import { useQuizViewStore, updateAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import type { QuizQuestionPage } from "../../../model/questionTypes/page"; @@ -10,7 +10,7 @@ type PageProps = { export const Page = ({ currentQuestion }: PageProps) => { const { answers } = useQuizViewStore(); - const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {}; + const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {}; return ( diff --git a/src/pages/ViewPublicationPage/questions/Rating.tsx b/src/pages/ViewPublicationPage/questions/Rating.tsx index 1486093..5de9fa7 100644 --- a/src/pages/ViewPublicationPage/questions/Rating.tsx +++ b/src/pages/ViewPublicationPage/questions/Rating.tsx @@ -5,7 +5,7 @@ import { useTheme, } from "@mui/material"; -import { useQuizViewStore, updateAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import TropfyIcon from "@icons/questionsPage/tropfyIcon"; import FlagIcon from "@icons/questionsPage/FlagIcon"; @@ -57,7 +57,7 @@ export const Rating = ({ currentQuestion }: RatingProps) => { const theme = useTheme(); const { answer } = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id ) ?? {}; const form = buttonRatingForm.find( ({ name }) => name === currentQuestion.content.form @@ -86,7 +86,7 @@ export const Rating = ({ currentQuestion }: RatingProps) => { - updateAnswer(currentQuestion.content.id, String(value)) + updateAnswer(currentQuestion.id, String(value)) } sx={{ height: "50px", gap: "15px" }} max={currentQuestion.content.steps} diff --git a/src/pages/ViewPublicationPage/questions/Select.tsx b/src/pages/ViewPublicationPage/questions/Select.tsx index 376d824..445efd8 100644 --- a/src/pages/ViewPublicationPage/questions/Select.tsx +++ b/src/pages/ViewPublicationPage/questions/Select.tsx @@ -1,8 +1,8 @@ import { Box, Typography } from "@mui/material"; -import { Select as SelectComponent } from "../../../pages/Questions/Select"; +import { Select as SelectComponent } from "../tools//Select"; -import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store"; import type { QuizQuestionSelect } from "../../../model/questionTypes/select"; @@ -14,7 +14,7 @@ export const Select = ({ currentQuestion }: SelectProps) => { const { answers } = useQuizViewStore(); const { answer } = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id ) ?? {}; return ( @@ -34,12 +34,12 @@ export const Select = ({ currentQuestion }: SelectProps) => { items={currentQuestion.content.variants.map(({ answer }) => answer)} onChange={(_, value) => { if (value < 0) { - deleteAnswer(currentQuestion.content.id); + deleteAnswer(currentQuestion.id); return; } - updateAnswer(currentQuestion.content.id, String(value)); + updateAnswer(currentQuestion.id, String(value)); }} /> diff --git a/src/pages/ViewPublicationPage/questions/Text.tsx b/src/pages/ViewPublicationPage/questions/Text.tsx index e620664..2863028 100644 --- a/src/pages/ViewPublicationPage/questions/Text.tsx +++ b/src/pages/ViewPublicationPage/questions/Text.tsx @@ -2,7 +2,7 @@ import { Box, Typography } from "@mui/material"; import CustomTextField from "@ui_kit/CustomTextField"; -import { useQuizViewStore, updateAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import type { QuizQuestionText } from "../../../model/questionTypes/text"; @@ -12,9 +12,7 @@ type TextProps = { export const Text = ({ currentQuestion }: TextProps) => { const { answers } = useQuizViewStore(); - const answer = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id - )?.answer as string; + const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {}; return ( @@ -29,10 +27,9 @@ export const Text = ({ currentQuestion }: TextProps) => { > - updateAnswer(currentQuestion.content.id, target.value) - } + onChange={({ target }) => updateAnswer(currentQuestion.id, target.value)} /> diff --git a/src/pages/ViewPublicationPage/questions/Variant.tsx b/src/pages/ViewPublicationPage/questions/Variant.tsx index 5c43f96..11f390f 100644 --- a/src/pages/ViewPublicationPage/questions/Variant.tsx +++ b/src/pages/ViewPublicationPage/questions/Variant.tsx @@ -7,18 +7,17 @@ import { FormControlLabel, Radio, Checkbox, + TextField, useTheme, } from "@mui/material"; -import CustomTextField from "@ui_kit/CustomTextField"; - import { useQuizViewStore, updateAnswer, deleteAnswer, updateOwnVariant, deleteOwnVariant, -} from "@root/quizView"; +} from "@root/quizView/store"; import RadioCheck from "@ui_kit/RadioCheck"; import RadioIcon from "@ui_kit/RadioIcon"; @@ -44,17 +43,17 @@ export const Variant = ({ currentQuestion }: VariantProps) => { const { answers, ownVariants } = useQuizViewStore(); const { answer } = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id ) ?? {}; const ownVariant = ownVariants.find( - (variant) => variant.contentId === currentQuestion.content.id + (variant) => variant.id === currentQuestion.id ); const Group = currentQuestion.content.multi ? FormGroup : RadioGroup; useEffect(() => { if (!ownVariant) { - updateOwnVariant(currentQuestion.content.id, ""); + updateOwnVariant(currentQuestion.id, ""); } }, []); @@ -63,7 +62,7 @@ export const Variant = ({ currentQuestion }: VariantProps) => { {currentQuestion.title} answer === id )} @@ -142,7 +141,8 @@ const VariantItem = ({ width: "100%", "&.MuiFormControl-root": { width: "100%", - }, + + } }} value={index} labelPlacement="start" @@ -157,7 +157,8 @@ const VariantItem = ({ } icon={} /> ) } - label={own ? : variant.answer} + //@ts-ignore + label={own ? : variant.answer} onClick={(event) => { event.preventDefault(); const variantId = currentQuestion.content.variants[index].id; @@ -166,7 +167,7 @@ const VariantItem = ({ const currentAnswer = typeof answer !== "string" ? answer || [] : []; updateAnswer( - currentQuestion.content.id, + currentQuestion.id, currentAnswer.includes(variantId) ? currentAnswer?.filter((item) => item !== variantId) : [...currentAnswer, variantId] @@ -175,10 +176,10 @@ const VariantItem = ({ return; } - updateAnswer(currentQuestion.content.id, variantId); + updateAnswer(currentQuestion.id, variantId); if (answer === variantId) { - deleteAnswer(currentQuestion.content.id); + deleteAnswer(currentQuestion.id); } }} /> diff --git a/src/pages/ViewPublicationPage/questions/Varimg.tsx b/src/pages/ViewPublicationPage/questions/Varimg.tsx index 065ae9c..8b96b0e 100644 --- a/src/pages/ViewPublicationPage/questions/Varimg.tsx +++ b/src/pages/ViewPublicationPage/questions/Varimg.tsx @@ -7,9 +7,9 @@ import { useTheme, } from "@mui/material"; -import gag from "./gag.png"; +import gag from "./gag.png" -import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView"; +import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store"; import RadioCheck from "@ui_kit/RadioCheck"; import RadioIcon from "@ui_kit/RadioIcon"; @@ -25,20 +25,20 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => { const theme = useTheme(); const { answer } = answers.find( - ({ questionId }) => questionId === currentQuestion.content.id + ({ questionId }) => questionId === currentQuestion.id ) ?? {}; const variant = currentQuestion.content.variants.find( ({ id }) => answer === id ); - console.log(currentQuestion); + console.log(currentQuestion) return ( {currentQuestion.title} answer === id )} @@ -67,12 +67,12 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => { event.preventDefault(); updateAnswer( - currentQuestion.content.id, + currentQuestion.id, currentQuestion.content.variants[index].id ); if (answer === currentQuestion.content.variants[index].id) { - deleteAnswer(currentQuestion.content.id); + deleteAnswer(currentQuestion.id); } }} control={ @@ -84,32 +84,36 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => { {/* {(variant?.extendedText || currentQuestion.content.back) && ( */} - - {answer ? ( - + { + answer ? + - ) : ( - variant?.extendedText || "Выберите вариант ответа слева" - )} - - {/* )} */} + : + (variant?.extendedText || "Выберите вариант ответа слева") + } + + + {/* )} */} ); diff --git a/src/pages/Questions/Select.tsx b/src/pages/ViewPublicationPage/tools/Select.tsx similarity index 100% rename from src/pages/Questions/Select.tsx rename to src/pages/ViewPublicationPage/tools/Select.tsx diff --git a/src/ui_kit/StartPagePreview/YoutubeEmbedIframe.tsx b/src/pages/ViewPublicationPage/tools/YoutubeEmbedIframe.tsx similarity index 100% rename from src/ui_kit/StartPagePreview/YoutubeEmbedIframe.tsx rename to src/pages/ViewPublicationPage/tools/YoutubeEmbedIframe.tsx diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts new file mode 100755 index 0000000..6431bc5 --- /dev/null +++ b/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/setupTests.ts b/src/setupTests.ts new file mode 100755 index 0000000..8f2609b --- /dev/null +++ b/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/src/stores/answer.ts b/src/stores/answer.ts deleted file mode 100644 index cf67cf7..0000000 --- a/src/stores/answer.ts +++ /dev/null @@ -1,68 +0,0 @@ -import {create} from "zustand"; -import {persist} from "zustand/middleware"; - -interface AnswerStore { - listAnswer: any; - updateAnswerList: (id: number, index: number, values: unknown) => void; - removeAnswer: any; - createAnswer: (idQuiz: number, idQuestion: number) => void; -} - -export const answerStore = create()( - - persist( - (set, get) => ({ - listAnswer: { - 2537998: { - 3677473: { - variants: - [ - "" - ], - own: true, - multi: true - } - } - }, - updateAnswerList: (id: number, index: number, values: any) => { - const array = get()["listAnswer"][id] || []; - array[index] = { - ...array[index], - ...values - }; - const state = get()["listAnswer"] || {}; - state[id] = array - set({listAnswer: state}); - }, - - createAnswer:(idQuiz: number, idQuestion: number) => { - const array = get()["listAnswer"][idQuiz][idQuestion] || []; - array.push( - { - variants: - [ - "" - ], - own: true, - multi: true - } - ) - const state = get()["listAnswer"] || {}; - state[idQuiz][idQuestion] = array - set({listAnswer: state}); - }, - - removeAnswer: (id:number, index: number) => { - const array = get()["listAnswer"][id] || []; - array.splice(index, 1) - const state = get()["listAnswer"] || {}; - state[id] = array - set({listAnswer: state}); - }, - }), - - { - name: "answer", - } - ) -); \ No newline at end of file diff --git a/src/stores/contactForm.ts b/src/stores/contactForm.ts deleted file mode 100644 index 549a1db..0000000 --- a/src/stores/contactForm.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { create } from "zustand"; -import { sendContactFormRequest } from "../api/contactForm"; -import { getMessageFromFetchError } from "../utils/backendMessageHandler"; - -interface ContactFormStore { - isModalOpen: boolean; - isSubmitDisabled: boolean; - mail: string; - phoneNumberField: string; - telegramField: string; - whatsappField: string; -} - -const initialState: ContactFormStore = { - isModalOpen: false, - isSubmitDisabled: false, - mail: "", - phoneNumberField: "", - telegramField: "", - whatsappField: "", -}; - -export const useContactFormStore = create()( - (set, get) => initialState -); - -export const setIsContactFormOpen = (isModalOpen: ContactFormStore["isModalOpen"]) => useContactFormStore.setState({ isModalOpen }); -export const setContactFormMailField = (mail: ContactFormStore["mail"]) => useContactFormStore.setState({ mail }); -export const setContactFormTelegramField = (telegramField: ContactFormStore["telegramField"]) => useContactFormStore.setState({ telegramField }); -export const setIsSubmitDisabled = (isSubmitDisabled: ContactFormStore["isSubmitDisabled"]) => useContactFormStore.setState({ isSubmitDisabled }); -export const setContactFormPhoneNumberField = (phoneNumberField: ContactFormStore["phoneNumberField"]) => { - if (/^\+?\d*$/.test(phoneNumberField)) useContactFormStore.setState({ phoneNumberField }); -}; -export const setContactFormWhatsappField = (whatsappField: ContactFormStore["whatsappField"]) => { - if (/^\+?\d*$/.test(whatsappField)) useContactFormStore.setState({ whatsappField }); -}; - -export const sendContactForm = async (): Promise => { - const { mail, phoneNumberField, telegramField, whatsappField } = useContactFormStore.getState(); - - if (!mail) return "Почта не указана"; - if (!mail.includes("@")) return "Почта некорректна"; - let contact = "Опросник, предрегистрация"; - - - try { - useContactFormStore.setState({ isSubmitDisabled: true }); - const response = await sendContactFormRequest({ - contact, - whoami: mail, - }); - - if (response.status !== 200) throw new Error(response.statusText); - - useContactFormStore.setState({ ...initialState }); - - return "Данные отправлены"; - } catch (error: any) { - useContactFormStore.setState({ isSubmitDisabled: false }); - return getMessageFromFetchError(error); - } -}; \ No newline at end of file diff --git a/src/stores/questions.ts b/src/stores/questions.ts deleted file mode 100644 index f559f2a..0000000 --- a/src/stores/questions.ts +++ /dev/null @@ -1,385 +0,0 @@ -import { create } from "zustand"; -import { devtools, persist } from "zustand/middleware"; - -import type { - AnyTypedQuizQuestion -} from "../model/questionTypes/shared"; - -import { QuestionType } from "@model/question/question"; -import { produce, setAutoFreeze } from "immer"; -import { QUIZ_QUESTION_BASE } from "../constants/base"; -import { QUIZ_QUESTION_DATE } from "../constants/date"; -import { QUIZ_QUESTION_EMOJI } from "../constants/emoji"; -import { QUIZ_QUESTION_FILE } from "../constants/file"; -import { QUIZ_QUESTION_IMAGES } from "../constants/images"; -import { QUIZ_QUESTION_NUMBER } from "../constants/number"; -import { QUIZ_QUESTION_PAGE } from "../constants/page"; -import { QUIZ_QUESTION_RATING } from "../constants/rating"; -import { QUIZ_QUESTION_SELECT } from "../constants/select"; -import { QUIZ_QUESTION_TEXT } from "../constants/text"; -import { QUIZ_QUESTION_VARIANT } from "../constants/variant"; -import { QUIZ_QUESTION_VARIMG } from "../constants/varimg"; - -setAutoFreeze(false); - -interface QuestionStore { - listQuestions: Record; -} - -let isFirstPartialize = true; - -/** @deprecated */ -export const questionStore = create()( - persist( - devtools( - () => ({ - listQuestions: {}, - }), - { - name: "Question", - enabled: process.env.NODE_ENV === "development", - trace: process.env.NODE_ENV === "development", - actionsBlacklist: "ignored", - } - ), - { - name: "question", - partialize: (state: QuestionStore) => { - if (isFirstPartialize) { - isFirstPartialize = false; - - Object.keys(state.listQuestions).forEach((quizId) => { - [...state.listQuestions[quizId]].forEach(({ backendId: id, deleted }) => { - if (deleted) { - const removedItemIndex = state.listQuestions[quizId].findIndex( - (item) => item.backendId === id - ); - - state.listQuestions[quizId].splice(removedItemIndex, 1); - } - }); - }); - } - - return state; - }, - merge: (persistedState, currentState) => { - const state = persistedState as QuestionStore; - - // replace blob urls with "" - Object.values(state.listQuestions).forEach(questions => { - questions.forEach(question => { - if (question.type === "page") { - if (question.content.picture.startsWith("blob:")) { - question.content.picture = ""; - } - } - if (question.type === "images") { - question.content.variants.forEach(variant => { - if (variant.extendedText.startsWith("blob:")) { - variant.extendedText = ""; - } - if (variant.originalImageUrl?.startsWith("blob:")) { - variant.originalImageUrl = ""; - } - }); - } - if (question.type === "varimg") { - question.content.variants.forEach(variant => { - if (variant.extendedText.startsWith("blob:")) { - variant.extendedText = ""; - } - if (variant.originalImageUrl?.startsWith("blob:")) { - variant.originalImageUrl = ""; - } - }); - } - }); - }); - - return { - ...currentState, - ...state, - }; - }, - } - ) -); - -/** @deprecated */ -export const updateQuestionsList = ( - quizId: number, - index: number, - data: Partial -) => { - const questionListClone = { ...questionStore.getState()["listQuestions"] }; - questionListClone[quizId][index] = { - ...questionListClone[quizId][index], - ...data, - }; - questionStore.setState({ listQuestions: questionListClone }); -}; - -/** @deprecated */ -export const updateQuestion = ( - quizId: number, - questionIndex: number, - recipe: (question: T) => void, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex] as T; - - recipe(question); -}, { - type: "updateQuestion", - quizId, - questionIndex, - recipe, -}); - -/** @deprecated */ -export const removeQuestionsByQuizId = (quizId: number) => setProducedState(state => { - delete state.listQuestions[quizId]; -}, "removeQuestionsByQuizId"); - -/** @deprecated */ -export const setVariantImageUrl = ( - quizId: number, - questionIndex: number, - variantIndex: number, - url: string, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex]; - if (!("variants" in question.content)) return; - - const variant = question.content.variants[variantIndex]; - - if (variant.extendedText === url) return; - - if (variant.extendedText !== variant.originalImageUrl) URL.revokeObjectURL(variant.extendedText); - variant.extendedText = url; -}, { - type: "setVariantImageUrl", - quizId, - questionIndex, - variantIndex, - url, -}); - -/** @deprecated */ -export const setVariantOriginalImageUrl = ( - quizId: number, - questionIndex: number, - variantIndex: number, - url: string, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex]; - if (!("variants" in question.content)) return; - - const variant = question.content.variants[variantIndex]; - - if (variant.originalImageUrl === url) return; - - if (variant.originalImageUrl) { - URL.revokeObjectURL(variant.originalImageUrl); - } - variant.originalImageUrl = url; -}, { - type: "setVariantOriginalImageUrl", - quizId, - questionIndex, - variantIndex, - url, -}); - -/** @deprecated */ -export const setPageQuestionPicture = ( - quizId: number, - questionIndex: number, - url: string, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex]; - if (question.type !== "page") return; - - if (question.content.picture === url) return; - - if ( - question.content.picture !== question.content.originalPicture - ) URL.revokeObjectURL(question.content.picture); - question.content.picture = url; -}); - -/** @deprecated */ -export const setPageQuestionOriginalPicture = ( - quizId: number, - questionIndex: number, - url: string, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex]; - if (question.type !== "page") return; - - if (question.content.originalPicture === url) return; - - URL.revokeObjectURL(question.content.originalPicture); - question.content.originalPicture = url; -}); - -/** @deprecated */ -export const setQuestionBackgroundImage = ( - quizId: number, - questionIndex: number, - url: string, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex]; - - if (question.content.back === url) return; - - if ( - question.content.back !== question.content.originalBack - ) URL.revokeObjectURL(question.content.back); - question.content.back = url; -}) - -/** @deprecated */ -export const setQuestionOriginalBackgroundImage = ( - quizId: number, - questionIndex: number, - url: string, -) => setProducedState(state => { - const question = state.listQuestions[quizId][questionIndex]; - - if (question.content.originalBack === url) return; - - URL.revokeObjectURL(question.content.originalBack); - question.content.originalBack = url; -}) - -/** @deprecated */ -export const updateQuestionsListDragAndDrop = ( - quizId: number, - updatedQuestions: AnyTypedQuizQuestion[] -) => { - const questionListClone = { ...questionStore.getState()["listQuestions"] }; - questionStore.setState({ - listQuestions: { ...questionListClone, [quizId]: updatedQuestions }, - }); -}; - - -/** @deprecated */ -export const reorderVariants = ( - quizId: number, - questionIndex: number, - sourceIndex: number, - destinationIndex: number, -) => setProducedState(state => { - if (sourceIndex === destinationIndex) return; - - const question = state.listQuestions[quizId][questionIndex]; - if (!("variants" in question.content)) return; - - const [removed] = question.content.variants.splice(sourceIndex, 1); - question.content.variants.splice(destinationIndex, 0, removed); -}, { - type: sourceIndex === destinationIndex ? "reorderVariants" : "ignored", - quizId, - questionIndex, - sourceIndex, - destinationIndex, -}); - -/** @deprecated */ -export const createQuestion = ( - quizId: number, - questionType: QuestionType = "variant", - placeIndex = -1 -) => { - const id = getRandom(); - const newData = { ...questionStore.getState()["listQuestions"] }; - - if (!newData[quizId]) { - newData[quizId] = []; - } - - const defaultObject = [ - QUIZ_QUESTION_BASE, - QUIZ_QUESTION_DATE, - QUIZ_QUESTION_EMOJI, - QUIZ_QUESTION_FILE, - QUIZ_QUESTION_IMAGES, - QUIZ_QUESTION_NUMBER, - QUIZ_QUESTION_PAGE, - QUIZ_QUESTION_RATING, - QUIZ_QUESTION_SELECT, - QUIZ_QUESTION_TEXT, - QUIZ_QUESTION_VARIANT, - QUIZ_QUESTION_VARIMG, - ].find((defaultObjectItem) => defaultObjectItem.type === questionType); - - if (defaultObject) { - newData[quizId].splice( - placeIndex < 0 ? newData[quizId].length : placeIndex, - 0, - { ...JSON.parse(JSON.stringify(defaultObject)), backendId: id } - ); - - questionStore.setState({ listQuestions: newData }); - } -}; - -/** @deprecated */ -export const copyQuestion = (quizId: number, copiedQuestionIndex: number) => { - const listQuestions = { ...questionStore.getState()["listQuestions"] }; - - const copiedQuiz = { ...listQuestions[quizId][copiedQuestionIndex] }; - listQuestions[quizId].splice(copiedQuestionIndex, 0, { - ...copiedQuiz, - backendId: getRandom(), - }); - - questionStore.setState({ listQuestions }); -}; - -/** @deprecated */ -export const removeQuestionForce = (quizId: number, removedId: number) => { - const questionListClone = { ...questionStore.getState()["listQuestions"] }; - const removedItemIndex = questionListClone[quizId].findIndex( - ({ backendId: id }) => id === removedId - ); - questionListClone[quizId].splice(removedItemIndex, 1); - questionStore.setState({ listQuestions: questionListClone }); -}; - -/** @deprecated */ -export const removeQuestion = (quizId: number, index: number) => { - const questionListClone = { ...questionStore.getState()["listQuestions"] }; - questionListClone[quizId][index].deleted = true; - questionStore.setState({ listQuestions: questionListClone }); -}; - -/** @deprecated */ -export const findQuestionById = (quizId: number) => { - let found = null; - questionStore - .getState() - ["listQuestions"][quizId].some((quiz: AnyTypedQuizQuestion, index: number) => { - if (quiz.backendId === quizId) { - found = { quiz, index }; - return true; - } - return false; - }); - return found; -}; - -function getRandom() { - const min = Math.ceil(1000000); - const max = Math.floor(10000000); - return Math.floor(Math.random() * (max - min)) + min; -} - -function setProducedState( - recipe: (state: QuestionStore) => void, - action?: A, -) { - questionStore.setState(state => produce(state, recipe), false, action); -} diff --git a/src/stores/questions/actions.ts b/src/stores/questions/actions.ts deleted file mode 100644 index edf94d0..0000000 --- a/src/stores/questions/actions.ts +++ /dev/null @@ -1,558 +0,0 @@ -import { questionApi } from "@api/question"; -import { quizApi } from "@api/quiz"; -import { devlog } from "@frontend/kitui"; -import { questionToEditQuestionRequest } from "@model/question/edit"; -import { QuestionType, RawQuestion, rawQuestionToQuestion } from "@model/question/question"; -import { AnyTypedQuizQuestion, QuestionVariant, UntypedQuizQuestion, createQuestionVariant } from "@model/questionTypes/shared"; -import { defaultQuestionByType } from "../../constants/default"; -import { produce } from "immer"; -import { nanoid } from "nanoid"; -import { enqueueSnackbar } from "notistack"; -import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError"; -import { RequestQueue } from "../../utils/requestQueue"; -import { updateRootContentId } from "@root/quizes/actions"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import { QuestionsStore, useQuestionsStore } from "./store"; -import { useUiTools } from "../uiTools/store"; - - -export const setQuestions = (questions: RawQuestion[] | null) => setProducedState(state => { - const untypedResultQuestions = state.questions.filter(q => q.type === null || q.type === "result"); - - state.questions = questions?.map(rawQuestionToQuestion) ?? []; - state.questions.push(...untypedResultQuestions); -}, { - type: "setQuestions", - questions, -}); - -export const createUntypedQuestion = (quizId: number, insertAfterQuestionId?: string) => setProducedState(state => { - const newUntypedQuestion = { - id: nanoid(), - quizId, - type: null, - title: "", - description: "", - deleted: false, - expanded: true, - }; - - if (insertAfterQuestionId) { - const index = state.questions.findIndex(q => q.id === insertAfterQuestionId); - if (index === -1) return; - state.questions.splice(index + 1, 0, newUntypedQuestion); - return; - } - - state.questions.push(newUntypedQuestion); -}, { - type: "createUntypedQuestion", - quizId, -}); - -const removeQuestion = (questionId: string) => setProducedState(state => { - const index = state.questions.findIndex(q => q.id === questionId); - if (index === -1) return; - - state.questions.splice(index, 1); -}, { - type: "removeQuestion", - questionId, -}); - -export const updateUntypedQuestion = ( - questionId: string, - updateFn: (question: UntypedQuizQuestion) => void, -) => { - setProducedState(state => { - const question = state.questions.find(q => q.id === questionId); - if (!question) return; - if (question.type !== null) throw new Error("Cannot update typed question, use 'updateQuestion' instead"); - - updateFn(question); - }, { - type: "updateUntypedQuestion", - questionId, - updateFn: updateFn.toString(), - }); -}; - -export const cleanQuestions = () => setProducedState(state => { - state.questions = []; -}, { - type: "cleanQuestions", -}); - -const setQuestionBackendId = (questionId: string, backendId: number) => setProducedState(state => { - const question = state.questions.find(q => q.id === questionId); - if (!question) return; - if (question.type === null) throw new Error("Cannot set backend id for untyped question"); - - question.backendId = backendId; -}, { - type: "setQuestionBackendId", - questionId: questionId, - backendId, -}); - -const updateQuestionOrders = () => { - const questions = useQuestionsStore.getState().questions.filter( - (question): question is AnyTypedQuizQuestion => question.type !== null && question.type !== "result" - ); - - questions.forEach((question, index) => { - updateQuestion(question.id, question => { - question.page = index; - }, true); - }); -}; - -export const reorderQuestions = ( - sourceIndex: number, - destinationIndex: number, -) => { - if (sourceIndex === destinationIndex) return; - - setProducedState(state => { - const [removed] = state.questions.splice(sourceIndex, 1); - state.questions.splice(destinationIndex, 0, removed); - }, { - type: "reorderQuestions", - sourceIndex, - destinationIndex, - }); - - updateQuestionOrders(); -}; - -export const toggleExpandQuestion = (questionId: string) => setProducedState(state => { - const question = state.questions.find(q => q.id === questionId); - if (!question) return; - - question.expanded = !question.expanded; -}, { - type: "toggleExpandQuestion", - questionId, -}); - -export const collapseAllQuestions = () => setProducedState(state => { - state.questions.forEach(question => question.expanded = false); -}, "collapseAllQuestions"); - -const DELETE_TIMEOUT = 5000; - -export const deleteQuestionWithTimeout = (questionId: string, deleteFn: (questionId: string) => void) => setProducedState(state => { - const question = state.questions.find(q => q.id === questionId); - if (!question) return; - if (question.type === null || question.type === "result") { - queueMicrotask(() => deleteFn(questionId)); - return; - } - - question.deleted = true; - clearTimeout(question.deleteTimeoutId); - question.deleteTimeoutId = window.setTimeout(() => { - deleteFn(questionId); - }, DELETE_TIMEOUT); -}, { - type: "deleteQuestionWithTimeout", - questionId, -}); - -export const cancelQuestionDeletion = (questionId: string) => setProducedState(state => { - const question = state.questions.find(q => q.id === questionId); - if (!question || question.type === null || question.type === "result") return; - - question.deleted = false; - clearTimeout(question.deleteTimeoutId); -}, { - type: "cancelQuestionDeletion", - questionId, -}); - - -const REQUEST_DEBOUNCE = 200; -const requestQueue = new RequestQueue(); -let requestTimeoutId: ReturnType; - -export const updateQuestion = ( - questionId: string, - updateFn: (question: T) => void, - skipQueue = false, -) => { - setProducedState(state => { - const question = state.questions.find(q => q.id === questionId) || state.questions.find(q => q.type !== null && q.content.id === questionId); - if (!question) return; - if (question.type === null) throw new Error("Cannot update untyped question, use 'updateUntypedQuestion' instead"); - - updateFn(question as T); - }, { - type: "updateQuestion", - questionId, - updateFn: updateFn.toString(), - }); - - // clearTimeout(requestTimeoutId); - - const request = async () => { - const q = useQuestionsStore.getState().questions.find(q => q.id === questionId) || useQuestionsStore.getState().questions.find(q => q.type !== null && q.content.id === questionId); - if (!q) return; - if (q.type === null) throw new Error("Cannot send update request for untyped question"); - - try { - const response = await questionApi.edit(questionToEditQuestionRequest(q)); - - //Если мы делаем листочек веточкой - удаляем созданный к нему результ - const questionResult = useQuestionsStore.getState().questions.find(questionResult => questionResult.type === "result" && questionResult.content.rule.parentId === q.content.id); - if (questionResult && q.content.rule.default.length !== 0) deleteQuestion(String(questionResult.quizId)); - - if (q.backendId !== response.updated) { - console.warn(`Question backend id has changed from ${q.backendId} to ${response.updated}`); - } - } catch (error) { - if (isAxiosCanceledError(error)) return; - - devlog("Error editing question", { error, questionId }); - enqueueSnackbar("Не удалось сохранить вопрос"); - } - }; - - if (skipQueue) { - request(); - return; - } - - // requestTimeoutId = setTimeout(() => { - requestQueue.enqueue(request); - // }, REQUEST_DEBOUNCE); -}; - -export const addQuestionVariant = (questionId: string) => { - updateQuestion(questionId, question => { - switch (question.type) { - case "variant": - case "emoji": - case "select": - case "images": - case "varimg": - question.content.variants.push(createQuestionVariant()); - break; - default: throw new Error(`Cannot add variant to question of type "${question.type}"`); - } - }); -}; - -export const deleteQuestionVariant = (questionId: string, variantId: string) => { - updateQuestion(questionId, question => { - if (!("variants" in question.content)) return; - - const variantIndex = question.content.variants.findIndex(variant => variant.id === variantId); - if (variantIndex === -1) return; - - question.content.variants.splice(variantIndex, 1); - }); -}; - -export const setQuestionVariantField = ( - questionId: string, - variantId: string, - field: keyof QuestionVariant, - value: QuestionVariant[keyof QuestionVariant], -) => { - updateQuestion(questionId, question => { - if (!("variants" in question.content)) return; - - const variantIndex = question.content.variants.findIndex(variant => variant.id === variantId); - if (variantIndex === -1) return; - - const variant = question.content.variants[variantIndex]; - variant[field] = value; - }); -}; - -export const reorderQuestionVariants = ( - questionId: string, - sourceIndex: number, - destinationIndex: number, -) => { - if (sourceIndex === destinationIndex) return; - - updateQuestion(questionId, question => { - if (!("variants" in question.content)) return; - - const [removed] = question.content.variants.splice(sourceIndex, 1); - question.content.variants.splice(destinationIndex, 0, removed); - - }); -}; - -export const uploadQuestionImage = async ( - questionId: string, - quizQid: string | undefined, - blob: Blob, - updateFn: (question: AnyTypedQuizQuestion, imageId: string) => void, -) => { - const question = useQuestionsStore.getState().questions.find(q => q.id === questionId); - if (!question || !quizQid) return; - - try { - console.log(question.quizId) - const response = await quizApi.addImages(question.quizId, blob); - - const values = Object.values(response); - if (values.length !== 1) { - console.warn("Error uploading image"); - return; - } - - const imageId = values[0]; - const imageUrl = `https://squiz.pena.digital/squizimages/${quizQid}/${imageId}`; - - updateQuestion(questionId, question => { - updateFn(question, imageUrl); - }); - - return imageUrl; - } catch (error) { - devlog("Error uploading question image", error); - - enqueueSnackbar("Не удалось загрузить изображение"); - } -}; - -export const setQuestionInnerName = ( - questionId: string, - name: string, -) => { - updateQuestion(questionId, question => { - question.content.innerName = name; - }); -}; - -export const changeQuestionType = ( - questionId: string, - type: QuestionType, -) => { - updateQuestion(questionId, question => { - const oldId = question.content.id; - const oldRule = question.content.rule; - oldRule.main = []; - question.type = type; - question.content = defaultQuestionByType[type].content; - question.content.id = oldId; - question.content.rule = oldRule; - }); -}; - -export const createTypedQuestion = async ( - questionId: string, - type: QuestionType, -) => requestQueue.enqueue(async () => { - const questions = useQuestionsStore.getState().questions; - const question = questions.find(q => q.id === questionId); - if (!question) return; - if (question.type !== null) throw new Error("Cannot upgrade already typed question"); - - const untypedOrResultQuestionsLength = questions.filter(q => q.type === "result" || q.type === null).length; - - try { - const createdQuestion = await questionApi.create({ - quiz_id: question.quizId, - type, - title: question.title, - description: question.description, - page: questions.length - untypedOrResultQuestionsLength, - required: false, - content: JSON.stringify(defaultQuestionByType[type].content), - }); - - setProducedState(state => { - const questionIndex = state.questions.findIndex(q => q.id === questionId); - if (questionIndex !== -1) state.questions.splice( - questionIndex, - 1, - rawQuestionToQuestion(createdQuestion) - ); - }, { - type: "createTypedQuestion", - question, - }); - - updateQuestionOrders(); - } catch (error) { - devlog("Error creating question", error); - enqueueSnackbar("Не удалось создать вопрос"); - } -}); - -export const deleteQuestion = async (questionId: string) => requestQueue.enqueue(async () => { - console.log("Я получил запрос на удаление. ИД - ", questionId) - - const question = useQuestionsStore.getState().questions.find(q => q.id === questionId); - console.log("delete question ", question) - if (!question) return; - - - - if (question.type === null) { - console.log("removeQuestion") - removeQuestion(questionId); - return; - } - - try { - await questionApi.delete(question.backendId); - - removeQuestion(questionId); - - updateQuestionOrders(); - } catch (error) { - devlog("Error deleting question", error); - enqueueSnackbar("Не удалось удалить вопрос"); - } -}); - -export const copyQuestion = async (questionId: string, quizId: number) => requestQueue.enqueue(async () => { - const question = useQuestionsStore.getState().questions.find(q => q.id === questionId); - if (!question) return; - - const frontId = nanoid(); - if (question.type === null) { - const copiedQuestion = structuredClone(question); - copiedQuestion.id = frontId; - - setProducedState(state => { - state.questions.push(copiedQuestion); - }, { - type: "copyQuestion", - questionId, - quizId, - }); - - return; - } - - try { - const { updated: newQuestionId } = await questionApi.copy(question.backendId, quizId); - - const copiedQuestion = structuredClone(question); - copiedQuestion.backendId = newQuestionId; - copiedQuestion.id = frontId; - copiedQuestion.content.id = frontId; - copiedQuestion.content.rule = { main: [], parentId: "", default: "", children: [] }; - - setProducedState(state => { - state.questions.push(copiedQuestion); - }, { - type: "copyQuestion", - questionId, - quizId, - }); - - updateQuestionOrders(); - } catch (error) { - devlog("Error copying question", error); - enqueueSnackbar("Не удалось скопировать вопрос"); - } -}); - -function setProducedState( - recipe: (state: QuestionsStore) => void, - action?: A, -) { - useQuestionsStore.setState(state => produce(state, recipe), false, action); -}; - - - - -export const getQuestionById = (questionId: string | null) => { - if (questionId === null) return null; - return useQuestionsStore.getState().questions.find(q => q.id === questionId) || null; -}; -export const getQuestionByContentId = (questionContentId: string | null) => { - if (questionContentId === null) return null; - return useQuestionsStore.getState().questions.find(q => { - if (q.type === null) return false; - - return (q.content.id === questionContentId); - }) || null; -}; - - - -export const clearRuleForAll = () => { - const { questions } = useQuestionsStore.getState(); - questions.forEach(question => { - if (question.type !== null && (question.content.rule.main.length > 0 || question.content.rule.default.length > 0 || question.content.rule.parentId)) { - updateQuestion(question.content.id, question => { - question.content.rule.parentId = ""; - question.content.rule.main = []; - question.content.rule.default = ""; - }); - } - }); -}; - - -export const createFrontResult = (quizId: number, parentContentId?: string) => setProducedState(state => { - const frontId = nanoid(); - const content = JSON.parse(JSON.stringify(defaultQuestionByType["result"].content)); - content.id = frontId; - if (parentContentId) content.rule.parentId = parentContentId; - state.questions.push({ - id: frontId, - quizId, - type: "result", - title: "", - description: "", - deleted: false, - expanded: true, - page: 101, - openedModalSettings: false, - backendId: 1, - deleteTimeoutId: 0, - content - }); -}, { - type: "createFrontResult", - quizId, -}); - - -export const createBackResult = async ( - questionId: string, - type: QuestionType, -) => requestQueue.enqueue(async () => { - const question = useQuestionsStore.getState().questions.find(q => q.id === questionId); - if (!question) return; - if (question.type !== "result") throw new Error("Cannot upgrade already typed question"); - - try { - const createdQuestion = await questionApi.create({ - quiz_id: question.quizId, - type, - title: question.title, - description: question.description, - page: 0, - required: true, - content: JSON.stringify(defaultQuestionByType[type].content), - }); - - setProducedState(state => { - const questionIndex = state.questions.findIndex(q => q.id === questionId); - if (questionIndex !== -1) state.questions.splice( - questionIndex, - 1, - rawQuestionToQuestion(createdQuestion) - ); - }, { - type: "createBackResult", - question, - }); - } catch (error) { - devlog("Error creating question", error); - enqueueSnackbar("Не удалось создать вопрос"); - } -}); - diff --git a/src/stores/questions/hooks.ts b/src/stores/questions/hooks.ts deleted file mode 100644 index 9de650f..0000000 --- a/src/stores/questions/hooks.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { questionApi } from "@api/question"; -import { devlog } from "@frontend/kitui"; -import { isAxiosError } from "axios"; -import { enqueueSnackbar } from "notistack"; -import useSWR from "swr"; -import { setQuestions } from "./actions"; -import { useQuestionsStore } from "./store"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import { useEffect } from "react"; - - -export function useQuestions() { - const quiz = useCurrentQuiz(); - const { isLoading, error, isValidating } = useSWR(["questions", quiz?.backendId], ([, id]) => questionApi.getList({ quiz_id: id }), { - onSuccess: setQuestions, - onError: error => { - const message = isAxiosError(error) ? (error.response?.data ?? "") : ""; - - devlog("Error getting question list", error); - enqueueSnackbar(`Не удалось получить вопросы. ${message}`); - } - }); - const questions = useQuestionsStore(state => state.questions); - - return { questions, isLoading, error, isValidating }; -} diff --git a/src/stores/questions/store.ts b/src/stores/questions/store.ts deleted file mode 100644 index 95367eb..0000000 --- a/src/stores/questions/store.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "@model/questionTypes/shared"; -import { create } from "zustand"; -import { devtools } from "zustand/middleware"; - - -export type QuestionsStore = { - questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[]; -}; - -const initialState: QuestionsStore = { - questions: [], - -}; - -export const useQuestionsStore = create()( - devtools( - () => initialState, - { - name: "QuestionsStore", - enabled: process.env.NODE_ENV === "development", - trace: process.env.NODE_ENV === "development", - actionsBlacklist: "ignored", - } - ) -); diff --git a/src/stores/quizData/actions.ts b/src/stores/quizData/actions.ts new file mode 100644 index 0000000..d33b720 --- /dev/null +++ b/src/stores/quizData/actions.ts @@ -0,0 +1,8 @@ +import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; +import { useQuestionsStore } from "./store"; + + +export const getQuestionById = (questionId: string | null):AnyTypedQuizQuestion | null => { + if (questionId === null) return null; + return useQuestionsStore.getState().items.find(q => q.id === questionId) || null; +}; \ No newline at end of file diff --git a/src/stores/quizData/hooks.ts b/src/stores/quizData/hooks.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/stores/quizData/store.ts b/src/stores/quizData/store.ts new file mode 100644 index 0000000..f537eb2 --- /dev/null +++ b/src/stores/quizData/store.ts @@ -0,0 +1,718 @@ +import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; +import { QuizConfig } from "@model/quizSettings"; +import { create } from "zustand"; +import { devtools } from "zustand/middleware"; + + +export type QuestionsStore = { + items: (AnyTypedQuizQuestion)[]; + settings: Settings; + cnt: number; +}; + +interface Settings { + + fp: boolean, + rep: boolean, + name: string, + lim: number, + due: number, + delay: number, + pausable: boolean, + cfg: QuizConfig +} + +const initialState: QuestionsStore = { + settings: { + fp: false, // собираем фингерпринт или нет. пока игнорим + rep: false, // можно ли перепроходить опрос + name: "название опроса", // название опроса + lim: 0, // ограничение на количество прохождений + due: 9999999999, // ограничение на дату окончания прохождения. т.е. если у опроса уже вышло время прохождения, уже нельзя давать пользователю проходить его + delay: 999999999, // сколько времени разрешено проходить опрос + pausable: true, //разрешено ли ставить опрос на паузу + // собственно, поле конфига + cfg: { + "type": null, + "noStartPage": false, + "startpageType": null, + "results": null, + "haveRoot": null, + "resultInfo": { + "when": "after", + "share": false, + "replay": false, + "theme": "", + "reply": "", + "replname": "" + }, + "startpage": { + "description": "", + "button": "", + "position": "left", + "favIcon": null, + "logo": null, + "originalLogo": null, + "background": { + "type": null, + "desktop": null, + "originalDesktop": null, + "mobile": null, + "originalMobile": null, + "video": null, + "cycle": false + } + }, + "info": { + "phonenumber": "", + "clickable": false, + "orgname": "", + "site": "", + "law": "" + }, + "formContact": { + "title": "", + "desc": "", + "name": { + "text": "", + "innerText": "", + "key": "", + "required": false, + "used": true + }, + "email": { + "text": "", + "innerText": "", + "key": "", + "required": false, + "used": true + }, + "phone": { + "text": "", + "innerText": "", + "key": "", + "required": false, + "used": true + }, + "text": { + "text": "", + "innerText": "", + "key": "", + "required": false, + "used": false + }, + "address": { + "text": "", + "innerText": "", + "key": "", + "required": false, + "used": false + }, + "button": "" + }, + "meta": "" + + } + }, + + //@ts-ignore + items: [ + { + "id": "26064", + "description": "", + "page": 0, + "quizId": 4856, + "required": false, + "title": "Варианты ответов", + "type": "variant", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vblavi2c73fq9rb0", + "originalBack": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vblavi2c73fq9rb0", + "autofill": false, + "largeCheck": false, + "multi": false, + "own": false, + "innerNameCheck": false, + "required": false, + "innerName": "", + "variants": [ + { + "id": "A2chQ9cZ1oSwGrGVthpd4", + "answer": "первый", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "Sb6IR4kmFJeyVtpV8HVTh", + "answer": "второй", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "4ZkVPXzSku_O7JDvR7guR", + "answer": "тритий", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + } + ] + } + }, + { + "id": "26066", + "description": "", + "page": 1, + "quizId": 4856, + "required": false, + "title": "варианты с картинками", + "type": "images", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "own": false, + "multi": false, + "xy": "1:1", + "innerNameCheck": false, + "innerName": "", + "large": false, + "format": "carousel", + "required": false, + "variants": [ + { + "id": "28xVXJS-dRr8wIbQmyfsb", + "answer": "первый", + "extendedText": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vfdavi2c73fq9rcg", + "originalImageUrl": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vf5avi2c73fq9rc0", + "hints": "" + }, + { + "id": "pVj4-56rJ_neQfAkUTHcV", + "answer": "второй", + "extendedText": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vhlavi2c73fq9rdg", + "hints": "", + "originalImageUrl": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vh5avi2c73fq9rd0" + }, + { + "id": "lMEkuOlzZI_4J1nlRf54V", + "answer": "тритий", + "extendedText": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vilavi2c73fq9reg", + "hints": "", + "originalImageUrl": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vidavi2c73fq9re0" + } + ], + "largeCheck": false + } + }, + { + "id": "26069", + "description": "", + "page": 2, + "quizId": 4856, + "required": false, + "title": "варианты и картинка", + "type": "varimg", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "own": false, + "innerNameCheck": false, + "innerName": "", + "required": false, + "variants": [ + { + "id": "4uy_Vm9FXq-qPAzaBBkXu", + "answer": "первый ", + "hints": "", + "extendedText": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vmdavi2c73fq9rfg", + "originalImageUrl": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vm5avi2c73fq9rf0" + }, + { + "id": "Lt7-FPzjBn67G6z8XSrBV", + "answer": "второй", + "extendedText": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vndavi2c73fq9rgg", + "hints": "", + "originalImageUrl": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9vn5avi2c73fq9rg0" + }, + { + "id": "Du7e6TzwQEjPgAU3-5MDM", + "answer": "тритий", + "extendedText": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9votavi2c73fq9rhg", + "hints": "", + "originalImageUrl": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clv9volavi2c73fq9rh0" + } + ], + "largeCheck": false, + "replText": "" + } + }, + { + "id": "26073", + "description": "", + "page": 3, + "quizId": 4856, + "required": false, + "title": "эмоджи", + "type": "emoji", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "multi": false, + "own": false, + "innerNameCheck": false, + "innerName": "", + "required": false, + "variants": [ + { + "id": "v3rYpKwP9C7NbCI9Q_jcO", + "answer": "первый", + "extendedText": "😍", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "m2qRUWk2nkCkgqz_XXXPW", + "answer": "текст", + "extendedText": "😆", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "xLkM2MKUdJPKDaH3sNGlD", + "answer": "", + "extendedText": "😄", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "Ng7YweDbm2g7fa3Fxf54L", + "answer": "выше пусто", + "extendedText": "😇", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "PvGj9SkpgE3gQ3IcLC0yv", + "answer": "аааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа", + "extendedText": "😀", + "hints": "", + "originalImageUrl": "" + } + ] + } + }, + + { + "id": "26078", + "description": "", + "page": 4, + "quizId": 4856, + "required": false, + "title": "своё поле для ввода", + "type": "text", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + //@ts-ignore + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "placeholder": "пример ответа введён тут", + "innerNameCheck": false, + "innerName": "", + "required": false, + "answerType": "single", + "onlyNumbers": false + } + }, + { + "id": "26084", + "description": "", + "page": 5, + "quizId": 4856, + "required": false, + "title": "выпадающий список", + "type": "select", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "multi": false, + "required": false, + "innerNameCheck": false, + "innerName": "", + "default": "", + "variants": [ + { + "id": "nS0tFnCyjQtJH7yR392Ck", + "answer": "выпадашка", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "lG0ffCvdX89o7En_LVCUG", + "answer": "подпадашка", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "M6jG7SlNXuRw1x68M7-bE", + "answer": "западашка", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + }, + { + "id": "3TQ0t8750k3xKIrTp_h1T", + "answer": "впадашка", + "extendedText": "", + "hints": "", + "originalImageUrl": "" + } + ] + } + }, + { + "id": "26091", + "description": "", + "page": 6, + "quizId": 4856, + "required": false, + "title": "дата", + "type": "date", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "required": false, + "innerNameCheck": false, + "innerName": "", + "dateRange": false, + "time": false + } + }, + { + "id": "26099", + "description": "", + "page": 7, + "quizId": 4856, + "required": false, + "title": "полузнок", + "type": "number", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "required": false, + "innerNameCheck": false, + "innerName": "", + "range": "1—100999999", + "defaultValue": 0, + "step": 1, + "steps": 5, + "start": 50, + "chooseRange": false, + "form": "star" + } + }, + { + "id": "26108", + "description": "", + "page": 8, + "quizId": 4856, + "required": false, + "title": "загрузка файла", + "type": "file", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "required": false, + "innerNameCheck": false, + "innerName": "", + "type": "picture" + } + }, + { + "id": "26118", + "description": "", + "page": 9, + "quizId": 4856, + "required": false, + "title": "страница", + "type": "page", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "innerNameCheck": false, + "innerName": "", + "text": "текст страница", + "picture": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clva0bdavi2c73fq9rig", + "originalPicture": "https://squiz.pena.digital/squizimages/c1ee11d2-ed5a-47d1-b500-bda6fd442114/clva0b5avi2c73fq9ri0", + "video": "" + } + }, + { + "id": "26129", + "description": "", + "page": 10, + "quizId": 4856, + "required": false, + "title": "рейтинг", + "type": "rating", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "required": false, + "innerNameCheck": false, + "innerName": "", + "steps": 5, + "ratingExpanded": false, + "form": "star", + "ratingNegativeDescription": "", + "ratingPositiveDescription": "" + } + }, + { + "id": "26141", + "description": "", + "page": 11, + "quizId": 4856, + "required": false, + "title": "страница конца", + "type": "page", + "expanded": true, + "openedModalSettings": false, + "deleted": false, + "deleteTimeoutId": 0, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "innerNameCheck": false, + "innerName": "", + "text": "", + "picture": "", + "originalPicture": "", + "video": "" + } + }, + //@ts-ignore + { + id: "2364", + "quizId": 2364, + "type": "result", + "title": "заголовок линейности", + "description": "", + "deleted": false, + "expanded": true, + "page": 101, + "required": true, + "content": { + "hint": { + "text": "", + "video": "" + }, + "rule": { + "children": [], + "main": [], + "parentId": "line", + "default": "" + }, + "back": "", + "originalBack": "", + "autofill": false, + "video": "", + "innerName": "", + "text": "", + "price": [ + 0 + ], + "useImage": false + } + } + ], + cnt: 13 // количество вопросов в опросе +}; + +export const useQuestionsStore = create()( + devtools( + () => initialState, + { + name: "QuestionsStore", + enabled: process.env.NODE_ENV === "development", + trace: process.env.NODE_ENV === "development", + actionsBlacklist: "ignored", + } + ) +); diff --git a/src/stores/quizPreview.ts b/src/stores/quizPreview.ts deleted file mode 100644 index 6058e85..0000000 --- a/src/stores/quizPreview.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { create } from "zustand"; -import { devtools } from "zustand/middleware"; - - -interface QuizPreviewStore { - isPreviewShown: boolean; - currentQuestionIndex: number; -} - -export const useQuizPreviewStore = create()( - devtools( - (set, get) => ({ - isPreviewShown: false, - currentQuestionIndex: 0, - }), - { - name: "quizPreview", - enabled: process.env.NODE_ENV !== "production", - } - ) -); - -export const showQuizPreview = () => useQuizPreviewStore.setState({ isPreviewShown: true }); - -export const hideQuizPreview = () => useQuizPreviewStore.setState({ isPreviewShown: false }); - -export const toggleQuizPreview = () => useQuizPreviewStore.setState( - state => ({ isPreviewShown: !state.isPreviewShown }) -); - -export const setCurrentQuestionIndex = (step: number) => useQuizPreviewStore.setState( - state => ({ currentQuestionIndex:state.currentQuestionIndex = step }) -); - -export const incrementCurrentQuestionIndex = (maxStep: number) => useQuizPreviewStore.setState( - state => ({ currentQuestionIndex: Math.min(state.currentQuestionIndex + 1, maxStep) }) -); - -export const decrementCurrentQuestionIndex = () => useQuizPreviewStore.setState( - state => ({ currentQuestionIndex: Math.max(state.currentQuestionIndex - 1, 0) }) -); diff --git a/src/stores/quizView/actions.ts b/src/stores/quizView/actions.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/stores/quizView/hooks.ts b/src/stores/quizView/hooks.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/stores/quizView.ts b/src/stores/quizView/store.ts similarity index 84% rename from src/stores/quizView.ts rename to src/stores/quizView/store.ts index 523579a..3c5d477 100644 --- a/src/stores/quizView.ts +++ b/src/stores/quizView/store.ts @@ -1,7 +1,6 @@ import { create } from "zustand"; import { devtools } from "zustand/middleware"; -import type { QuestionVariant } from "../model/questionTypes/shared"; type Answer = { questionId: string; @@ -9,8 +8,8 @@ type Answer = { }; type OwnVariant = { - contentId: string; - variant: QuestionVariant; + id: string; + variant: any; }; interface QuizViewStore { @@ -54,15 +53,15 @@ export const deleteAnswer = (questionId: string) => { useQuizViewStore.setState({ answers: filteredItems }); }; -export const updateOwnVariant = (contentId: string, answer: string) => { +export const updateOwnVariant = (id: string, answer: string) => { const ownVariants = [...useQuizViewStore.getState().ownVariants]; const ownVariantIndex = ownVariants.findIndex( - (variant) => variant.contentId === contentId + (variant) => variant.id === id ); if (ownVariantIndex < 0) { ownVariants.push({ - contentId, + id, variant: { id: getRandom(), answer, @@ -78,11 +77,11 @@ export const updateOwnVariant = (contentId: string, answer: string) => { useQuizViewStore.setState({ ownVariants }); }; -export const deleteOwnVariant = (contentId: string) => { +export const deleteOwnVariant = (id: string) => { const ownVariants = [...useQuizViewStore.getState().ownVariants]; const filteredOwnVariants = ownVariants.filter( - (variant) => variant.contentId !== contentId + (variant) => variant.id !== id ); useQuizViewStore.setState({ ownVariants: filteredOwnVariants }); diff --git a/src/stores/quizes.ts b/src/stores/quizes.ts deleted file mode 100644 index 0a43add..0000000 --- a/src/stores/quizes.ts +++ /dev/null @@ -1,167 +0,0 @@ -import {create} from "zustand"; -import {persist} from "zustand/middleware"; -import { removeQuestionsByQuizId } from "./questions"; - -interface QuizStore { - listQuizes: { [key: number]: Quizes }; - updateQuizesList: (id: number, values: unknown) => void; - removeQuiz: (id: number) => void; - createBlank: () => void; -} - -export interface Quizes { - id: number, - qid: string, - deleted: boolean, - archived: boolean, - fingerprinting: boolean, - repeatable: boolean, - note_prevented: boolean, - mail_notifications: boolean, - unique_answers: boolean, - name: string, - description: string, - status: string, - limit: number, - due_to: number, - time_of_passing: number, - pausable: boolean, - version: number, - version_comment: string, - created_at: string, - updated_at: string, - question_cnt: number, - passed_count: number, - average_time: number, - super: true, - group_id: number, - step: number, - startpage: string, - createResult: boolean, - config: { - type: string, - logo: string, - noStartPage: boolean, - startpage: { - description: string, - button: string, - position: string, - background: { - type: string, - desktop: string, - mobile: string, - video: string, - cycle: boolean - }, - }, - info: { - phonenumber: string, - clickable: boolean, - orgname: string, - site: string, - law?: string - }, - meta: string, - } -} - -/** @deprecated */ -export const quizStore = create()( - persist( - (set, get) => ({ - listQuizes: { - }, - updateQuizesList: (id: number, values: any) => { - const state = get()["listQuizes"] || {}; - state[id] = { - ...state[id], - ...values - }; - set({listQuizes: state}); - }, - removeQuiz: (id) => { - const state = get()["listQuizes"] || {}; - - const newState = Object.entries(state).reduce((accumulator, [key, value], index, array) => { - if (key !== id.toString()) { - accumulator[key] = value; - } - return accumulator; - }, {}); - set({listQuizes: newState}); - - removeQuestionsByQuizId(id); - }, - createBlank: () => { - const id = getRandom(1000000, 10000000) - const newListQuizes = get()["listQuizes"] || {}; - newListQuizes[id] = { - "id": id, - "qid": "", - "deleted": false, - "archived": true, - "fingerprinting": true, - "repeatable": true, - "note_prevented": true, - "mail_notifications": true, - "unique_answers": true, - "name": "", - "description": "", - "status": "", - "limit": 0, - "due_to": 0, - "time_of_passing": 0, - "pausable": true, - "version": 0, - "version_comment": "", - "created_at": "", - "updated_at": "", - "question_cnt": 0, - "passed_count": 0, - "average_time": 0, - "super": true, - "group_id": 0, - "step": 1, - "startpage": "", - "createResult": false, - "config": { - "noStartPage": false, - "type": "", // quiz или form - "logo": "hub.pena.digital/img/logo", - "startpage": { - "description": "",// приветственный текст опроса - "button": "", // текст на кнопке начала опроса - "position": "ltr", // ltr или rtl. отображение элементов поверх фона - "background": { - "type": "image", //image или video - "desktop": "", - "mobile": "", - "video":"", - "cycle": true //зацикливать видео или нет - }, - }, - "info": { - "phonenumber": "", - "clickable": true, - "orgname": "", - "site": "", - "law": "" - }, - "meta": "что-то" - } - }; - set({listQuizes: newListQuizes}); - return id; - }, - }), - { - name: "quizes", - } - ) -); - -function getRandom(min: number, max: number) { - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * (max - min)) + min; -} diff --git a/src/stores/quizes/actions.ts b/src/stores/quizes/actions.ts deleted file mode 100644 index 5cffdd6..0000000 --- a/src/stores/quizes/actions.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { quizApi } from "@api/quiz"; -import { devlog, getMessageFromFetchError } from "@frontend/kitui"; -import { quizToEditQuizRequest } from "@model/quiz/edit"; -import { Quiz, RawQuiz, rawQuizToQuiz } from "@model/quiz/quiz"; -import { QuizConfig, maxQuizSetupSteps } from "@model/quizSettings"; -import { produce } from "immer"; -import { enqueueSnackbar } from "notistack"; -import { NavigateFunction } from "react-router-dom"; -import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError"; -import { RequestQueue } from "../../utils/requestQueue"; -import { QuizStore, useQuizStore } from "./store"; -import { createUntypedQuestion } from "@root/questions/actions"; -import { useCurrentQuiz } from "./hooks" - - -export const setEditQuizId = (quizId: number | null) => setProducedState(state => { - state.editQuizId = quizId; -}, { - type: "setEditQuizId", - quizId, -}); - -export const resetEditConfig = () => setProducedState(state => { - state.editQuizId = null; - state.currentStep = 0; -}, "resetEditConfig"); - -export const setQuizes = (quizes: RawQuiz[] | null) => setProducedState(state => { - state.quizes = quizes?.map(rawQuizToQuiz) ?? []; -}, { - type: "setQuizes", - quizes, -}); - -const addQuiz = (quiz: Quiz) => setProducedState(state => { - state.quizes.push(quiz); -}, { - type: "addQuiz", - quiz, -}); - -const removeQuiz = (quizId: string) => setProducedState(state => { - const index = state.quizes.findIndex(q => q.id === quizId); - if (index === -1) return; - - state.quizes.splice(index, 1); -}, { - type: "removeQuiz", - quizId, -}); - -const setQuizBackendId = (quizId: string, backendId: number) => setProducedState(state => { - const quiz = state.quizes.find(q => q.id === quizId); - if (!quiz) return; - - quiz.backendId = backendId; -}, { - type: "setQuizBackendId", - quizId, - backendId, -}); - -export const incrementCurrentStep = () => setProducedState(state => { - state.currentStep = Math.min(maxQuizSetupSteps - 1, state.currentStep + 1); -}, { - type: "incrementCurrentStep", -}); - -export const decrementCurrentStep = () => setProducedState(state => { - state.currentStep = Math.max(0, state.currentStep - 1); -}, { - type: "decrementCurrentStep", -}); - -export const setCurrentStep = (step: number) => setProducedState(state => { - state.currentStep = Math.max(0, Math.min(maxQuizSetupSteps - 1, step)); -}, { - type: "setCurrentStep", - step, -}); - -export const setQuizType = ( - quizId: string, - quizType: QuizConfig["type"], -) => { - updateQuiz( - quizId, - quiz => { - quiz.config.type = quizType; - }, - ); -}; - -export const setQuizStartpageType = ( - quizId: string, - startpageType: QuizConfig["startpageType"], -) => { - updateQuiz( - quizId, - quiz => { - quiz.config.startpageType = startpageType; - }, - ); -}; - -const REQUEST_DEBOUNCE = 200; -const requestQueue = new RequestQueue(); -let requestTimeoutId: ReturnType; - -export const updateQuiz = ( - quizId: string | null | undefined, - updateFn: (quiz: Quiz) => void, -) => { - if (!quizId) return; - - setProducedState(state => { - const quiz = state.quizes.find(q => q.id === quizId); - if (!quiz) return; - - updateFn(quiz); - }, { - type: "updateQuiz", - quizId, - updateFn: updateFn.toString(), - }); - - clearTimeout(requestTimeoutId); - requestTimeoutId = setTimeout(async () => { - requestQueue.enqueue(async () => { - const quiz = useQuizStore.getState().quizes.find(q => q.id === quizId); - if (!quiz) return; - - const response = await quizApi.edit(quizToEditQuizRequest(quiz)); - - setQuizBackendId(quizId, response.updated); - setEditQuizId(response.updated); - }).catch(error => { - if (isAxiosCanceledError(error)) return; - - devlog("Error editing quiz", error, quizId); - enqueueSnackbar("Не удалось сохранить настройки квиза"); - }); - }, REQUEST_DEBOUNCE); -}; - -export const createQuiz = async (navigate: NavigateFunction) => requestQueue.enqueue(async () => { - try { - const rawQuiz = await quizApi.create(); - const quiz = rawQuizToQuiz(rawQuiz); - - addQuiz(quiz); - setEditQuizId(quiz.backendId); - navigate("/edit"); - - await createUntypedQuestion(rawQuiz.id); - } catch (error) { - devlog("Error creating quiz", error); - - const message = getMessageFromFetchError(error) ?? ""; - enqueueSnackbar(`Не удалось создать квиз. ${message}`); - } -}); - -export const deleteQuiz = async (quizId: string) => requestQueue.enqueue(async () => { - const quiz = useQuizStore.getState().quizes.find(q => q.id === quizId); - if (!quiz) return; - - try { - await quizApi.delete(quiz.backendId); - - removeQuiz(quizId); - } catch (error) { - devlog("Error deleting quiz", error); - - const message = getMessageFromFetchError(error) ?? ""; - enqueueSnackbar(`Не удалось удалить квиз. ${message}`); - } -}); -export const updateRootContentId = (quizId: string, id:string) => updateQuiz( - quizId, - quiz => { - console.log("Я изменение статуса корня проекта дерева, меняю на ", id) - quiz.config.haveRoot = id - }, -); - - -// TODO copy quiz - -export const uploadQuizImage = async ( - quizId: string, - blob: Blob, - updateFn: (quiz: Quiz, imageId: string) => void, -) => { - const quiz = useQuizStore.getState().quizes.find(q => q.id === quizId); - if (!quiz) return; - - try { - const response = await quizApi.addImages(quiz.backendId, blob); - - const values = Object.values(response); - if (values.length !== 1) { - console.warn("Error uploading image"); - return; - } - - const imageId = values[0]; - - updateQuiz(quizId, quiz => { - updateFn(quiz, `https://squiz.pena.digital/squizimages/${quiz.qid}/${imageId}`); - }); - } catch (error) { - devlog("Error uploading quiz image", error); - - enqueueSnackbar("Не удалось загрузить изображение"); - } -}; - -function setProducedState( - recipe: (state: QuizStore) => void, - action?: A, -) { - useQuizStore.setState(state => produce(state, recipe), false, action); -} diff --git a/src/stores/quizes/hooks.ts b/src/stores/quizes/hooks.ts deleted file mode 100644 index bcf7db0..0000000 --- a/src/stores/quizes/hooks.ts +++ /dev/null @@ -1,34 +0,0 @@ -import useSWR from "swr"; -import { useQuizStore } from "./store"; -import { quizApi } from "@api/quiz"; -import { setQuizes } from "./actions"; -import { isAxiosError } from "axios"; -import { devlog } from "@frontend/kitui"; -import { enqueueSnackbar } from "notistack"; - - - -export function useQuizes() { - const { isLoading, error, isValidating } = useSWR("quizes", () => quizApi.getList(), { - onSuccess: setQuizes, - onError: (error: unknown) => { - const message = isAxiosError(error) - ? error.response?.data ?? "" - : ""; - - devlog("Error getting quiz list", error); - enqueueSnackbar("Не удалось получить квизы"); - }, - }); - const quizes = useQuizStore(state => state.quizes); - - return { quizes, isLoading, error, isValidating }; -} - -export function useCurrentQuiz() { - const { quizes, editQuizId } = useQuizStore(); - - const quiz = quizes.find(q => q.backendId === editQuizId); - - return quiz; -} diff --git a/src/stores/quizes/store.ts b/src/stores/quizes/store.ts deleted file mode 100644 index 1656acd..0000000 --- a/src/stores/quizes/store.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Quiz } from "@model/quiz/quiz"; -import { create } from "zustand"; -import { devtools, persist } from "zustand/middleware"; - - -export type QuizStore = { - quizes: Quiz[]; - editQuizId: number | null; - currentStep: number; -}; - -const initialState: QuizStore = { - quizes: [], - editQuizId: null, - currentStep: 0, -}; - -export const useQuizStore = create()( - persist( - devtools( - () => initialState, - { - name: "QuizStore", - enabled: process.env.NODE_ENV === "development", - trace: process.env.NODE_ENV === "development", - } - ), { - name: "QuizStore", - partialize: state => ({ - editQuizId: state.editQuizId, - currentStep: state.currentStep, - }), - }) -); diff --git a/src/stores/uiTools/actions.ts b/src/stores/uiTools/actions.ts deleted file mode 100644 index 03c2a53..0000000 --- a/src/stores/uiTools/actions.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { useUiTools } from "./store"; - - - -export const updateOpenBranchingPanel = (value: boolean) => useUiTools.setState({ openBranchingPanel: value }); - - -export const cleardragQuestionContentId = () => { - useUiTools.setState({ dragQuestionContentId: null }); -}; -export const updateDragQuestionContentId = (contentId?: string) => { - useUiTools.setState({ dragQuestionContentId: contentId ? contentId : null }); -}; - - -let UDTOABM: ReturnType; -export const updateDesireToOpenABranchingModal = (contentId: string) => { - useUiTools.setState({ desireToOpenABranchingModal: contentId }); - clearTimeout(UDTOABM); - UDTOABM = setTimeout(() => { - useUiTools.setState({ desireToOpenABranchingModal: null }); - }, 7000); -}; -export const clearDesireToOpenABranchingModal = () => { - useUiTools.setState({ desireToOpenABranchingModal: null }); -}; - - -export const updateEditSomeQuestion = (contentId?: string) => { - useUiTools.setState({ editSomeQuestion: contentId === undefined ? null : contentId }); -}; - - -export const updateOpenedModalSettingsId = (id?: string) => useUiTools.setState({ openedModalSettingsId: id ? id : null }); \ No newline at end of file diff --git a/src/stores/uiTools/store.ts b/src/stores/uiTools/store.ts deleted file mode 100644 index 2a10299..0000000 --- a/src/stores/uiTools/store.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { create } from "zustand"; -import { devtools } from "zustand/middleware"; - - -export type UiTools = { - openedModalSettingsId: string | null; - dragQuestionContentId: string | null; - openBranchingPanel: boolean; - desireToOpenABranchingModal: string | null; - editSomeQuestion: string | null; -}; - -const initialState: UiTools = { - openedModalSettingsId: null as null, - dragQuestionContentId: null, - openBranchingPanel: false, - desireToOpenABranchingModal: null as null, - editSomeQuestion: null as null, -}; - -export const useUiTools = create()( - devtools( - () => initialState, - { - name: "UiTools", - enabled: process.env.NODE_ENV === "development", - trace: process.env.NODE_ENV === "development", - } - ) -); diff --git a/src/stores/user.ts b/src/stores/user.ts deleted file mode 100644 index a6e5ad1..0000000 --- a/src/stores/user.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { User } from "@frontend/kitui"; -import { produce } from "immer"; -import { create } from "zustand"; -import { createJSONStorage, devtools, persist } from "zustand/middleware"; - -interface UserStore { - userId: string | null; - user: User | null; - // userAccount: UserAccount | null; -} - -const initialState: UserStore = { - userId: null, - user: null, -}; - -export const useUserStore = create()( - persist( - devtools((set, get) => initialState, { - name: "User", - enabled: process.env.NODE_ENV === "development", - trace: true, - }), - { - version: 2, - name: "user", - storage: createJSONStorage(() => localStorage), - partialize: (state) => ({ - userId: state.userId, - user: state.user, - }), - migrate: (persistedState, version) => ({ - ...(persistedState as UserStore), - user: null, - }), - } - ) -); - -export const setUserId = (userId: string | null) => useUserStore.setState({ userId }); -export const setUser = (user: User) => - useUserStore.setState( - produce((state) => { - state.user = user; - }) - ); - -export const clearUserData = () => useUserStore.setState({ ...initialState }); diff --git a/src/ui_kit/ContactForm.tsx b/src/ui_kit/ContactForm.tsx index 1df3a99..99a5c49 100644 --- a/src/ui_kit/ContactForm.tsx +++ b/src/ui_kit/ContactForm.tsx @@ -1,19 +1,10 @@ -import { - Box, - Button, - IconButton, - TextField, - Typography, - useMediaQuery, - useTheme, - Modal, -} from "@mui/material"; -import { - sendContactForm, - setContactFormMailField, - setIsContactFormOpen, - useContactFormStore, -} from "../stores/contactForm"; +import { Box, Button, IconButton, TextField, Typography, useMediaQuery, useTheme, Modal } from "@mui/material"; +// import { +// sendContactForm, +// setContactFormMailField, +// setIsContactFormOpen, +// useContactFormStore, +// } from "../stores/contactForm"; import { enqueueSnackbar } from "notistack"; import X from "../assets/icons/x"; import PenaLogo from "../ui_kit/PenaLogo"; @@ -22,130 +13,130 @@ export default () => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("md")); - const isModalOpen = useContactFormStore((state) => state.isModalOpen); - const isSubmitDisabled = useContactFormStore( - (state) => state.isSubmitDisabled - ); - const mail = useContactFormStore((state) => state.mail); - const upMd = useMediaQuery(theme.breakpoints.up("md")); + // const isModalOpen = useContactFormStore((state) => state.isModalOpen); + // const isSubmitDisabled = useContactFormStore((state) => state.isSubmitDisabled); + // const mail = useContactFormStore((state) => state.mail); + // const upMd = useMediaQuery(theme.breakpoints.up("md")); - async function handleSendForm() { - const message = await sendContactForm(); + // async function handleSendForm() { + // const message = await sendContactForm(); - if (message) enqueueSnackbar(message); - } - - return ( - setIsContactFormOpen(false)} - aria-labelledby="modal-modal-title" - aria-describedby="modal-modal-description" - > - - setIsContactFormOpen(false)} - sx={{ - position: "absolute", - right: "7px", - top: "7px", - }} - > - - - - - - - Предрегистрация - - - E-mail - - ) => - // setContactFormMailField(e.target.value) - // } - // placeholder="username@penahaub.com" - // name="name" - // fullWidth - // sx={{ - // width: "100%", - // // mt: "25px", - // mb: "10px", - // "& .MuiInputBase-root": { - // backgroundColor: "#F2F3F7", - // height: "45px", - // borderRadius: "10px", - // }, - // }} - // inputProps={{ - // sx: { - // borderRadius: "10px", - // fontSize: "18px", - // lineHeight: "21px", - // py: 0, - // }, - // }} - /> - - - После запуска продукта вам придет сообщение на указанную электронную - почту - - - - ); -}; + // if (message) enqueueSnackbar(message); + // } +return <> +// return ( +// setIsContactFormOpen(false)} +// aria-labelledby="modal-modal-title" +// aria-describedby="modal-modal-description" +// > +// +// setIsContactFormOpen(false)} +// sx={{ +// position: "absolute", +// right: "7px", +// top: "7px", +// }} +// > +// +// +// +// +// +// +// Предрегистрация +// +// E-mail +// ) => setContactFormMailField(e.target.value)} +// placeholder="username@penahaub.com" +// name="name" +// fullWidth +// sx={{ +// width: "100%", +// // mt: "25px", +// mb: "10px", +// "& .MuiInputBase-root": { +// backgroundColor: "#F2F3F7", +// height: "45px", +// borderRadius: "10px", +// }, +// }} +// inputProps={{ +// sx: { +// borderRadius: "10px", +// fontSize: "18px", +// lineHeight: "21px", +// py: 0, +// }, +// }} +// /> +// +// +// После запуска продукта вам придет сообщение +// на указанную электронную почту +// +// +// +// ); + }; diff --git a/src/ui_kit/CreationCard.tsx b/src/ui_kit/CreationCard.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/CustomCheckbox.tsx b/src/ui_kit/CustomCheckbox.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/CustomTextField.tsx b/src/ui_kit/CustomTextField.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/Header/Avatar.tsx b/src/ui_kit/Header/Avatar.tsx deleted file mode 100644 index c8d488d..0000000 --- a/src/ui_kit/Header/Avatar.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Avatar, Box, SxProps, Theme, Typography } from "@mui/material"; - - -interface Props { - sx: SxProps; -} -export default function CustomAvatar({ sx }: Props) { - - return ( - - AA - - - - - - - - - ); -} \ No newline at end of file diff --git a/src/ui_kit/Header/Header.tsx b/src/ui_kit/Header/Header.tsx deleted file mode 100644 index 8a98318..0000000 --- a/src/ui_kit/Header/Header.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import BackArrowIcon from "@icons/BackArrowIcon"; -import EyeIcon from "@icons/EyeIcon"; -import { Box, Button, Container, FormControl, IconButton, TextField, useMediaQuery, useTheme } from "@mui/material"; -import { decrementCurrentStep } from "@root/quizes/actions"; -import PenaLogo from "../PenaLogo"; -import CustomAvatar from "./Avatar"; -import NavMenuItem from "./NavMenuItem"; -import { Link } from "react-router-dom"; - -export default function Header() { - const theme = useTheme(); - const isTablet = useMediaQuery(theme.breakpoints.down(1000)); - - return ( - - - - - - - - - - - - - - {isTablet ? null : ( - <> - - - - - - - - - - - - - )} - - ); -} diff --git a/src/ui_kit/Header/NavMenuItem.tsx b/src/ui_kit/Header/NavMenuItem.tsx deleted file mode 100644 index 45a844b..0000000 --- a/src/ui_kit/Header/NavMenuItem.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Link, Typography, useTheme } from "@mui/material"; - - -interface Props { - text: string; - isActive?: boolean; - onClick?: () => void; - href?: string -} - -export default function NavMenuItem({ href, onClick, text, isActive = false }: Props) { - const theme = useTheme(); - - return ( - - - {text} - - - ); -} \ No newline at end of file diff --git a/src/ui_kit/Header/NavbarCollapsed.tsx b/src/ui_kit/Header/NavbarCollapsed.tsx deleted file mode 100644 index 0cb25da..0000000 --- a/src/ui_kit/Header/NavbarCollapsed.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { IconButton, useTheme } from "@mui/material"; -import SectionWrapper from "../SectionWrapper"; -import MenuIcon from "@mui/icons-material/Menu"; -import PenaLogo from "@ui_kit/PenaLogo"; - - -interface Props { - isLoggedIn: boolean; -} - -export default function NavbarCollapsed({ isLoggedIn }: Props) { - const theme = useTheme(); - - return ( - - - - - - - ); -} \ No newline at end of file diff --git a/src/ui_kit/MenuItem.tsx b/src/ui_kit/MenuItem.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/MiniButtonSetting.tsx b/src/ui_kit/MiniButtonSetting.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/Modal/modal.css b/src/ui_kit/Modal/modal.css new file mode 100644 index 0000000..34f8fe9 --- /dev/null +++ b/src/ui_kit/Modal/modal.css @@ -0,0 +1,76 @@ +.ReactCrop__drag-bar, +.ord-e { + background-color: #7e2aea; +} + +.ReactCrop__crop-selection:not(.ReactCrop--no-animate .ReactCrop__crop-selection) { + background-image: none; +} + +.ReactCrop__drag-bar.ord-e { + right: 0; + top: 0; + width: 3px; + height: 100%; + margin-right: -3px; +} + +.ReactCrop__drag-bar.ord-s { + bottom: 0; + left: 0; + width: 100%; + height: 3px; + margin-bottom: -3px; +} + +.ReactCrop__drag-bar.ord-n { + bottom: 0; + left: 0; + width: 100%; + height: 3px; + margin-bottom: -3px; +} + +.ReactCrop__drag-bar.ord-w { + top: 0; + left: 0; + width: 3px; + height: 100%; + margin-left: -3px; +} + +/* кружочки */ + +.ReactCrop .ord-nw:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-n:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-ne:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-se:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-e:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-s:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-sw:after { + background-color: #7e2aea; +} + +.ReactCrop .ord-w:after { + background-color: #7e2aea; +} + +/* кружочки */ diff --git a/src/ui_kit/PenaLogo.tsx b/src/ui_kit/PenaLogo.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/PrivateRoute.tsx b/src/ui_kit/PrivateRoute.tsx deleted file mode 100644 index b42f735..0000000 --- a/src/ui_kit/PrivateRoute.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { useUserStore } from "@root/user"; -import { Navigate, Outlet } from "react-router-dom" - - -export default function PrivateRoute() { - const user = useUserStore(state => state.user) - - return user ? : -} diff --git a/src/ui_kit/QuestionsMiniButton.tsx b/src/ui_kit/QuestionsMiniButton.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/QuizPreview/QuizPreview.tsx b/src/ui_kit/QuizPreview/QuizPreview.tsx deleted file mode 100644 index 3fa01fe..0000000 --- a/src/ui_kit/QuizPreview/QuizPreview.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import VisibilityIcon from '@mui/icons-material/Visibility'; -import { Box, IconButton } from "@mui/material"; -import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview"; -import { useLayoutEffect, useRef } from "react"; -import { Rnd } from "react-rnd"; -import { useWindowSize } from "../../utils/hooks/useWindowSize"; -import QuizPreviewLayout from "./QuizPreviewLayout"; -import ResizeIcon from "@icons/ResizeIcon"; - -const DRAG_PARENT_MARGIN = 0; -const NAVBAR_HEIGHT = 0; -const DRAG_PARENT_BOTTOM_MARGIN = 0; - -interface RndPositionAndSize { - x: number; - y: number; - width: string; - height: string; -} - -export default function QuizPreview() { - const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown); - const rndParentRef = useRef(null); - const rndRef = useRef(null); - const rndPositionAndSizeRef = useRef({ - x: 0, - y: 0, - width: "340", - height: "480", - }); - const isFirstShowRef = useRef(true); - - useLayoutEffect( - function stickPreviewToBottomRight() { - const rnd = rndRef.current; - const rndSelfElement = rnd?.getSelfElement(); - if ( - !rnd || - !rndSelfElement || - !rndParentRef.current || - !isFirstShowRef.current - ) - return; - - const rndParentRect = rndParentRef.current.getBoundingClientRect(); - const rndRect = rndSelfElement.getBoundingClientRect(); - - const x = rndParentRect.width - rndRect.width; - const y = rndParentRect.height - rndRect.height; - - rnd.updatePosition({ x, y }); - rndPositionAndSizeRef.current.x = x; - rndPositionAndSizeRef.current.y = y; - - isFirstShowRef.current = false; - }, - [isPreviewShown] - ); - - return ( - - {isPreviewShown && ( - { - rndPositionAndSizeRef.current.x = position.x; - rndPositionAndSizeRef.current.y = position.y; - rndPositionAndSizeRef.current.width = ref.style.width; - rndPositionAndSizeRef.current.height = ref.style.height; - }} - onDragStop={(e, d) => { - rndPositionAndSizeRef.current.x = d.x; - rndPositionAndSizeRef.current.y = d.y; - }} - onDragStart={(e, d) => { - e.preventDefault(); - }} - enableResizing={{ - topLeft: isPreviewShown, - }} - resizeHandleComponent={{ - topLeft: , - }} - resizeHandleStyles={{ - topLeft: { - top: "-1px", - left: "-1px", - }, - }} - style={{ - overflow: "hidden", - pointerEvents: "auto", - }} - > - - - )} - - - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx b/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx deleted file mode 100644 index 2aec53d..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import { Box, Button, LinearProgress, Paper, Typography, FormControl, Select as MuiSelect, MenuItem, useTheme } from "@mui/material"; -import { useQuestionsStore } from "@root/questions/store"; -import { - decrementCurrentQuestionIndex, - incrementCurrentQuestionIndex, - useQuizPreviewStore, - setCurrentQuestionIndex -} from "@root/quizPreview"; -import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "model/questionTypes/shared"; -import { useEffect } from "react"; -import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft"; -import Date from "./QuizPreviewQuestionTypes/Date"; -import Emoji from "./QuizPreviewQuestionTypes/Emoji"; -import File from "./QuizPreviewQuestionTypes/File"; -import Images from "./QuizPreviewQuestionTypes/Images"; -import Number from "./QuizPreviewQuestionTypes/Number"; -import Page from "./QuizPreviewQuestionTypes/Page"; -import Rating from "./QuizPreviewQuestionTypes/Rating"; -import Select from "./QuizPreviewQuestionTypes/Select"; -import Text from "./QuizPreviewQuestionTypes/Text"; -import Variant from "./QuizPreviewQuestionTypes/Variant"; -import Varimg from "./QuizPreviewQuestionTypes/Varimg"; -import { notReachable } from "../../utils/notReachable"; -import ArrowDownIcon from "@icons/ArrowDownIcon"; - -export default function QuizPreviewLayout() { - const theme = useTheme(); - const questions = useQuestionsStore(state => state.questions); - const currentQuizStep = useQuizPreviewStore( - (state) => state.currentQuestionIndex - ); - - const nonDeletedQuizQuestions = questions.filter( - (question) => !question.deleted - ); - const maxCurrentQuizStep = - nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0; - const currentProgress = Math.floor( - (currentQuizStep / maxCurrentQuizStep) * 100 - ); - - const currentQuestion = nonDeletedQuizQuestions[currentQuizStep]; - - useEffect( - function resetCurrentQuizStep() { - if (currentQuizStep > maxCurrentQuizStep) { - decrementCurrentQuestionIndex(); - } - }, - [currentQuizStep, maxCurrentQuizStep] - ); - - return ( - - - - - - - - - setCurrentQuestionIndex(window.Number(target.value)) - } - sx={{ - height: "48px", - borderRadius: "8px", - "& .MuiOutlinedInput-notchedOutline": { - border: `1px solid ${theme.palette.brightPurple.main} !important`, - }, - }} - MenuProps={{ - PaperProps: { - sx: { - mt: "8px", - p: "4px", - borderRadius: "8px", - border: "1px solid #EEE4FC", - boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)", - }, - }, - MenuListProps: { - sx: { - py: 0, - display: "flex", - flexDirection: "column", - gap: "8px", - "& .Mui-selected": { - backgroundColor: theme.palette.background.default, - color: theme.palette.brightPurple.main, - }, - }, - }, - }} - inputProps={{ - sx: { - color: theme.palette.brightPurple.main, - display: "flex", - alignItems: "center", - px: "9px", - gap: "20px", - }, - }} - IconComponent={(props) => } - > - {Object.values(questions).map( - ({ id, title }, index) => ( - - {`${index + 1}. ${title}`} - - ) - )} - - - - - - - {nonDeletedQuizQuestions.length > 0 - ? `Вопрос ${currentQuizStep + 1} из ${nonDeletedQuizQuestions.length - }` - : "Нет вопросов"} - - {nonDeletedQuizQuestions.length > 0 && ( - - )} - - - - - - - - - ); -} - -function QuestionPreviewComponent({ question }: { - question: AnyTypedQuizQuestion | UntypedQuizQuestion | undefined; -}) { - if (!question || question.type === null) return null; - - switch (question.type) { - case "variant": return ; - case "images": return ; - case "varimg": return ; - case "emoji": return ; - case "text": return ; - case "select": return - - {file && Выбран файл: {file.name}} - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Images.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Images.tsx deleted file mode 100644 index 3fb00fb..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Images.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { useEffect, useState } from "react"; -import { - Box, - ButtonBase, - Divider, - Tooltip, - Typography, - useTheme, -} from "@mui/material"; - -import InfoIcon from "@icons/InfoIcon"; - -import type { QuizQuestionImages } from "model/questionTypes/images"; - -interface Props { - question: QuizQuestionImages; -} - -export default function Images({ question }: Props) { - const theme = useTheme(); - const [selectedVariants, setSelectedVariants] = useState([]); - - function handleVariantClick(index: number) { - if (!question.content.multi) return setSelectedVariants([index]); - - const newSelectedVariants = [...selectedVariants]; - if (newSelectedVariants.includes(index)) { - newSelectedVariants.splice(newSelectedVariants.indexOf(index), 1); - } else { - newSelectedVariants.push(index); - } - setSelectedVariants(newSelectedVariants); - } - - useEffect( - function resetSelectedVariants() { - setSelectedVariants([]); - }, - [question.content.multi] - ); - - return ( - - {question.title} - - {question.content.variants - .filter(({ answer }) => answer) - .map((variant, index) => ( - handleVariantClick(index)} - data-cy="variant-button" - data-checked={selectedVariants.includes(index)} - sx={{ - display: "flex", - flexDirection: "column", - borderRadius: "8px", - overflow: "hidden", - border: "1px solid", - borderColor: selectedVariants.includes(index) - ? theme.palette.brightPurple.main - : "#E3E3E3", - }} - > - {variant.extendedText ? ( - question variant - ) : ( - Картинка отсутствует - )} - - - {variant.answer} - {variant.hints && ( - - - - - - )} - - - ))} - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Number.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Number.tsx deleted file mode 100644 index b3218b0..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Number.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { useLayoutEffect, useState } from "react"; -import { Box, Typography } from "@mui/material"; - -import { CustomSlider } from "@ui_kit/CustomSlider"; - -import type { QuizQuestionNumber } from "model/questionTypes/number"; - -interface Props { - question: QuizQuestionNumber; -} - -export default function Number({ question }: Props) { - const [sliderValues, setSliderValues] = useState(0); - - const start = question.content.start; - const min = parseInt(question.content.range.split("—")[0]); - const max = parseInt(question.content.range.split("—")[1]); - - useLayoutEffect(() => { - if (question.content.chooseRange) { - setSliderValues([start, start + (max - start) / 2]); - } else { - setSliderValues(start); - } - }, [max, question.content.chooseRange, start]); - - return ( - - - {question.title} - - - { - setSliderValues(value); - }} - min={min} - max={max} - defaultValue={start} - step={question.content.step} - /> - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Page.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Page.tsx deleted file mode 100644 index 4567eee..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Box, Typography } from "@mui/material"; - -import type { QuizQuestionPage } from "model/questionTypes/page"; - -interface Props { - question: QuizQuestionPage; -} - -export default function Page({ question }: Props) { - return ( - - {question.title} - {question.content.text} - {question.content.picture && ( - - - - )} - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Rating.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Rating.tsx deleted file mode 100644 index c5b5e0f..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Rating.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { FC, useState } from "react"; -import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; - -import FlagIcon from "@icons/questionsPage/FlagIcon"; -import StarIconMini from "@icons/questionsPage/StarIconMini"; -import HashtagIcon from "@icons/questionsPage/hashtagIcon"; -import HeartIcon from "@icons/questionsPage/heartIcon"; -import LightbulbIcon from "@icons/questionsPage/lightbulbIcon"; -import LikeIcon from "@icons/questionsPage/likeIcon"; -import TropfyIcon from "@icons/questionsPage/tropfyIcon"; - -import type { QuizQuestionRating } from "model/questionTypes/rating"; - -type RatingIconType = - | "star" - | "trophie" - | "flag" - | "heart" - | "like" - | "bubble" - | "hashtag"; - -const ratingIconComponentByType: Record< - RatingIconType, - FC<{ color: string }> -> = { - star: StarIconMini, - trophie: TropfyIcon, - flag: FlagIcon, - heart: HeartIcon, - like: LikeIcon, - bubble: LightbulbIcon, - hashtag: HashtagIcon, -}; - -interface Props { - question: QuizQuestionRating; -} - -export default function Rating({ question }: Props) { - const theme = useTheme(); - const isMobile = useMediaQuery(theme.breakpoints.down(790)); - const [selectedRating, setSelectedRating] = useState(0); - - const RatingIconComponent = - ratingIconComponentByType[question.content.form as RatingIconType]; - - return ( - - {question.title} - - - {Array.from( - { length: question.content.steps }, - (_, index) => index - ).map((itemNumber) => ( - setSelectedRating(itemNumber + 1)} - data-cy="rating-button" - sx={{ - cursor: "pointer", - transform: "scale(1.5)", - ":hover": { - transform: "scale(1.7)", - transition: "0.2s", - }, - }} - > - itemNumber - ? theme.palette.brightPurple.main - : theme.palette.grey2.main - } - /> - - ))} - - - {question.content.ratingNegativeDescription} - {question.content.ratingPositiveDescription} - - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Select.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Select.tsx deleted file mode 100644 index 37197de..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Select.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import { useState } from "react"; -import { - Box, - FormControl, - MenuItem, - Select, - SelectChangeEvent, - Typography, - useTheme, -} from "@mui/material"; - -import ArrowDownIcon from "@icons/ArrowDownIcon"; - -import type { QuizQuestionSelect } from "model/questionTypes/select"; -interface Props { - question: QuizQuestionSelect; -} - -export default function Text({ question }: Props) { - const theme = useTheme(); - const [selectValue, setSelectValue] = useState(""); - - function handleChange(event: SelectChangeEvent) { - setSelectValue((event.target as HTMLInputElement).value); - } - - return ( - - {question.title} - - - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Text.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Text.tsx deleted file mode 100644 index a064967..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Text.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Box, Typography } from "@mui/material"; - -import CustomTextField from "@ui_kit/CustomTextField"; - -import type { QuizQuestionText } from "model/questionTypes/text"; - -interface Props { - question: QuizQuestionText; -} - -export default function Text({ question }: Props) { - return ( - - {question.title} - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Variant.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Variant.tsx deleted file mode 100644 index c9d3341..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Variant.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { ChangeEvent, useState } from "react"; -import { - Box, - FormControl, - FormControlLabel, - FormLabel, - Radio, - RadioGroup, - useRadioGroup, - Tooltip, - Typography, -} from "@mui/material"; - -import InfoIcon from "@icons/InfoIcon"; - -import type { QuizQuestionVariant } from "model/questionTypes/variant"; -import CustomRadio from "@ui_kit/CustomRadio"; -import RadioCheck from "@ui_kit/RadioCheck"; -import RadioIcon from "@ui_kit/RadioIcon"; - -interface Props { - question: QuizQuestionVariant; -} - -export default function Variant({ question }: Props) { - const [value, setValue] = useState(null); - - const handleChange = (event: ChangeEvent) => { - setValue((event.target as HTMLInputElement).value); - }; - - return ( - - - {question.title} - - - {question.content.variants - .filter(({ answer }) => answer) - .map((variant, index) => ( - } icon={} - /> - } - label={ - - - {variant.answer} - - {variant.hints && ( - - - - - - )} - - } - /> - ))} - - - ); -} diff --git a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Varimg.tsx b/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Varimg.tsx deleted file mode 100644 index de20292..0000000 --- a/src/ui_kit/QuizPreview/QuizPreviewQuestionTypes/Varimg.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import { useState, ChangeEvent } from "react"; -import { - Box, - FormControl, - FormControlLabel, - FormLabel, - Radio, - RadioGroup, - Tooltip, - Typography, useTheme, -} from "@mui/material"; - -import InfoIcon from "@icons/InfoIcon"; - -import type { QuestionVariant } from "model/questionTypes/shared"; -import type { QuizQuestionVarImg } from "model/questionTypes/varimg"; -import RadioCheck from "@ui_kit/RadioCheck"; -import RadioIcon from "@ui_kit/RadioIcon"; - -interface Props { - question: QuizQuestionVarImg; -} - -export default function Varimg({ question }: Props) { - const [selectedVariantIndex, setSelectedVariantIndex] = useState(-1); - const theme = useTheme(); - const handleChange = (event: ChangeEvent) => { - setSelectedVariantIndex( - question.content.variants.findIndex( - (variant) => variant.answer === event.target.value - ) - ); - }; - - const currentVariant: QuestionVariant | undefined = - question.content.variants[selectedVariantIndex]; - - return ( - - - - {question.title} - - - {question.content.variants - .filter(({ answer }) => answer) - .map((variant, index) => ( - } icon={} - /> - } - label={ - - {variant.answer} - {variant.hints && ( - - - - - - )} - - } - /> - ))} - - - - {currentVariant?.extendedText ? ( - question variant - ) : ( - - {selectedVariantIndex === -1 - ? "Выберите вариант" - : "Картинка отсутствует"} - - )} - - - ); -} diff --git a/src/ui_kit/SectionWrapper.tsx b/src/ui_kit/SectionWrapper.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/SelectableButton.tsx b/src/ui_kit/SelectableButton.tsx old mode 100644 new mode 100755 diff --git a/src/ui_kit/Sidebar.tsx b/src/ui_kit/Sidebar.tsx deleted file mode 100644 index 2d34d62..0000000 --- a/src/ui_kit/Sidebar.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import CollapseMenuIcon from "@icons/CollapseMenuIcon"; -import GearIcon from "@icons/GearIcon"; -import PencilCircleIcon from "@icons/PencilCircleIcon"; -import PuzzlePieceIcon from "@icons/PuzzlePieceIcon"; -import TagIcon from "@icons/TagIcon"; -import { quizSetupSteps } from "@model/quizSettings"; -import { - Box, - IconButton, - List, - Typography, - useTheme -} from "@mui/material"; -import { setCurrentStep } from "@root/quizes/actions"; -import { useQuizStore } from "@root/quizes/store"; -import { useState } from "react"; -import MenuItem from "./MenuItem"; - - -const quizSettingsMenuItems = [ - [TagIcon, "Дополнения"], - [PencilCircleIcon, "Дизайн"], - [PuzzlePieceIcon, "Интеграции"], - [GearIcon, "Настройки"], -] as const; - -export default function Sidebar() { - const theme = useTheme(); - const [isMenuCollapsed, setIsMenuCollapsed] = useState(false); - const currentStep = useQuizStore(state => state.currentStep); - - const handleMenuCollapseToggle = () => setIsMenuCollapsed((prev) => !prev); - - return ( - - - {!isMenuCollapsed && ( - - Создание квиза - - )} - - - - - - {quizSetupSteps.map((menuItem, index) => { - const Icon = menuItem.sidebarIcon; - - return ( - setCurrentStep(index)} - key={index} - text={menuItem.sidebarText} - isCollapsed={isMenuCollapsed} - isActive={currentStep === index} - icon={ - - } - /> - ); - })} - - {!isMenuCollapsed && ( - - Настройки квиза - - )} - - {quizSettingsMenuItems.map((menuItem, index) => { - const Icon = menuItem[0]; - const totalIndex = index + quizSetupSteps.length; - const isActive = currentStep === totalIndex + 1; - - return ( - null} - key={menuItem[1]} - text={menuItem[1]} - isActive={isActive} - isCollapsed={isMenuCollapsed} - icon={ - - } - /> - ); - })} - - - ); -} diff --git a/src/ui_kit/StartPagePreview/QuizPreviewLayout.tsx b/src/ui_kit/StartPagePreview/QuizPreviewLayout.tsx deleted file mode 100644 index 5747247..0000000 --- a/src/ui_kit/StartPagePreview/QuizPreviewLayout.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import { - Box, - Button, - ButtonBase, - Link, - Paper, - Typography, - useMediaQuery, - useTheme, -} from "@mui/material"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import YoutubeEmbedIframe from "./YoutubeEmbedIframe"; -import { QuizStartpageAlignType, QuizStartpageType } from "@model/quizSettings"; -import { notReachable } from "../../utils/notReachable"; -import { useUADevice } from "../../utils/hooks/useUADevice"; - - -export default function QuizPreviewLayout() { - const theme = useTheme(); - const quiz = useCurrentQuiz(); - const { isMobileDevice } = useUADevice(); - - if (!quiz) return null; - - const handleCopyNumber = () => { - navigator.clipboard.writeText(quiz.config.info.phonenumber); - }; - - const background = quiz.config.startpage.background.type === "image" - ? quiz.config.startpage.background.desktop - ? ( - - ) - : null - : quiz.config.startpage.background.type === "video" - ? quiz.config.startpage.background.video - ? ( - - ) - : null - : null; - - return ( - - - - {quiz.config.startpage.logo && ( - - )} - - {quiz.config.info.orgname} - - - } - quizMainBlock={<> - - {quiz.name} - - {quiz.config.startpage.description} - - - - - - - {quiz.config.info.clickable ? ( - isMobileDevice ? ( - - - {quiz.config.info.phonenumber} - - - ) : ( - - - {quiz.config.info.phonenumber} - - - ) - ) : ( - - {quiz.config.info.phonenumber} - - )} - - {quiz.config.info.law} - - - } - backgroundBlock={background} - startpageType={quiz.config.startpageType} - alignType={quiz.config.startpage.position} - /> - - ); -} - -function QuizPreviewLayoutByType({ quizHeaderBlock, quizMainBlock, backgroundBlock, startpageType, alignType }: { - quizHeaderBlock: JSX.Element; - quizMainBlock: JSX.Element; - backgroundBlock: JSX.Element | null; - startpageType: QuizStartpageType; - alignType: QuizStartpageAlignType; -}) { - const theme = useTheme(); - const isTablet = useMediaQuery(theme.breakpoints.down(630)); - - switch (startpageType) { - case null: - case "standard": { - return ( - - - {quizHeaderBlock} - {quizMainBlock} - - - {backgroundBlock} - - - ); - } - case "expanded": { - return ( - - - {quizHeaderBlock} - {quizMainBlock} - - - {backgroundBlock} - - - ); - } - case "centered": { - return ( - - {quizHeaderBlock} - {backgroundBlock && - - {backgroundBlock} - - } - {quizMainBlock} - - ); - } - default: notReachable(startpageType); - } -} - -const startpageAlignTypeToJustifyContent: Record = { - left: "start", - center: "center", - right: "end", -}; diff --git a/src/ui_kit/StartPagePreview/index.tsx b/src/ui_kit/StartPagePreview/index.tsx deleted file mode 100644 index 9744248..0000000 --- a/src/ui_kit/StartPagePreview/index.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import VisibilityIcon from "@mui/icons-material/Visibility"; -import { Box, IconButton, useTheme, useMediaQuery } from "@mui/material"; -import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview"; -import { useLayoutEffect, useRef } from "react"; -import { Rnd } from "react-rnd"; -import QuizPreviewLayout from "./QuizPreviewLayout"; -import ResizeIcon from "@icons/ResizeIcon"; - -const DRAG_PARENT_MARGIN = 0; -const NAVBAR_HEIGHT = 0; -const DRAG_PARENT_BOTTOM_MARGIN = 0; - -interface RndPositionAndSize { - x: number; - y: number; - width: string; - height: string; -} - -export const StartPagePreview = () => { - const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown); - const rndParentRef = useRef(null); - const rndRef = useRef(null); - const theme = useTheme(); - const isTablet = useMediaQuery(theme.breakpoints.down(630)); - const rndPositionAndSizeRef = useRef({ - x: 0, - y: 0, - width: isTablet ? "350" : "600", - height: "330", - }); - const isFirstShowRef = useRef(true); - - useLayoutEffect( - function stickPreviewToBottomRight() { - const rnd = rndRef.current; - const rndSelfElement = rnd?.getSelfElement(); - if ( - !rnd || - !rndSelfElement || - !rndParentRef.current || - !isFirstShowRef.current - ) - return; - - const rndParentRect = rndParentRef.current.getBoundingClientRect(); - const rndRect = rndSelfElement.getBoundingClientRect(); - - const x = rndParentRect.width - rndRect.width; - const y = rndParentRect.height - rndRect.height; - - rnd.updatePosition({ x, y }); - rndPositionAndSizeRef.current.x = x; - rndPositionAndSizeRef.current.y = y; - - isFirstShowRef.current = false; - }, - [isPreviewShown] - ); - - return ( - - {isPreviewShown && ( - { - rndPositionAndSizeRef.current.x = position.x; - rndPositionAndSizeRef.current.y = position.y; - rndPositionAndSizeRef.current.width = ref.style.width; - rndPositionAndSizeRef.current.height = ref.style.height; - }} - onDragStop={(e, d) => { - rndPositionAndSizeRef.current.x = d.x; - rndPositionAndSizeRef.current.y = d.y; - }} - onDragStart={(e, d) => { - e.preventDefault(); - }} - enableResizing={{ - topLeft: isPreviewShown, - }} - resizeHandleComponent={{ - topLeft: , - }} - resizeHandleStyles={{ - topLeft: { - top: "-1px", - left: "-1px", - zIndex: 100, - }, - }} - style={{ - overflow: "hidden", - pointerEvents: "auto", - borderRadius: "5px", - }} - > - - - )} - - - - - ); -}; diff --git a/src/ui_kit/Stepper.tsx b/src/ui_kit/Stepper.tsx old mode 100644 new mode 100755 index c695ce1..152d741 --- a/src/ui_kit/Stepper.tsx +++ b/src/ui_kit/Stepper.tsx @@ -1,61 +1,61 @@ -import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; -import MobileStepper from "@mui/material/MobileStepper"; -import { maxQuizSetupSteps, quizSetupSteps } from "@model/quizSettings"; - -interface Props { - activeStep: number; -} - -export default function ProgressMobileStepper({ - activeStep, -}: Props) { - const theme = useTheme(); - const isTablet = useMediaQuery(theme.breakpoints.down(1000)); - - return ( - - } - backButton={<>} - /> - - - {" "} - Шаг {activeStep + 1 } из {maxQuizSetupSteps} - - {quizSetupSteps[activeStep].stepperText} - - - ); -} +import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; +import MobileStepper from "@mui/material/MobileStepper"; +import { maxQuizSetupSteps, quizSetupSteps } from "@model/quizSettings"; + +interface Props { + activeStep: number; +} + +export default function ProgressMobileStepper({ + activeStep, +}: Props) { + const theme = useTheme(); + const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + + return ( + + } + backButton={<>} + /> + + + {" "} + Шаг {activeStep + 1 } из {maxQuizSetupSteps} + + {quizSetupSteps[activeStep].stepperText} + + + ); +} diff --git a/src/ui_kit/UploadBox.tsx b/src/ui_kit/UploadBox.tsx old mode 100644 new mode 100755 diff --git a/src/utils/notReachable.ts b/src/utils/notReachable.ts index 4c23636..4063c2a 100644 --- a/src/utils/notReachable.ts +++ b/src/utils/notReachable.ts @@ -1,3 +1,3 @@ -export function notReachable(error: string): never { - throw new Error(`Shouldn't reach here: ${error}`); +export function notReachable(_: never): never { + throw new Error(`Shouldn't reach here: ${_}`); } diff --git a/src/utils/themes/dark.ts b/src/utils/themes/dark.ts old mode 100644 new mode 100755 diff --git a/src/utils/themes/generic.ts b/src/utils/themes/generic.ts old mode 100644 new mode 100755 diff --git a/src/utils/themes/light.ts b/src/utils/themes/light.ts old mode 100644 new mode 100755 diff --git a/tsconfig.extend.json b/tsconfig.extend.json old mode 100644 new mode 100755 index 638166f..81832f9 --- a/tsconfig.extend.json +++ b/tsconfig.extend.json @@ -2,9 +2,6 @@ "compilerOptions": { "baseUrl": "./src", "paths": { - "@/*": [ - "./*" - ], "@ui_kit/*": [ "./ui_kit/*" ], diff --git a/tsconfig.json b/tsconfig.json old mode 100644 new mode 100755 index 7de1dea..cf78e18 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,32 @@ { - "extends": "./tsconfig.extend.json", - "compilerOptions": { - "target": "es2015", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" - }, - "include": ["src"], - "exclude": ["cypress.config.ts", "cypress", "node_modules"] + "extends": "./tsconfig.extend.json", + "compilerOptions": { + "target": "es2015", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "include": [ + "src", + ], + "exclude": [ + "cypress.config.ts", + "cypress", + "node_modules", + ] } diff --git a/yarn.lock b/yarn.lock index f256826..931571e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1157,7 +1157,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@craco/craco@^7.1.0": +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@craco/craco@^7.0.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@craco/craco/-/craco-7.1.0.tgz#12bd394c7f0334e214302e4d35a1768f68042fbb" integrity sha512-oRAcPIKYrfPXp9rSzlsDNeOaVtDiKhoyqSXUoqiK24jCkHr4T8m/a2f74yXIzCbIheoUWDOIfWZyRgFgT+cpqA== @@ -1288,6 +1293,38 @@ resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== +"@cypress/request@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.1.tgz#72d7d5425236a2413bd3d8bb66d02d9dc3168960" + integrity sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + http-signature "~1.3.6" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "6.10.4" + safe-buffer "^5.1.2" + tough-cookie "^4.1.3" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + "@emoji-mart/data@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@emoji-mart/data/-/data-1.1.2.tgz#777c976f8f143df47cbb23a7077c9ca9fe5fc513" @@ -1343,7 +1380,7 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== -"@emotion/react@^11.11.1": +"@emotion/react@^11.10.5": version "11.11.1" resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== @@ -1373,7 +1410,7 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== -"@emotion/styled@^11.11.0": +"@emotion/styled@^11.10.5": version "11.11.0" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== @@ -1432,10 +1469,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.55.0": - version "8.55.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6" - integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA== +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== "@floating-ui/core@^1.4.2": version "1.5.2" @@ -1465,9 +1502,9 @@ integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== "@frontend/kitui@^1.0.54": - version "1.0.54" - resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.54.tgz#0235d5a8effb9b92351471c3c7775f28cb2839f6" - integrity sha1-AjXVqO/7m5I1FHHDx3dfKMsoOfY= + version "1.0.59" + resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.59.tgz#c4584506bb5cab4fc1df35f5b1d0d66ec379a9a1" + integrity sha1-xFhFBrtcq0/B3zX1sdDWbsN5qaE= dependencies: immer "^10.0.2" reconnecting-eventsource "^1.6.2" @@ -1788,14 +1825,14 @@ resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.0.tgz#6b45d5bff38f305402d24d3bf86075b56c578909" integrity sha512-NpGtlHwuyLfJtdrlERXb8qRqd279O0VnuGaZAor1ehdNhUJOD1bSxHDeXKZkbqNpvi50hasFj7lsbTpluworTQ== -"@mui/icons-material@^5.15.0": +"@mui/icons-material@^5.10.14": version "5.15.0" resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.15.0.tgz#fdc93611ca77ce3b79128be02fb6c1ae79b972b8" integrity sha512-zHY6fOkaK7VfhWeyxO8MjO3IAjEYpYMXuqUhX7TkUZJ9+TSH/9dn4ClG4K2j6hdgBU5Yrq2Z/89Bo6BHHp7AdQ== dependencies: "@babel/runtime" "^7.23.5" -"@mui/material@^5.15.0": +"@mui/material@^5.10.14": version "5.15.0" resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.15.0.tgz#f801cf56d505cc52dca225438360ab9c62057285" integrity sha512-60CDI/hQNwJv9a3vEZtFG7zz0USdQhVwpBd3fZqrzhuXSdiMdYMaZcCXeX/KMuNq0ZxQEAZd74Pv+gOb408QVA== @@ -1861,10 +1898,10 @@ prop-types "^15.8.1" react-is "^18.2.0" -"@mui/x-date-pickers@^6.18.4": - version "6.18.4" - resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-6.18.4.tgz#0b54634d182b5fdf6337c0915f39b606c094b64f" - integrity sha512-YqJ6lxZHBIt344B3bvRAVbdYSQz4dcmJQXGcfvJTn26VdKjpgzjAqwhlbQhbAt55audJOWzGB99ImuQuljDROA== +"@mui/x-date-pickers@^6.16.1": + version "6.18.5" + resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-6.18.5.tgz#a2a70ce2926f0acb8ee414b546ba1f7daf399c21" + integrity sha512-3jImYIWP2Xgi608yzm/Sz1v0MTjQQYdZSQOEIi3dWBfSAU9B06KXDpqlXfRSpTV+rtsnfYIIyiWlz6Ltk7sUWw== dependencies: "@babel/runtime" "^7.23.2" "@mui/base" "^5.0.0-beta.22" @@ -1917,7 +1954,7 @@ schema-utils "^3.0.0" source-map "^0.7.3" -"@popperjs/core@^2.11.8": +"@popperjs/core@^2.0.0", "@popperjs/core@^2.11.8": version "2.11.8" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== @@ -1965,9 +2002,9 @@ picomatch "^2.2.2" "@rushstack/eslint-patch@^1.1.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz#1898e7a7b943680d757417a47fb10f5fcc230b39" - integrity sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA== + version "1.6.1" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz#9ab8f811930d7af3e3d549183a50884f9eb83f36" + integrity sha512-UY+FGM/2jjMkzQLn8pxcHGMaVLh9aEitG3zY2CiY7XHdLiz3bZOwa6oDxNqEMv7zZkV+cj5DOdz0cQ1BP5Hjgw== "@sinclair/typebox@^0.24.1": version "0.24.51" @@ -2143,9 +2180,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.7" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.7.tgz#a7aebf15c7bc0eb9abd638bdb5c0b8700399c9d0" - integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" @@ -2194,6 +2231,19 @@ dependencies: "@types/node" "*" +"@types/cytoscape-popper@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/cytoscape-popper/-/cytoscape-popper-2.0.4.tgz#cd1e81d28b202e2bfc5608e0e60ae53c908bf0e3" + integrity sha512-vGRiAMXeEIoY5ziPO0NrS8xmJyVkT8j8ARzvyD/x6CXciAO1+80Q2/Triyd9/+5I4PeatGo1Pch5YBwDMB1D6A== + dependencies: + "@popperjs/core" "^2.0.0" + "@types/cytoscape" "*" + +"@types/cytoscape@*": + version "3.19.16" + resolved "https://registry.yarnpkg.com/@types/cytoscape/-/cytoscape-3.19.16.tgz#c54ad4ff5c53a0046f42d1b08a11e730ad83dcc1" + integrity sha512-A3zkjaZ6cOGyqEvrVuC1YUgiRSJhDZOj8Qhd1ALH2/+YxH2za1BOmR4RWQsKYHsc+aMP/IWoqg1COuUbZ39t/g== + "@types/eslint-scope@^3.7.3": version "3.7.7" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" @@ -2247,6 +2297,14 @@ dependencies: "@types/node" "*" +"@types/hoist-non-react-statics@^3.3.1": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494" + integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" @@ -2310,13 +2368,25 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^20.10.4": +"@types/node@*": version "20.10.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198" integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== dependencies: undici-types "~5.26.4" +"@types/node@^16.7.13": + version "16.18.68" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.68.tgz#3155f64a961b3d8d10246c80657f9a7292e3421a" + integrity sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg== + +"@types/node@^18.17.5": + version "18.19.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.3.tgz#e4723c4cb385641d61b983f6fe0b716abd5f8fc0" + integrity sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg== + dependencies: + undici-types "~5.26.4" + "@types/parse-json@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" @@ -2347,7 +2417,22 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== -"@types/react-dom@^18.2.18": +"@types/react-beautiful-dnd@^13.1.4": + version "13.1.7" + resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.7.tgz#cc8038896ee7dee99b8bfd0eaed0a02a8617bedc" + integrity sha512-jQZLov9OkD0xRQkqz8/lx66bHYAYv+g4+POBqnH5Jtt/xo4MygzM879Q9sxAiosPBdNj1JYTdbPxDn3dNRYgow== + dependencies: + "@types/react" "*" + +"@types/react-cytoscapejs@^1.2.4": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/react-cytoscapejs/-/react-cytoscapejs-1.2.5.tgz#6648bbcc0f243b08b65a8753225b541068764653" + integrity sha512-G9VcGQOlER3njklOu5D0FDGHYfkQJ3yEL95kGbgI/MR08N5dQ7IbLSZI8WqaB4fG0zOURIg0BUtOCrbE5HRZEQ== + dependencies: + "@types/cytoscape" "*" + "@types/react" "*" + +"@types/react-dom@^18.0.0": version "18.2.18" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.18.tgz#16946e6cd43971256d874bc3d0a72074bb8571dd" integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw== @@ -2361,7 +2446,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.2.45": +"@types/react@*", "@types/react@^18.0.0": version "18.2.45" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.45.tgz#253f4fac288e7e751ab3dc542000fb687422c15c" integrity sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg== @@ -2416,6 +2501,16 @@ "@types/mime" "*" "@types/node" "*" +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== + +"@types/sizzle@^2.3.2": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.8.tgz#518609aefb797da19bf222feb199e8f653ff7627" + integrity sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg== + "@types/sockjs@^0.3.33": version "0.3.36" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" @@ -2459,6 +2554,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yauzl@^2.9.1": + version "2.10.3" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999" + integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q== + dependencies: + "@types/node" "*" + "@typescript-eslint/eslint-plugin@^5.5.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" @@ -2757,6 +2859,14 @@ agent-base@6: dependencies: debug "4" +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -2796,7 +2906,12 @@ ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: require-from-string "^2.0.2" uri-js "^4.2.2" -ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -2850,6 +2965,11 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -2984,12 +3104,29 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + ast-types-flow@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== -async@^3.2.3: +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@^3.2.0, async@^3.2.3: version "3.2.5" resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== @@ -3028,12 +3165,22 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + axe-core@=4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== -axios@^1.6.2: +axios@^1.5.1: version "1.6.2" resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== @@ -3190,11 +3337,23 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + bfj@^7.0.2: version "7.1.0" resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.1.0.tgz#c5177d522103f9040e1b12980fe8c38cf41d3f8b" @@ -3216,6 +3375,11 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== + bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -3298,11 +3462,24 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + builtin-modules@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" @@ -3318,6 +3495,11 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cachedir@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" + integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ== + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" @@ -3375,6 +3557,11 @@ case-sensitive-paths-webpack-plugin@^2.4.0: resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3402,6 +3589,11 @@ char-regex@^2.0.0: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e" integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== +check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== + check-types@^11.2.3: version "11.2.3" resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.3.tgz#1ffdf68faae4e941fce252840b1787b8edc93b71" @@ -3444,6 +3636,35 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-table3@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" + integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + client-only@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" @@ -3467,7 +3688,7 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clsx@^1.1.0, clsx@^1.1.1: +clsx@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -3525,12 +3746,12 @@ colord@^2.9.1: resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== -colorette@^2.0.10: +colorette@^2.0.10, colorette@^2.0.16: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== -combined-stream@^1.0.8: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -3547,6 +3768,11 @@ commander@^4.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" @@ -3656,6 +3882,11 @@ core-js@^3.19.2: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.34.0.tgz#5705e6ad5982678612e96987d05b27c6c7c274a5" integrity sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag== +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -3701,7 +3932,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3905,11 +4136,67 @@ csstype@^3.0.2, csstype@^3.1.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +cypress@^13.6.1: + version "13.6.1" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.6.1.tgz#c5f714f08551666ed3ac1fa95718eabb23a416df" + integrity sha512-k1Wl5PQcA/4UoTffYKKaxA0FJKwg8yenYNYRzLt11CUR0Kln+h7Udne6mdU1cUIdXBDTVZWtmiUjzqGs7/pEpw== + dependencies: + "@cypress/request" "^3.0.0" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^18.17.5" + "@types/sinonjs__fake-timers" "8.1.1" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + buffer "^5.6.0" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + cli-cursor "^3.1.0" + cli-table3 "~0.6.1" + commander "^6.2.1" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.4" + enquirer "^2.3.6" + eventemitter2 "6.4.7" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-ci "^3.0.0" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.8" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + process "^0.11.10" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.5.3" + supports-color "^8.1.1" + tmp "~0.2.1" + untildify "^4.0.0" + yauzl "^2.10.0" + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -3919,7 +4206,7 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -dayjs@^1.11.10: +dayjs@^1.10.4, dayjs@^1.11.10: version "1.11.10" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== @@ -3938,7 +4225,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" -debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -3960,6 +4247,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + deepmerge@^4.2.2: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" @@ -4187,6 +4479,14 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4200,9 +4500,9 @@ ejs@^3.1.6: jake "^10.8.5" electron-to-chromium@^1.4.601: - version "1.4.612" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.612.tgz#350c6fd4201d677307519b931949fa64dae6a5cc" - integrity sha512-dM8BMtXtlH237ecSMnYdYuCkib2QHq0kpWfUnavjdYsyr/6OsAwg5ZGUfnQ9KD1Ga4QgB2sqXlB2NT8zy2GnVg== + version "1.4.614" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz#2fe789d61fa09cb875569f37c309d0c2701f91c0" + integrity sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ== emittery@^0.10.2: version "0.10.2" @@ -4214,6 +4514,11 @@ emittery@^0.8.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== +emoji-mart@^5.5.2: + version "5.5.2" + resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-5.5.2.tgz#3ddbaf053139cf4aa217650078bc1c50ca8381af" + integrity sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -4234,6 +4539,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enhanced-resolve@^5.15.0: version "5.15.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" @@ -4242,6 +4554,14 @@ enhanced-resolve@^5.15.0: graceful-fs "^4.2.4" tapable "^2.2.0" +enquirer@^2.3.6: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -4454,9 +4774,9 @@ eslint-plugin-flowtype@^8.0.3: string-natural-compare "^3.0.1" eslint-plugin-import@^2.25.3: - version "2.29.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" - integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== dependencies: array-includes "^3.1.7" array.prototype.findlastindex "^1.2.3" @@ -4474,7 +4794,7 @@ eslint-plugin-import@^2.25.3: object.groupby "^1.0.1" object.values "^1.1.7" semver "^6.3.1" - tsconfig-paths "^3.14.2" + tsconfig-paths "^3.15.0" eslint-plugin-jest@^25.3.0: version "25.7.0" @@ -4577,14 +4897,14 @@ eslint-webpack-plugin@^3.1.1: schema-utils "^4.0.0" eslint@^8.3.0: - version "8.55.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.55.0.tgz#078cb7b847d66f2c254ea1794fa395bf8e7e03f8" - integrity sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA== + version "8.56.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.55.0" + "@eslint/js" "8.56.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -4678,6 +4998,11 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -4688,6 +5013,21 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +execa@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -4703,6 +5043,13 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -4755,6 +5102,32 @@ express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -4781,11 +5154,6 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fast-memoize@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.2.tgz#79e3bb6a4ec867ea40ba0e7146816f6cdce9b57e" - integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw== - fastq@^1.6.0: version "1.15.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" @@ -4807,6 +5175,20 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4922,6 +5304,11 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.3" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" @@ -4959,6 +5346,29 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +formik@^2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/formik/-/formik-2.4.5.tgz#f899b5b7a6f103a8fabb679823e8fafc7e0ee1b4" + integrity sha512-Gxlht0TD3vVdzMDHwkiNZqJ7Mvg77xQNfmBRrNtvzcHZs72TJppSTDKHpImCMJZwcWPBJ8jSQQ95GJzXFf1nAQ== + dependencies: + "@types/hoist-non-react-statics" "^3.3.1" + deepmerge "^2.1.1" + hoist-non-react-statics "^3.3.0" + lodash "^4.17.21" + lodash-es "^4.17.21" + react-fast-compare "^2.0.1" + tiny-warning "^1.0.2" + tslib "^2.0.0" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -4983,7 +5393,7 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0, fs-extra@^9.0.1: +fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -5058,6 +5468,13 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -5071,6 +5488,20 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== + dependencies: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -5114,6 +5545,13 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -5251,7 +5689,7 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hoist-non-react-statics@^3.3.1: +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -5384,6 +5822,15 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-signature@~1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" + integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== + dependencies: + assert-plus "^1.0.0" + jsprim "^2.0.2" + sshpk "^1.14.1" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -5392,6 +5839,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5428,12 +5880,17 @@ identity-obj-proxy@^3.0.0: dependencies: harmony-reflect "^1.4.6" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== -immer@^10.0.2: +immer@^10.0.2, immer@^10.0.3: version "10.0.3" resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.3.tgz#a8de42065e964aa3edf6afc282dfc7f7f34ae3c9" integrity sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A== @@ -5464,6 +5921,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -5482,6 +5944,11 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + ini@^1.3.5: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" @@ -5554,6 +6021,13 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + is-core-module@^2.13.0, is-core-module@^2.13.1: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" @@ -5609,6 +6083,14 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-map@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -5641,7 +6123,7 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== -is-path-inside@^3.0.3: +is-path-inside@^3.0.2, is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -5719,11 +6201,16 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: dependencies: which-typed-array "^1.1.11" -is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -5771,6 +6258,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" @@ -6341,6 +6833,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" @@ -6404,7 +6901,7 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@^0.4.0: +json-schema@0.4.0, json-schema@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== @@ -6414,6 +6911,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" @@ -6449,6 +6951,16 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jsprim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" + integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -6501,6 +7013,11 @@ launch-editor@^2.6.0: picocolors "^1.0.0" shell-quote "^1.8.1" +lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -6537,6 +7054,20 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +listr2@^3.8.3: + version "3.14.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -6578,6 +7109,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -6593,6 +7129,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -6608,6 +7149,24 @@ lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -6724,7 +7283,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -6767,7 +7326,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -6816,6 +7375,11 @@ nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +nanoid@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.4.tgz#d2b608d8169d7da669279127615535705aa52edf" + integrity sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig== + natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -6882,7 +7446,7 @@ notistack@^3.0.1: clsx "^1.1.0" goober "^2.0.33" -npm-run-path@^4.0.1: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -7011,14 +7575,14 @@ on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -onetime@^5.1.2: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -7058,6 +7622,11 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== + p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -7093,6 +7662,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-retry@^4.5.0: version "4.6.2" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" @@ -7184,6 +7760,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -7204,7 +7785,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatc resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.3.0: +pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -7790,7 +8371,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1, pretty-bytes@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== @@ -7827,6 +8408,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise@^8.1.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -7851,6 +8437,11 @@ prop-types@^15.6.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +property-expr@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" + integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -7859,6 +8450,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -7869,6 +8465,14 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -7879,6 +8483,13 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== +qs@6.10.4: + version "6.10.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.4.tgz#6a3003755add91c0ec9eacdc5f878b034e73f9e7" + integrity sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g== + dependencies: + side-channel "^1.0.4" + qs@6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -7925,13 +8536,6 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -re-resizable@6.9.6: - version "6.9.6" - resolved "https://registry.yarnpkg.com/re-resizable/-/re-resizable-6.9.6.tgz#b95d37e3821481b56ddfb1e12862940a791e827d" - integrity sha512-0xYKS5+Z0zk+vICQlcZW+g54CcJTTmHluA7JUUgvERDxnKAnytylcyPsA+BSFi759s5hPlHmBRegFrwXs2FuBQ== - dependencies: - fast-memoize "^2.5.1" - react-app-polyfill@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" @@ -7982,19 +8586,23 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" -react-draggable@4.4.5: - version "4.4.5" - resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.5.tgz#9e37fe7ce1a4cf843030f521a0a4cc41886d7e7c" - integrity sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g== +react-error-boundary@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.12.tgz#59f8f1dbc53bbbb34fc384c8db7cf4082cb63e2c" + integrity sha512-kJdxdEYlb7CPC1A0SeUY38cHpjuu6UkvzKiAmqmOFL21VRfMhOcWxTCBgLVCO0VEMh9JhFNcVaXlV4/BTpiwOA== dependencies: - clsx "^1.1.1" - prop-types "^15.8.1" + "@babel/runtime" "^7.12.5" react-error-overlay@^6.0.11: version "6.0.11" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== +react-fast-compare@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -8015,16 +8623,7 @@ react-refresh@^0.11.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== -react-rnd@^10.4.1: - version "10.4.1" - resolved "https://registry.yarnpkg.com/react-rnd/-/react-rnd-10.4.1.tgz#9e1c3f244895d7862ef03be98b2a620848c3fba1" - integrity sha512-0m887AjQZr6p2ADLNnipquqsDq4XJu/uqVqI3zuoGD19tRm6uB83HmZWydtkilNp5EWsOHbLGF4IjWMdd5du8Q== - dependencies: - re-resizable "6.9.6" - react-draggable "4.4.5" - tslib "2.3.1" - -react-router-dom@^6.21.0: +react-router-dom@^6.6.2: version "6.21.0" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.21.0.tgz#aa4c6bc046a8e8723095bc09b3c0ab2254532712" integrity sha512-1dUdVj3cwc1npzJaf23gulB562ESNvxf7E4x8upNJycqyUm5BRRZ6dd3LrlzhtLaMrwOCO8R0zoiYxdaJx4LlQ== @@ -8039,7 +8638,7 @@ react-router@6.21.0: dependencies: "@remix-run/router" "1.14.0" -react-scripts@^5.0.1: +react-scripts@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" integrity sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ== @@ -8189,9 +8788,9 @@ regenerator-runtime@^0.13.9: integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== regenerator-transform@^0.15.2: version "0.15.2" @@ -8249,6 +8848,13 @@ renderkid@^3.0.0: lodash "^4.17.21" strip-ansi "^6.0.1" +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== + dependencies: + throttleit "^1.0.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -8315,6 +8921,14 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + retry@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" @@ -8325,6 +8939,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -8356,6 +8975,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rxjs@^7.5.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + safe-array-concat@^1.0.0, safe-array-concat@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" @@ -8371,7 +8997,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8385,7 +9011,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -8622,6 +9248,24 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + sockjs@^0.3.24: version "0.3.24" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" @@ -8713,6 +9357,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sshpk@^1.14.1: + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -8926,7 +9585,7 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: +supports-color@^8.0.0, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -9111,11 +9770,38 @@ throat@^6.0.1: resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== +throttleit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" + integrity sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ== + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +tiny-case@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" + integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== + +tiny-warning@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +tmp@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -9138,7 +9824,12 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^4.0.0: +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + +tough-cookie@^4.0.0, tough-cookie@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== @@ -9191,27 +9882,22 @@ ts-node@^10.7.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsconfig-paths@^3.14.2: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.2" minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -9223,6 +9909,18 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -9257,6 +9955,11 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -9311,7 +10014,7 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^5.3.3: +typescript@^5.2.2: version "5.3.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== @@ -9386,6 +10089,11 @@ unquote@~1.1.1: resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" @@ -9414,10 +10122,10 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -use-debounce@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-10.0.0.tgz#5091b18d6c16292605f588bae3c0d2cfae756ff2" - integrity sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A== +use-debounce@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-9.0.4.tgz#51d25d856fbdfeb537553972ce3943b897f1ac85" + integrity sha512-6X8H/mikbrt0XE8e+JXRtZ8yYVvKkdYRfmIhWZYsP8rcNs9hk3APV8Ua2mFkKRLcJKVdnX2/Vwrmg2GWKUQEaQ== use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: version "1.2.0" @@ -9473,6 +10181,15 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -9509,6 +10226,11 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" +web-vitals@^2.1.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.4.tgz#76563175a475a5e835264d373704f9dde718290c" + integrity sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg== + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -9931,6 +10653,15 @@ workbox-window@6.6.1: "@types/trusted-types" "^2.0.2" workbox-core "6.6.1" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -10018,6 +10749,14 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" @@ -10028,7 +10767,17 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zustand@^4.4.7: +yup@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.3.tgz#d2f6020ad1679754c5f8178a29243d5447dead04" + integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw== + dependencies: + property-expr "^2.0.5" + tiny-case "^1.0.3" + toposort "^2.0.2" + type-fest "^2.19.0" + +zustand@^4.3.8: version "4.4.7" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.7.tgz#355406be6b11ab335f59a66d2cf9815e8f24038c" integrity sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw==