[
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  parser: '@typescript-eslint/parser',\n  extends: [\n    'plugin:react/recommended',\n    'plugin:@typescript-eslint/recommended',\n    'prettier/@typescript-eslint',\n    'plugin:react-hooks/recommended',\n    'plugin:prettier/recommended',\n  ],\n  plugins: ['@typescript-eslint', 'react', 'prettier', 'react-hooks'],\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n    ecmaFeatures: {\n      jsx: true,\n    },\n  },\n\n  rules: {\n    'react-hooks/rules-of-hooks': 'error',\n    'react-hooks/exhaustive-deps': 'warn',\n    'comma-dangle': ['error', 'only-multiline'],\n    'react/prop-types': 'off',\n    'react/display-name': 'off',\n    '@typescript-eslint/explicit-function-return-type': 'off',\n    'prettier/prettier': ['error', { endOfLine: 'auto' }],\n    '@typescript-eslint/interface-name-prefix': 'off',\n    '@typescript-eslint/ban-ts-ignore': 'off',\n    '@typescript-eslint/explicit-module-boundary-types': 'off',\n    '@typescript-eslint/no-empty-function': 'off',\n    '@typescript-eslint/no-explicit-any': 'off',\n    '@typescript-eslint/no-var-reqiures': 'off',\n  },\n\n  settings: {\n    react: {\n      version: 'detect',\n    },\n  },\n  globals: { React: 'writable' },\n};\n"
  },
  {
    "path": ".firebaserc",
    "content": "{\n  \"projects\": {\n    \"default\": \"rss-teams\"\n  }\n}\n"
  },
  {
    "path": ".github/workflows/deploy-client.yml",
    "content": "name: Build and Deploy\non:\n  push:\n    branches:\n      - master\n\njobs:\n  admin:\n    name: Deploy PROD\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Repo\n        uses: actions/checkout@master\n      - name: Install Dependencies\n        run: npm install\n      - name: Build\n        run: npm run build\n      - name: Archive Production Artifact\n        uses: actions/upload-artifact@master\n        with:\n          name: build\n          path: build\n      - name: Deploy to Firebase\n        uses: w9jds/firebase-action@master\n        with:\n          args: deploy --only hosting\n        env:\n          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n/.eslintcache*\n\n# testing\n/coverage\n\n# production\n/build\n/.firebase\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.eslintcache*\n"
  },
  {
    "path": ".prettierrc",
    "content": "\n{\n  \"endOfLine\": \"auto\",\n  \"semi\": true,\n  \"singleQuote\": true,\n  \"tabWidth\": 2,\n  \"trailingComma\": \"es5\",\n  \"printWidth\": 100\n}"
  },
  {
    "path": "README.md",
    "content": "# RSS-Teams-FE - Deprecated and no longer maintained. The latest deployed version will become unavailable from 28/10/2022 due to Heroku limitations.\nLink to deployment - https://rss-teams.web.app/login\n\nStack:  \n1 React - https://reactjs.org/  \n2 Redux, redux-thunk, redux-devtools-extension - https://redux.js.org/  \n3 Typescript - https://www.typescriptlang.org/  \n4 Apollo - https://www.howtographql.com/  \n\nUsed libs:  \n1 styled-components - https://askd.rocks/pres/styled-gdg/  \n2 react-router/react-router-dom - https://reactrouter.com/  \n3 react-hook-form  \n4 react-window  \n5 react-paginate  \n6 reactour  \n\nLinters: prettier, eslint.\n\nBranch RSSFE-01 contains login via github made frontend way.\n\nApp description:  \nThe application is intended for use by students of The Rolling Scopes School. The purpose of the application is to enable students to collect teams from friends, and single students - to be automatically assigned to teams.\n\nBackend repo: https://github.com/rolling-scopes-school/RSS-Teams-BE  \nMindMap: https://miro.com/welcomeonboard/2TsmiaGCbWQVZGhwyEW6EDfjdeQpOnKt6Hl62GvbVkT3ky3h02vqWHvI2gCz76cG\n\n# Getting Started with Create React App\n\nThis project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).\n\n## Available Scripts\n\nIn the project directory, you can run:\n\n### `yarn start`\n\nRuns the app in the development mode.\\\nOpen [http://localhost:3000](http://localhost:3000) to view it in the browser.\n\nThe page will reload if you make edits.\\\nYou will also see any lint errors in the console.\n\n### `yarn test`\n\nLaunches the test runner in the interactive watch mode.\\\nSee the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.\n\n### `yarn build`\n\nBuilds the app for production to the `build` folder.\\\nIt correctly bundles React in production mode and optimizes the build for the best performance.\n\nThe build is minified and the filenames include the hashes.\\\nYour app is ready to be deployed!\n\nSee the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.\n\n### `yarn eject`\n\n**Note: this is a one-way operation. Once you `eject`, you can’t go back!**\n\nIf you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.\n\nInstead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.\n\nYou don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.\n\n## Learn More\n\nYou can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).\n\nTo learn React, check out the [React documentation](https://reactjs.org/).\n"
  },
  {
    "path": "firebase.json",
    "content": "{\n  \"hosting\": {\n    \"public\": \"build\",\n    \"ignore\": [\n      \"firebase.json\",\n      \"**/.*\",\n      \"**/node_modules/**\"\n    ],\n    \"rewrites\": [\n      {\n        \"source\": \"**\",\n        \"destination\": \"/index.html\"\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"rss-teams-fe\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@apollo/client\": \"^3.3.7\",\n    \"@testing-library/jest-dom\": \"^5.11.4\",\n    \"@testing-library/react\": \"^11.1.0\",\n    \"@testing-library/user-event\": \"^12.1.10\",\n    \"@types/jest\": \"^26.0.15\",\n    \"@types/node\": \"^12.0.0\",\n    \"@types/react\": \"^16.9.53\",\n    \"@types/react-dom\": \"^16.9.8\",\n    \"@types/react-router-dom\": \"^5.1.7\",\n    \"@types/react-virtualized-auto-sizer\": \"^1.0.0\",\n    \"@types/react-window\": \"^1.8.2\",\n    \"@types/reactour\": \"^1.18.1\",\n    \"@types/redux-actions\": \"^2.6.1\",\n    \"@types/styled-components\": \"^5.1.7\",\n    \"graphql\": \"^15.5.0\",\n    \"i18next\": \"^19.9.1\",\n    \"react\": \"^17.0.1\",\n    \"react-dom\": \"^17.0.1\",\n    \"react-hook-form\": \"^6.15.1\",\n    \"react-i18next\": \"^11.8.8\",\n    \"react-paginate\": \"^7.0.0\",\n    \"react-redux\": \"^7.2.2\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"react-scripts\": \"4.0.3\",\n    \"react-virtualized-auto-sizer\": \"^1.0.4\",\n    \"react-window\": \"^1.8.6\",\n    \"reactour\": \"^1.18.3\",\n    \"redux\": \"^4.0.5\",\n    \"redux-actions\": \"^2.6.5\",\n    \"redux-thunk\": \"^2.3.0\",\n    \"styled-components\": \"^5.2.1\",\n    \"typescript\": \"4.2.4\",\n    \"web-vitals\": \"^0.2.4\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"npm run pre-build && react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\",\n    \"pre-build\": \"node pre-build\",\n    \"deploy\": \"firebase deploy\",\n    \"lint:eslint\": \"eslint \\\"{,!(node_modules)/**/}*.{ts,tsx}\\\"\",\n    \"fix:prettier\": \"prettier --write \\\"{,!(node_modules)/**/}*.{ts,tsx}\\\"\",\n    \"fix:eslint\": \"eslint --fix \\\"{,!(node_modules)/**/}*.{{ts,tsx}\\\"\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"react-app\",\n      \"react-app/jest\"\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@types/react-paginate\": \"^6.2.1\",\n    \"@types/react-redux\": \"^7.1.16\",\n    \"@types/redux\": \"^3.6.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.14.1\",\n    \"@typescript-eslint/parser\": \"^4.14.1\",\n    \"eslint\": \"^7.19.0\",\n    \"eslint-config-prettier\": \"^7.2.0\",\n    \"eslint-plugin-prettier\": \"^3.3.1\",\n    \"eslint-plugin-react\": \"^7.22.0\",\n    \"eslint-plugin-react-hooks\": \"^4.2.0\",\n    \"prettier\": \"^2.2.1\",\n    \"redux-devtools-extension\": \"^2.13.8\"\n  }\n}\n"
  },
  {
    "path": "pre-build.js",
    "content": "/* eslint-disable @typescript-eslint/no-var-requires */\nconst fs = require('fs');\nrequire('dotenv').config();\n\nconst BACKEND_LINK = `export const BACKEND_LINK = 'https://rss-teams.herokuapp.com/graphql';\n`;\n\nconst AUTH_BACKEND_LINK = `export const AUTH_BACKEND_LINK = 'https://rss-teams.herokuapp.com/auth/github/';\n`;\n\nfs.writeFileSync('./src/appConstants/api.ts', BACKEND_LINK + AUTH_BACKEND_LINK);\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.ico\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <meta name=\"theme-color\" content=\"#000000\" />\n    <meta\n      name=\"description\"\n      content=\"App for automatic distribution students of The Rolling Scopes School by teams\"\n    />\n    <link rel=\"apple-touch-icon\" href=\"%PUBLIC_URL%/favicon.png\" />\n    <!--\n      manifest.json provides metadata used when your web app is installed on a\n      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n    -->\n    <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\" />\n    <!--\n      Notice the use of %PUBLIC_URL% in the tags above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>RSS Teams</title>\n  </head>\n  <body>\n    <noscript>You need to enable JavaScript to run this app.</noscript>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start` or `yarn start`.\n      To create a production bundle, use `npm run build` or `yarn build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "public/manifest.json",
    "content": "{\n  \"short_name\": \"RSS Teams\",\n  \"name\": \"The Rolling Scopes School Teams\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    },\n    {\n      \"src\": \"favicon.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"192x192\"\n    },\n    {\n      \"src\": \"favicon.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"512x512\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "src/appConstants/api.ts",
    "content": "export const BACKEND_LINK = 'https://rss-teams-dev.herokuapp.com/graphql';\nexport const AUTH_BACKEND_LINK = 'https://rss-teams-dev.herokuapp.com/auth/github/';\n"
  },
  {
    "path": "src/appConstants/colors.ts",
    "content": "export const WHITE_COLOR = '#FFFFFF';\nexport const BG_COLOR = '#F2F8FD';\nexport const MAIN1_COLOR = '#6550F6'; // violet\nexport const MAIN1_DARK_COLOR = '#5039EF'; // dark violet\nexport const MAIN2_COLOR = '#FA6678'; // red\nexport const MAIN2_LIGHT_COLOR = '#FE7888'; // light red\nexport const LIGHT_TEXT_COLOR = '#7E96C2';\nexport const DARK_TEXT_COLOR = '#363D48';\nexport const OVERLAY_COLOR = '#363D4866';\nexport const DASHBOARD_HEADER_BG_COLOR = '#E1EEFA';\nexport const TABLE_SCROLLBAR_BG_COLOR = '#F9F9FD';\nexport const TABLE_SCROLLBAR_THUMB_COLOR = '#1E33570D';\nexport const TABLE_POPUP_BORDER_COLOR = '#363D4833';\nexport const FOOTER_NAMES_COLOR = '#9CA5B5';\n\nexport const ALERT_COLOR = '#FA6678'; // red\n"
  },
  {
    "path": "src/appConstants/index.ts",
    "content": "export { BACKEND_LINK, AUTH_BACKEND_LINK } from './api';\n\nexport const SET_USER_DATA = 'SET_USER_DATA';\nexport const AUTH_TOKEN = 'AUTH_TOKEN';\nexport const SET_TOKEN = 'SET_TOKEN';\nexport const SET_CURR_COURSE = 'SET_CURR_COURSE';\nexport const SET_COMMON_ERROR = 'SET_COMMON_ERROR';\nexport const SET_BURGER_MENU_OPEN = 'SET_BURGER_MENU_OPEN';\nexport const ACTIVE_MODAL_EXPEL = 'ACTIVE_MODAL_EXPEL';\nexport const ACTIVE_MODAL_LEAVE = 'ACTIVE_MODAL_LEAVE';\nexport const ACTIVE_MODAL_JOIN = 'ACTIVE_MODAL_JOIN';\nexport const ACTIVE_MODAL_CREATE_TEAM = 'ACTIVE_MODAL_CREATE_TEAM';\nexport const ACTIVE_MODAL_CREATED = 'ACTIVE_MODAL_CREATED';\nexport const ACTIVE_MODAL_UPDATE_SOCIAL_LINK = 'ACTIVE_MODAL_UPDATE_SOCIAL_LINK';\nexport const ACTIVE_MODAL_REMOVE_COURSE = 'ACTIVE_MODAL_REMOVE_COURSE';\nexport const ACTIVE_MODAL_SORT_STUDENTS = 'ACTIVE_MODAL_SORT_STUDENTS';\nexport const ACTIVE_MODAL_LEAVE_PAGE = 'ACTIVE_MODAL_LEAVE_PAGE';\nexport const ACTIVE_MODAL_CREATED_COURSE = 'ACTIVE_MODAL_CREATED_COURSE';\nexport const ACTIVE_MODAL_EDIT_COURSE = 'ACTIVE_MODAL_EDIT_COURSE';\nexport const SET_TEAM_MEMBER_EXPEL_ID = 'SET_TEAM_MEMBER_EXPEL_ID';\nexport const SET_TEAM_PASSWORD = 'SET_TEAM_PASSWORD';\nexport const SET_SOCIAL_LINK = 'SET_SOCIAL_LINK';\nexport const SET_FILTER_DATA = 'SET_FILTER_DATA';\nexport const SET_CURR_LANG = 'SET_CURR_LANG';\nexport const SET_EDIT_PROFILE_DATA_CHANGE = 'SET_EDIT_PROFILE_DATA_CHANGE';\nexport const SET_PATH_TO_THE_PAGE = 'SET_PATH_TO_THE_PAGE';\nexport const SET_IS_TOUR_OPEN = 'SET_IS_TOUR_OPEN';\n\nexport const USERS_PER_PAGE = 20;\nexport const TEAMS_PER_PAGE = 10;\nexport const CURRENT_YEAR = new Date(Date.now()).getFullYear();\n\nexport const CURRENT_COURSE = 'currentCourse';\nexport const CURRENT_LANG = 'currentLanguage';\nexport const TOUR_OPENING = 'tourOpening';\n\nexport const TABLE_HEADERS = [\n  '№',\n  'First / Last Name',\n  'Score',\n  'Team Number',\n  'Telegram',\n  'Discord',\n  'Github',\n  'Location',\n  'Courses',\n];\n\nexport const TABLE_TEAMS_HEADERS = [\n  '№',\n  'First / Last Name',\n  'Score',\n  'Telegram',\n  'Discord',\n  'Github',\n  'Location',\n  'Action',\n];\n\nexport const INPUT_VALUES_EDIT_PROFILE: string[] = [\n  'firstName',\n  'lastName',\n  'discord',\n  'telegram',\n  'city',\n  'country',\n  'score',\n];\n\nexport const MODAL_INPUT_VALIDATION = {\n  pattern: {\n    value:\n      /^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?[a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,5}(:[0-9]{1,5})?(\\/.*)?|^((http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/,\n    message: 'Use the format',\n  },\n  maxLength: {\n    value: 55,\n    message: 'This input exceed maxLength.',\n  },\n};\n\nexport const COURSE_NAME_VALIDATION = {\n  pattern: {\n    value: `${CURRENT_YEAR}`,\n    message: 'Please, enter correct course name',\n  },\n  minLength: {\n    value: 5,\n    message: 'Minimal length is 5.',\n  },\n  maxLength: {\n    value: 55,\n    message: 'This input exceed maxLength.',\n  },\n  uniq: {\n    message: 'Please, enter unique course name',\n  },\n};\n\nexport const TEAM_SIZE_VALIDATION = {\n  pattern: {\n    value: /^[2-9]$/i,\n    message: 'Please, enter correct team size',\n  },\n  minLength: {\n    value: 1,\n    message: 'Minimal length is 1.',\n  },\n  maxLength: {\n    value: 1,\n    message: 'This input exceed maxLength.',\n  },\n};\n\nexport const APP_NAVIGATION_LINKS = {\n  ['/students']: {\n    name: 'Dashboard',\n    isAlwaysVisible: false,\n  },\n  ['/']: {\n    name: 'Teams',\n    isAlwaysVisible: false,\n  },\n  ['/edit-profile']: {\n    name: 'Edit Profile',\n    isAlwaysVisible: true,\n  },\n  ['/tutorial']: {\n    name: 'Tutorial',\n    isAlwaysVisible: true,\n  },\n  ['/admin']: {\n    name: 'Admin',\n    isAlwaysVisible: true,\n  },\n};\n\nexport const DEFAULT_LANGUAGE = 'en';\nexport const LANGUAGES: string[] = [DEFAULT_LANGUAGE, 'ru'];\n\nexport const Language: { [key: string]: string } = {\n  en: 'EN',\n  ru: 'RU',\n};\n\nexport const FOOTER_INFO = [\n  {\n    title: 'Development',\n    members: ['besovadevka', 'MadaShindeInai', 'self067', 'manuminsk', 'Malagor', 'dariavv'],\n  },\n  {\n    title: 'Design',\n    members: ['Nastya Kapylova'],\n  },\n];\n\nexport const LINK_TO_DESIGN_BLOCK = 'https://www.linkedin.com/in/nastya-kapylova-54126215a';\n\nexport const LINK_TO_REPO = 'https://github.com/rolling-scopes-school/RSS-Teams-FE';\n\nexport const addCourseInputsInfo = [\n  { label: 'Course name', placeholder: 'Enter course name' },\n  { label: 'Team size', placeholder: 'Enter team size' },\n];\n\nexport const SHOW_COURSES_OPTIONS = [\n  { id: '1', name: 'All' },\n  { id: '2', name: 'Active' },\n  { id: '3', name: 'Terminated' },\n];\n\nexport const UNAUTHORIZED_ERROR_MESSAGE = 'Unauthorized';\n"
  },
  {
    "path": "src/components/App/index.tsx",
    "content": "import React, { FC, useEffect, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Route, Switch } from 'react-router-dom';\nimport {\n  TeamsList,\n  LoginPage,\n  StudentsTable,\n  TokenPage,\n  NotFoundPage,\n  EditProfile,\n  TutorialPage,\n  AdminPage,\n} from 'modules';\nimport { Loader, PrivateRoute, Header, Footer, ErrorModal, TourGuide } from 'components';\nimport { selectToken } from 'modules/LoginPage/selectors';\nimport { AUTH_TOKEN, CURRENT_COURSE, CURRENT_LANG, DEFAULT_LANGUAGE } from 'appConstants';\nimport { useWhoAmIQuery } from 'hooks/graphql';\nimport { AppStyled } from './styled';\nimport { setToken } from 'modules/LoginPage/loginPageReducer';\nimport { setUserData } from 'modules/StudentsTable/studentsTableReducer';\nimport { setCourse, setLanguage } from 'modules/LoginPage/loginPageMiddleware';\n\nexport const App: FC = () => {\n  const dispatch = useDispatch();\n  const loginToken = useSelector(selectToken);\n  const [loading, setLoading] = useState(true);\n  const { loadingW, whoAmI, errorW } = useWhoAmIQuery({\n    skip: loginToken === null,\n  });\n  const newUserCheck = !!whoAmI?.courses.length;\n  const isUserAdmin = !!whoAmI?.isAdmin;\n\n  useEffect(() => {\n    if (!loginToken) {\n      const token = sessionStorage.getItem(AUTH_TOKEN);\n      if (token) dispatch(setToken(token));\n    }\n\n    if (!!whoAmI) {\n      dispatch(setUserData(whoAmI));\n    }\n    if (whoAmI?.courses[0]) {\n      dispatch(setLanguage(localStorage.getItem(CURRENT_LANG) ?? DEFAULT_LANGUAGE));\n      dispatch(\n        setCourse(JSON.parse(localStorage.getItem(CURRENT_COURSE) as string) ?? whoAmI?.courses[0])\n      );\n    }\n\n    if (!loadingW) setLoading(false);\n  }, [dispatch, loginToken, loadingW, loading, whoAmI]);\n\n  if (errorW) return <ErrorModal error={errorW} />;\n  if (loading || loadingW) return <Loader />;\n\n  return (\n    <AppStyled>\n      <Header />\n\n      <Switch>\n        <PrivateRoute\n          path=\"/\"\n          exact\n          isLoggedIn={!!loginToken}\n          newUserCheck={newUserCheck}\n          component={TeamsList}\n        />\n        <PrivateRoute\n          exact\n          path=\"/students\"\n          isLoggedIn={!!loginToken}\n          newUserCheck={newUserCheck}\n          component={StudentsTable}\n        />\n        <PrivateRoute\n          exact\n          path=\"/admin\"\n          isLoggedIn={!!loginToken && isUserAdmin}\n          newUserCheck={isUserAdmin}\n          component={AdminPage}\n        />\n        <Route exact path=\"/token/:id\" component={TokenPage} />\n        <Route exact path=\"/login\" component={LoginPage} />\n        <Route exact path=\"/edit-profile\" component={EditProfile} />\n        <Route exact path=\"/tutorial\" component={TutorialPage} />\n        <Route path=\"*\" component={NotFoundPage} />\n      </Switch>\n\n      <TourGuide />\n\n      {!!loginToken && <Footer />}\n    </AppStyled>\n  );\n};\n"
  },
  {
    "path": "src/components/App/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const AppStyled = styled.div`\n  position: relative;\n  height: 100vh;\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n`;\n"
  },
  {
    "path": "src/components/CommonSelectList/index.tsx",
    "content": "import React, { FC, useEffect, useRef } from 'react';\nimport { Course } from 'types';\nimport {\n  StyledCoursesSelectWrapper,\n  StyledCoursesSelectHeaderWrapper,\n  StyledCoursesList,\n  StyledCoursesSelectInfo,\n  StyledCoursesSelectArrow,\n} from './styled';\nimport { useTranslation } from 'react-i18next';\nimport { Language } from 'appConstants';\n\ntype CommonSelectProps = {\n  displayList: boolean;\n  setDisplayList: (display: boolean) => void;\n  listItems: any;\n  onClickHandler: any;\n  title?: string;\n  currItem: string;\n  isLang?: boolean;\n  menuToggle?: boolean;\n  customStyle?: boolean;\n  showOptionsSelect?: boolean;\n};\n\nexport const CommonSelectList: FC<CommonSelectProps> = ({\n  displayList,\n  setDisplayList,\n  listItems,\n  onClickHandler,\n  title,\n  currItem,\n  isLang,\n  menuToggle,\n  customStyle,\n  showOptionsSelect,\n}) => {\n  const selectRef = useRef(null);\n  const { t } = useTranslation();\n\n  useEffect(() => {\n    const closeEventHandler = (ev: MouseEvent) => {\n      if ((selectRef.current as unknown as HTMLDivElement)?.contains(ev.target as HTMLDivElement)) {\n        setDisplayList(!displayList);\n        return;\n      }\n      setDisplayList(false);\n    };\n\n    document && document.addEventListener('click', closeEventHandler);\n\n    return (): void => {\n      document && document.removeEventListener('click', closeEventHandler);\n    };\n  }, [displayList, setDisplayList]);\n\n  const isListItemsExists = !!listItems.length;\n\n  return (\n    <StyledCoursesSelectWrapper\n      isClicked={displayList}\n      {...{ isLang, menuToggle, customStyle, showOptionsSelect }}\n      className={`CommonSelectList${!isLang && ' eighthStep'}`}\n    >\n      <StyledCoursesSelectHeaderWrapper\n        isClicked={displayList}\n        {...{ isLang, menuToggle, customStyle }}\n      >\n        {title && <p>{t(title)}</p>}\n        <StyledCoursesSelectInfo\n          hover={isListItemsExists}\n          ref={selectRef}\n          {...{ isLang, menuToggle, customStyle }}\n        >\n          <p>{t(currItem)}</p>\n          {isListItemsExists && <StyledCoursesSelectArrow />}\n        </StyledCoursesSelectInfo>\n      </StyledCoursesSelectHeaderWrapper>{' '}\n      {isListItemsExists && (\n        <StyledCoursesList {...{ isLang, menuToggle, customStyle }}>\n          {listItems.map((item: Course | string) => {\n            return (\n              <li\n                key={typeof item === 'string' ? item : item.id}\n                onClick={() => onClickHandler(item)}\n              >\n                {typeof item === 'string' ? Language[item] : t(item.name)}\n              </li>\n            );\n          })}\n        </StyledCoursesList>\n      )}\n    </StyledCoursesSelectWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/CommonSelectList/styled.ts",
    "content": "import {\n  MAIN1_DARK_COLOR,\n  WHITE_COLOR,\n  MAIN1_COLOR,\n  DARK_TEXT_COLOR,\n  BG_COLOR,\n  LIGHT_TEXT_COLOR,\n} from 'appConstants/colors';\nimport styled from 'styled-components';\nimport { ReactComponent as CoursesSelectArrow } from 'assets/svg/coursesSelectArrow.svg';\nimport { HeaderAdaptiveFont, SVGArrowAdaptive } from 'typography';\n\ntype TStyledCoursesSelectInfo = {\n  hover: boolean;\n} & TFooterProp;\n\ntype TStyledCoursesSelectList = {\n  isClicked: boolean;\n  showOptionsSelect?: boolean;\n} & TFooterProp;\n\ntype TFooterProp = {\n  isLang?: boolean;\n  menuToggle?: boolean;\n  customStyle?: boolean;\n};\n\nexport const StyledCoursesSelectWrapper = styled.div<TStyledCoursesSelectList>`\n  position: ${({ showOptionsSelect }) => showOptionsSelect && 'absolute'};\n  left: ${({ showOptionsSelect }) => showOptionsSelect && '5%'};\n  z-index: 1;\n  display: ${({ menuToggle }) => (menuToggle ? 'none' : 'flex')};\n  flex-direction: column;\n  width: ${({ isLang }) => (isLang ? '82px' : '300px')};\n  height: fit-content;\n  min-height: 40px;\n  margin: ${({ isLang }) => !isLang && '0 20px 0 0'};\n  overflow: hidden;\n  font: 400 1rem/24px 'Poppins', sans-serif;\n  color: ${({ customStyle }) => (customStyle ? DARK_TEXT_COLOR : WHITE_COLOR)};\n  background-color: ${({ customStyle }) => (customStyle ? BG_COLOR : MAIN1_DARK_COLOR)};\n  border-radius: 10px;\n  ${HeaderAdaptiveFont}\n\n  ul {\n    margin-top: ${({ isClicked }) => (isClicked ? '-5px' : '-150%')};\n  }\n\n  @media (max-width: 1100px) {\n    left: ${({ showOptionsSelect }) => showOptionsSelect && '9%'};\n    top: ${({ showOptionsSelect }) => showOptionsSelect && '50%'};\n  }\n  @media (max-width: 768px) {\n    left: ${({ showOptionsSelect }) => showOptionsSelect && '10%'};\n  }\n  @media (max-width: 700px) {\n    width: ${({ isLang }) => !isLang && '260px'};\n  }\n  @media (max-width: 600px) {\n    display: ${({ isLang }) => isLang && 'none'};\n    display: ${({ menuToggle }) => menuToggle && 'flex'};\n    margin: ${({ isLang }) => !isLang && '0 20px 0 0'};\n  }\n  @media (max-width: 440px) {\n    width: ${({ isLang }) => !isLang && '200px'};\n  }\n  @media (max-width: 375px) {\n    width: ${({ isLang }) => !isLang && '180px'};\n  }\n`;\n\nexport const StyledCoursesSelectHeaderWrapper = styled.div<TStyledCoursesSelectList>`\n  z-index: 2;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  height: 40px;\n  padding: 8px 15px;\n  background-color: ${({ customStyle }) => (customStyle ? BG_COLOR : MAIN1_DARK_COLOR)};\n  border-radius: 10px;\n  ${HeaderAdaptiveFont};\n\n  p {\n    margin: 0;\n    font-weight: 400;\n  }\n\n  & > p {\n    @media (max-width: 440px) {\n      display: none;\n    }\n  }\n\n  svg {\n    transform: ${({ isClicked }) => (isClicked ? 'rotate(180deg)' : 'rotate(0deg)')};\n    path {\n      stroke: ${({ customStyle }) => customStyle && LIGHT_TEXT_COLOR};\n    }\n  }\n`;\n\nexport const StyledCoursesList = styled.ul<TFooterProp>`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  margin: 0;\n  margin-top: 0;\n  padding: 8px 10px;\n  transition: all 0.7s ease-in-out;\n  gap: 5px;\n  ${HeaderAdaptiveFont}\n\n  li {\n    padding: 5px;\n    list-style: none;\n    background-color: ${({ customStyle }) => (customStyle ? WHITE_COLOR : MAIN1_COLOR)};\n    border-radius: 10px;\n    cursor: pointer;\n\n    &:hover {\n      background-color: transparent;\n    }\n  }\n`;\n\nexport const StyledCoursesSelectInfo = styled.div<TStyledCoursesSelectInfo>`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  width: ${({ isLang }) => isLang && '100%'};\n\n  &:hover {\n    cursor: ${({ hover }) => (hover ? 'pointer' : 'unset')};\n  }\n\n  p {\n    overflow: hidden;\n    max-width: 155px;\n    margin-left: 5px;\n    margin-right: ${({ hover }) => (hover ? '10px' : '31px')};\n    font-weight: 500;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    @media (max-width: 440px) {\n      margin-left: 0;\n      margin-right: ${({ hover }) => (hover ? '10px' : '0')};\n    }\n  }\n\n  svg {\n    ${SVGArrowAdaptive};\n  }\n\n  @media (max-width: 440px) {\n    width: ${({ isLang }) => !isLang && '100%'};\n  }\n`;\n\nexport const StyledCoursesSelectArrow = styled(CoursesSelectArrow)`\n  transition: transform 0.3s ease-in-out;\n`;\n"
  },
  {
    "path": "src/components/CourseField/index.tsx",
    "content": "import React, { FC, SelectHTMLAttributes } from 'react';\nimport { Label, Select, SelectInner } from 'typography';\nimport { FieldWrapper, SelectCourse } from './styled';\nimport { ValidationAlert } from '../InputField/styled';\nimport { useTranslation } from 'react-i18next';\n\ntype Course = {\n  id: string;\n  name: string;\n};\n\ninterface SelectFieldProps extends SelectHTMLAttributes<HTMLSelectElement> {\n  labelText?: string;\n  placeholder: string;\n  multi?: boolean;\n  register: any;\n  courses: Course[];\n  onAdd?: any;\n  isValid?: boolean;\n}\n\nexport const CourseField: FC<SelectFieldProps> = ({\n  labelText,\n  placeholder,\n  register,\n  courses,\n  onAdd,\n  isValid,\n  ...rest\n}) => {\n  const { t } = useTranslation();\n  const courseOptions = courses\n    ? courses.map((course: Course) => {\n        return (\n          <option key={course.id} value={course.id}>\n            {course.name}\n          </option>\n        );\n      })\n    : null;\n  return (\n    <FieldWrapper>\n      {labelText && <Label>{labelText}</Label>}\n      <SelectCourse>\n        <Select>\n          <SelectInner\n            placeholder={t(placeholder)}\n            ref={register}\n            value={0}\n            onChange={(e: any) => {\n              onAdd(courses.find((course: Course) => course.id === e.target.value));\n            }}\n            {...rest}\n          >\n            <option disabled hidden value=\"0\">\n              {t('Select course')}\n            </option>\n            {courseOptions}\n          </SelectInner>\n        </Select>\n      </SelectCourse>\n      {!isValid && <ValidationAlert>{t('You need to choose at least one course')}</ValidationAlert>}\n    </FieldWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/CourseField/styled.ts",
    "content": "import styled from 'styled-components';\nimport { BG_COLOR, LIGHT_TEXT_COLOR, MAIN1_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { SVGParamsAdaptive } from 'typography';\n\ntype TPlusButton = {\n  active?: boolean;\n};\n\nexport const FieldWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  margin-bottom: 20px;\n`;\n\nexport const SelectCourse = styled.div`\n  width: 300px;\n  margin-bottom: 0;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  @media (max-width: 440px) {\n    width: 100%;\n  }\n`;\n\nexport const CourseButton = styled.button`\n  width: 40px;\n  height: 40px;\n  margin-left: 10px;\n  padding: 10px;\n  outline: none;\n  border-radius: 10px;\n  border: none;\n  cursor: pointer;\n\n  svg {\n    ${SVGParamsAdaptive};\n  }\n`;\n\nexport const PlusButton = styled(CourseButton)<TPlusButton>`\n  background-color: ${({ active }) => (active ? MAIN1_COLOR : BG_COLOR)};\n\n  path {\n    stroke: ${({ active }) => (active ? WHITE_COLOR : LIGHT_TEXT_COLOR)};\n  }\n`;\n\nexport const CrossButton = styled(CourseButton)`\n  background: ${BG_COLOR}\n    url(\"data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M3.05029 3.05054L12.9499 12.9501' stroke='%237E96C2' stroke-width='2' stroke-linecap='round'/%3E%3Cpath d='M12.9497 3.05029L3.0501 12.9499' stroke='%237E96C2' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E%0A\")\n    no-repeat center center;\n`;\n\nexport const PlaceholderOption = styled.option`\n  display: none;\n`;\n"
  },
  {
    "path": "src/components/ErrorBoundary/index.tsx",
    "content": "import React, { Component } from 'react';\nimport { BoundryContainer } from './styled';\n\ninterface ErrorBoundaryState {\n  error: any;\n  errorInfo: any;\n}\n\nclass ErrorBoundary extends Component<any, ErrorBoundaryState> {\n  state = { error: null, errorInfo: null };\n\n  static getDerivedStateFromError(error: any, errorInfo: any) {\n    return { error: error, errorInfo: errorInfo };\n  }\n\n  componentDidCatch(error: any, errorInfo: any) {\n    // Catch errors in any components below and re-render with error message\n    this.setState({\n      error: error,\n      errorInfo: errorInfo,\n    });\n    // You can also log error messages to an error reporting service here\n  }\n\n  handleReload() {\n    location.reload();\n  }\n\n  render() {\n    const { children } = this.props;\n\n    if (this.state.errorInfo) {\n      return (\n        <BoundryContainer onClick={this.handleReload}>\n          Something went wrong.\n          <br /> Click on the page to reload it.\n        </BoundryContainer>\n      );\n    }\n\n    return <>{children}</>;\n  }\n}\n\nexport default ErrorBoundary;\n"
  },
  {
    "path": "src/components/ErrorBoundary/styled.ts",
    "content": "import styled from 'styled-components';\nimport { PageTitle } from 'typography';\n\nexport const BoundryContainer = styled(PageTitle)`\n  width: 100vw;\n  height: 100vh;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  font-size: 30px;\n  text-align: center;\n`;\n"
  },
  {
    "path": "src/components/ErrorModal/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { Modal } from 'components';\nimport { ApolloError } from '@apollo/client';\nimport { UNAUTHORIZED_ERROR_MESSAGE } from 'appConstants';\n\ntype Props = {\n  title?: string;\n  text?: string;\n  text2?: string;\n  open?: boolean;\n  cancelText?: string;\n  isCrossIconVisible?: boolean;\n  error?: ApolloError;\n};\n\nexport const ErrorModal: FC<Props> = ({\n  title = 'Something went wrong!',\n  text = 'Please, try again later.',\n  text2 = '@besovadevka or @MadaShindeInai',\n  open = true,\n  isCrossIconVisible = false,\n  cancelText = 'Ok',\n  error,\n}) => {\n  const isUserUnauthorized = !!error?.graphQLErrors.find(\n    ({ message }) => message === UNAUTHORIZED_ERROR_MESSAGE\n  );\n\n  if (isUserUnauthorized) {\n    return null;\n  }\n\n  const onClose = () => {\n    location.reload();\n  };\n\n  return (\n    <Modal\n      {...{ title, text, text2, open, onClose, isCrossIconVisible, cancelText }}\n      hideOnOutsideClick\n      hideOnEsc\n    ></Modal>\n  );\n};\n"
  },
  {
    "path": "src/components/FilterForm/filterFormFields.ts",
    "content": "import { TFilterForm } from 'types';\nimport { InputFieldProps } from '../../components/InputField';\n\nexport const filterFormFields: InputFieldProps[] = [\n  {\n    name: 'discord',\n    labelText: 'Discord',\n    placeholder: 'Enter discord name',\n    register: {\n      pattern: {\n        value: /^[A-Za-z0-9@#-_() ]+$/i,\n        message: 'This input is letters and digits only.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'github',\n    labelText: 'GitHub',\n    placeholder: 'Enter github name',\n    register: {\n      pattern: {\n        value: /^[A-Za-z0-9-_ ]+$/i,\n        message: 'This input is letters and digits only.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'location',\n    labelText: 'Location',\n    placeholder: 'Enter location',\n    register: {\n      pattern: {\n        value: /^[A-Za-z\\- ]+$/i,\n        message: 'This input is letters only.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'courseName',\n    labelText: 'Course',\n    placeholder: 'Enter course name',\n    register: {\n      pattern: {\n        value: /^[A-Za-z\\- ]+$/i,\n        message: 'This input is letters only.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n];\n\nexport const filterSelectFields: [string, [string, string | boolean][], string, string][] = [\n  [\n    'Sort by score',\n    [\n      ['Max score', 'DESC'],\n      ['Min score', 'ASC'],\n    ],\n    '100%',\n    'sortingOrder',\n  ],\n  [\n    'Sort by team',\n    [\n      ['All', false],\n      ['Without team', true],\n    ],\n    '100%',\n    'teamFilter',\n  ],\n];\n\nexport const defaultFilterData: TFilterForm = {\n  discord: null,\n  github: null,\n  location: null,\n  courseName: null,\n  sortingOrder: filterSelectFields[0][1][0][0],\n  teamFilter: filterSelectFields[1][1][0][0],\n};\n"
  },
  {
    "path": "src/components/FilterForm/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { FieldError, FieldErrors } from 'react-hook-form';\nimport { FilterSelect, InputField } from 'components';\nimport { InputsWrapper } from 'modules/EditProfile/styled';\nimport { TFilterForm } from 'types';\nimport { FilterFormBase, FilterButtonsWrapper, FilterButton } from './styled';\nimport { filterFormFields, filterSelectFields, defaultFilterData } from './filterFormFields';\nimport { DARK_TEXT_COLOR } from 'appConstants/colors';\nimport { Button } from 'typography';\nimport crossIcon from 'assets/svg/cross.svg';\nimport { selectFilterData } from 'modules/StudentsTable/selectors';\nimport { useTranslation } from 'react-i18next';\nimport { setFilterData } from 'modules/StudentsTable/studentsTableReducer';\n\ntype TFilter = {\n  inputValues: TFilterForm;\n  setInputValues: (data: TFilterForm) => void;\n  setIsFilterOpen: (data: boolean) => void;\n  setPage: (page: number) => void;\n  register: any;\n  handleSubmit: any;\n  errors: FieldErrors;\n  reset: any;\n};\n\nexport const FilterForm: FC<TFilter> = ({\n  inputValues,\n  setInputValues,\n  setIsFilterOpen,\n  setPage,\n  register,\n  handleSubmit,\n  errors,\n  reset,\n}) => {\n  const filterData = useSelector(selectFilterData);\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n\n  const changeInputValue = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>): void => {\n    const { name, value } = e.target;\n    setInputValues({\n      ...inputValues,\n      [name]: value.trim(),\n    });\n  };\n\n  const onFilterFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n    e.preventDefault();\n  };\n\n  const isValuesInnerEqual =\n    Object.values(defaultFilterData).toString() !== Object.values(inputValues).toString();\n  const isValuesOuterEqual =\n    Object.values(filterData).toString() !== Object.values(inputValues).toString();\n\n  return (\n    <FilterFormBase onSubmit={handleSubmit(onFilterFormSubmit)}>\n      <InputsWrapper>\n        {filterSelectFields.map((item: [string, [string, string | boolean][], string, string]) => {\n          return (\n            <FilterSelect\n              key={JSON.stringify(item)}\n              name={item[3]}\n              labelText={t(item[0])}\n              placeholder={t(item[0])}\n              register={register}\n              options={item[1].map((it) => it[0])}\n              onChange={changeInputValue}\n              currentOption={inputValues[item[3] as keyof TFilterForm] as string}\n              color={DARK_TEXT_COLOR}\n            />\n          );\n        })}\n        {filterFormFields.map((item) => {\n          return (\n            <InputField\n              key={JSON.stringify(item)}\n              name={item.name}\n              value={filterData[item.name as keyof TFilterForm] ?? ''}\n              labelText={item.labelText}\n              placeholder={item.placeholder}\n              aria-invalid={\n                (errors[item.name as keyof TFilterForm] as FieldError) ? 'true' : 'false'\n              }\n              message={(errors[item.name as keyof TFilterForm] as FieldError)?.message}\n              onChange={changeInputValue}\n              register={register(item.register)}\n            />\n          );\n        })}\n      </InputsWrapper>\n      <FilterButtonsWrapper>\n        {isValuesInnerEqual && (\n          <FilterButton\n            clearBtn\n            type=\"button\"\n            onClick={() => {\n              reset(defaultFilterData);\n              setInputValues(defaultFilterData);\n            }}\n          >\n            {<img src={crossIcon} alt=\"clear filter icon\" />}\n            {t('Clear filter')}\n          </FilterButton>\n        )}\n        <Button\n          className=\"SecondButtonForm\"\n          type=\"button\"\n          onClick={() => {\n            if (isValuesOuterEqual) {\n              dispatch(setFilterData(inputValues));\n              setPage(0);\n            }\n            setIsFilterOpen(false);\n          }}\n        >\n          {t('Apply')}\n        </Button>\n      </FilterButtonsWrapper>\n    </FilterFormBase>\n  );\n};\n"
  },
  {
    "path": "src/components/FilterForm/styled.ts",
    "content": "import styled from 'styled-components';\nimport { MAIN1_COLOR } from 'appConstants/colors';\nimport { EditProfileWrapper } from 'modules/EditProfile/styled';\nimport { Button } from 'typography';\n\ntype TFilerButtonProps = {\n  bgColor?: string | undefined;\n  clearBtn?: boolean;\n  outerBtn?: boolean;\n};\n\nexport const FilterFormBase = styled(EditProfileWrapper)`\n  z-index: 2;\n  position: absolute;\n  top: 25px;\n  right: 0;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  height: 412px;\n  @media screen and (max-width: 768px) {\n    height: auto;\n  }\n  @media (max-width: 440px) {\n    top: 5px;\n    right: -13px;\n    width: 320px;\n  }\n`;\n\nexport const FilterButton = styled(Button)<TFilerButtonProps>`\n  background-color: ${({ bgColor }) => bgColor ?? 'transparent'};\n  color: ${MAIN1_COLOR};\n  display: flex;\n  align-items: center;\n  gap: ${({ clearBtn = false }) => (clearBtn ? '11px' : '20px')};\n  margin-left: ${({ outerBtn = false }) => (outerBtn ? 'auto' : '0')};\n  padding: ${({ clearBtn = false }) => (clearBtn ? '13px 20px 13px 0' : '20px 30px')};\n\n  @media (max-width: 1200px) {\n    padding: ${({ clearBtn = false }) => (clearBtn ? '12px 16px 12px 0' : '18px 28px')};\n    gap: ${({ clearBtn = false }) => (clearBtn ? '10px' : '18px')};\n  }\n  @media (max-width: 992px) {\n    padding: ${({ clearBtn = false }) => (clearBtn ? '13px 12px 13px 0' : '14px 26px')};\n    gap: ${({ clearBtn = false }) => (clearBtn ? '10px' : '17px')};\n  }\n  @media (max-width: 768px) {\n    padding: ${({ clearBtn = false }) => (clearBtn ? '13px 8px 13px 0' : '8px 26px')};\n    gap: ${({ clearBtn = false }) => (clearBtn ? '10px' : '16px')};\n  }\n  @media (max-width: 550px) {\n    padding: ${({ clearBtn = false }) => (clearBtn ? '11px 5px 11px 0' : '5px 25px')};\n    gap: ${({ clearBtn = false }) => (clearBtn ? '8px' : '13px')};\n  }\n  @media (max-width: 440px) {\n    padding: ${({ clearBtn = false }) => (clearBtn ? '9px 5px 9px 0' : '5px 20px')};\n    gap: ${({ clearBtn = false }) => (clearBtn ? '6px' : '10px')};\n  }\n\n  img {\n    filter: invert(100%) sepia() saturate(10000%) hue-rotate(-110deg);\n\n    @media (max-width: 992px) {\n      width: 15px;\n    }\n    @media (max-width: 768px) {\n      width: 14px;\n    }\n    @media (max-width: 550px) {\n      width: 12px;\n    }\n    @media (max-width: 440px) {\n      width: 10px;\n    }\n  }\n`;\n\nexport const FilterButtonsWrapper = styled.div`\n  width: 100%;\n  display: flex;\n  align-items: center;\n\n  .SecondButtonForm {\n    margin-left: auto;\n  }\n`;\n"
  },
  {
    "path": "src/components/FilterSelect/index.tsx",
    "content": "import React, { FC, SelectHTMLAttributes } from 'react';\nimport { Label, Select, SelectInner } from 'typography';\nimport { FieldWrapper, SelectCourse } from 'components/CourseField/styled';\nimport { useTranslation } from 'react-i18next';\ninterface SelectFieldProps extends SelectHTMLAttributes<HTMLSelectElement> {\n  labelText?: string;\n  placeholder: string;\n  register: any;\n  options: string[];\n  currentOption: string;\n}\n\nexport const FilterSelect: FC<SelectFieldProps> = ({\n  labelText,\n  placeholder,\n  register,\n  options,\n  currentOption,\n  ...rest\n}) => {\n  const { t } = useTranslation();\n  const filterFieldOptions =\n    options.map((option: string) => {\n      return (\n        <option key={option} value={option}>\n          {t(option)}\n        </option>\n      );\n    }) ?? null;\n  return (\n    <FieldWrapper>\n      {labelText && <Label>{labelText}</Label>}\n      <SelectCourse>\n        <Select>\n          <SelectInner placeholder={t(placeholder)} ref={register} value={currentOption} {...rest}>\n            {filterFieldOptions}\n          </SelectInner>\n        </Select>\n      </SelectCourse>\n    </FieldWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/Footer/components/FooterContent/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { FooterContentBlock, FooterContentWrapper, FooterTitle } from 'components/Footer/styled';\nimport { FOOTER_INFO, LINK_TO_DESIGN_BLOCK } from 'appConstants';\nimport { useTranslation } from 'react-i18next';\n\nexport const FooterContent: FC = () => {\n  const { t } = useTranslation();\n  return (\n    <FooterContentWrapper>\n      {FOOTER_INFO.map((item, index) => {\n        return (\n          <FooterContentBlock key={JSON.stringify(item)}>\n            <FooterTitle>{t(item.title)}</FooterTitle>\n            <div className={`contentBlock${!!index ? ' designBlock' : ''}`}>\n              {item.members.map((item: string) => {\n                return (\n                  <a\n                    href={!!index ? LINK_TO_DESIGN_BLOCK : `https://github.com/${item}`}\n                    className={`contentItem${!!index ? ' designItem' : ''}`}\n                    key={item}\n                    target=\"_blank\"\n                    rel=\"noreferrer\"\n                  >\n                    {item}\n                  </a>\n                );\n              })}\n            </div>\n          </FooterContentBlock>\n        );\n      })}\n    </FooterContentWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/Footer/components/index.ts",
    "content": "export { FooterContent } from './FooterContent';\n"
  },
  {
    "path": "src/components/Footer/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { RSLogo } from 'typography';\nimport { StyledFooter, FooterWrapper, FooterContentBlockLogo } from './styled';\nimport { Link } from 'react-router-dom';\nimport { FooterContent } from './components';\n\nexport const Footer: FC = () => {\n  return (\n    <StyledFooter>\n      <FooterWrapper>\n        <FooterContentBlockLogo>\n          <Link to=\"/\">\n            <RSLogo login=\" \" />\n          </Link>\n        </FooterContentBlockLogo>\n        <FooterContent />\n      </FooterWrapper>\n    </StyledFooter>\n  );\n};\n"
  },
  {
    "path": "src/components/Footer/styled.ts",
    "content": "import styled from 'styled-components';\nimport { DARK_TEXT_COLOR, FOOTER_NAMES_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { GeneralAdaptiveFont } from 'typography';\n\nexport const StyledFooter = styled.footer`\n  position: sticky;\n  top: 100%;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n  height: 110px;\n  padding: 0 4.2%;\n  background-color: ${DARK_TEXT_COLOR};\n\n  @media (max-width: 992px) {\n    height: 100px;\n  }\n  @media (max-width: 880px) {\n    height: 80px;\n  }\n  @media (max-width: 768px) {\n    height: 65px;\n  }\n  @media (max-width: 550px) {\n    height: 60px;\n  }\n  @media (max-width: 440px) {\n    height: 50px;\n  }\n`;\n\nexport const FooterWrapper = styled.div`\n  display: flex;\n  justify-content: space-between;\n  width: 100%;\n  max-width: 1320px;\n  height: 100%;\n`;\n\nexport const FooterContentWrapper = styled.div`\n  display: flex;\n  justify-content: flex-end;\n  width: 100%;\n  gap: 5.6%;\n\n  @media (max-width: 880px) {\n    display: none;\n  }\n`;\n\nexport const FooterContentBlock = styled.div`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  gap: 13px;\n\n  .contentBlock {\n    display: flex;\n    flex-wrap: wrap;\n    min-height: 24px;\n    gap: 30px;\n\n    @media (max-width: 992px) {\n      gap: 20px;\n    }\n\n    .contentItem {\n      height: 100%;\n      margin-bottom: -20px;\n      font: 400 1rem/24px 'Poppins', sans-serif;\n      color: ${FOOTER_NAMES_COLOR};\n      text-decoration: none;\n      outline: none;\n      ${GeneralAdaptiveFont};\n\n      &:hover {\n        color: ${WHITE_COLOR};\n      }\n\n      @media (max-width: 992px) {\n        margin-bottom: 15px;\n      }\n    }\n  }\n\n  .contentBlock.designBlock {\n    width: auto;\n  }\n\n  .contentItem.designItem {\n    width: 140px;\n  }\n`;\n\nexport const FooterContentBlockLogo = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n\n  a {\n    height: 100%;\n    display: flex;\n    align-items: center;\n  }\n`;\n\nexport const FooterTitle = styled.h1`\n  font: 600 1rem/24px 'Poppins', sans-serif;\n  color: ${WHITE_COLOR};\n  margin: 0;\n  ${GeneralAdaptiveFont};\n`;\n"
  },
  {
    "path": "src/components/Header/components/BurgerMenu/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { NavLink } from 'react-router-dom';\nimport { selectIsBurgerMenuOpen } from 'modules/LoginPage/selectors';\nimport {\n  BurgerMenuWrapper,\n  BurgerMenuLayout,\n  CrossButton,\n  BurgerMenuNavList,\n  BurgerMenuNavListItem,\n  BurgerMenuOverlay,\n} from './styled';\nimport { setBurgerMenuOpen } from 'modules/LoginPage/loginPageReducer';\nimport { APP_NAVIGATION_LINKS } from 'appConstants';\nimport { useTranslation } from 'react-i18next';\nimport { TNavLink } from 'types';\nimport { LangSelect } from '../MenuWrapper/components/LangSelect';\n\ntype BurgerMenuProps = {\n  newUserCheck: boolean;\n  navOnClickHandler: (e: React.MouseEvent<HTMLElement>, path: string) => void;\n};\n\nexport const BurgerMenu: FC<BurgerMenuProps> = ({ newUserCheck, navOnClickHandler }) => {\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n  const isBurgerMenuOpen = useSelector(selectIsBurgerMenuOpen);\n\n  const onClickMenuToggle = () => {\n    dispatch(setBurgerMenuOpen(!isBurgerMenuOpen));\n  };\n\n  return (\n    <BurgerMenuWrapper {...{ isBurgerMenuOpen }}>\n      <BurgerMenuOverlay {...{ isBurgerMenuOpen }} onClick={onClickMenuToggle} />\n      <BurgerMenuLayout>\n        <CrossButton onClick={onClickMenuToggle} />\n        <BurgerMenuNavList>\n          {Object.values(APP_NAVIGATION_LINKS).map((link: TNavLink, index: number) => {\n            if (+newUserCheck + +link.isAlwaysVisible) {\n              return (\n                <BurgerMenuNavListItem key={JSON.stringify(link)}>\n                  <NavLink\n                    to={Object.keys(APP_NAVIGATION_LINKS)[index]}\n                    exact\n                    activeClassName=\"activeNavLink\"\n                    onClick={(e) => {\n                      onClickMenuToggle();\n                      navOnClickHandler(e, Object.keys(APP_NAVIGATION_LINKS)[index]);\n                    }}\n                  >\n                    {t(link.name)}\n                  </NavLink>\n                </BurgerMenuNavListItem>\n              );\n            }\n          })}\n        </BurgerMenuNavList>\n        <LangSelect menuToggle customStyle />\n      </BurgerMenuLayout>\n    </BurgerMenuWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/Header/components/BurgerMenu/styled.ts",
    "content": "import styled from 'styled-components';\nimport { DARK_TEXT_COLOR, OVERLAY_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { ReactComponent as IconClose } from 'assets/svg/cross.svg';\n\ntype BurgerMenuProps = {\n  isBurgerMenuOpen: boolean;\n};\n\nexport const BurgerMenuWrapper = styled.div<BurgerMenuProps>`\n  position: fixed;\n  z-index: 3;\n  top: 0;\n  display: flex;\n  width: 100vw;\n  height: 100vh;\n  transition: transform 0.6s ease-in-out;\n  transform: ${({ isBurgerMenuOpen }) => (isBurgerMenuOpen ? 'translateX(0)' : 'translateX(100%)')};\n`;\n\nexport const BurgerMenuOverlay = styled.div<BurgerMenuProps>`\n  width: calc(100% - 250px);\n  height: 100%;\n  background-color: ${({ isBurgerMenuOpen }) => (isBurgerMenuOpen ? OVERLAY_COLOR : 'none')};\n  transition: background-color 0.6s ease-in-out;\n\n  @media (max-width: 440px) {\n    width: calc(100% - 180px);\n  }\n`;\n\nexport const BurgerMenuLayout = styled.nav`\n  display: flex;\n  flex-direction: column;\n  gap: 40px;\n  width: 250px;\n  height: 100%;\n  padding: 20px 20px 20px 40px;\n  background: ${WHITE_COLOR};\n\n  @media (max-width: 440px) {\n    width: 180px;\n    padding-left: 20px;\n  }\n`;\n\nexport const CrossButton = styled(IconClose)`\n  width: 16px;\n  height: 16px;\n  align-self: flex-end;\n  cursor: pointer;\n`;\n\nexport const BurgerMenuNavList = styled.ul`\n  display: flex;\n  flex-direction: column;\n  gap: 40px;\n  margin: 0;\n  padding-inline-start: 0;\n`;\n\nexport const BurgerMenuNavListItem = styled.li`\n  list-style-type: none;\n\n  a {\n    text-decoration: none;\n    color: ${DARK_TEXT_COLOR};\n  }\n\n  a.activeNavLink,\n  a:hover {\n    font-weight: 700;\n  }\n`;\n"
  },
  {
    "path": "src/components/Header/components/MenuWrapper/components/CoursesSelect/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { selectCurrCourse } from 'modules/LoginPage/selectors';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\nimport { Course } from 'types';\nimport { CommonSelectList } from 'components';\nimport { setCourse } from 'modules/LoginPage/loginPageMiddleware';\n\nexport const CoursesSelect: FC = () => {\n  const [isCourseSelectOpen, setCourseSelectOpen] = useState(false);\n  const dispatch = useDispatch();\n  const currCourse = useSelector(selectCurrCourse);\n  const userData = useSelector(selectUserData);\n\n  const userCourses = userData.courses.filter((item) => item.id !== currCourse.id) ?? null;\n\n  const onCourseChange = (course: Course) => {\n    setCourseSelectOpen(false);\n    dispatch(setCourse(course));\n  };\n\n  return (\n    <CommonSelectList\n      title=\"Course\"\n      listItems={userCourses}\n      onClickHandler={onCourseChange}\n      currItem={currCourse.name}\n      displayList={isCourseSelectOpen}\n      setDisplayList={setCourseSelectOpen}\n    />\n  );\n};\n"
  },
  {
    "path": "src/components/Header/components/MenuWrapper/components/LangSelect/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { LANGUAGES } from 'appConstants';\nimport { selectCurrLanguage } from 'modules/LoginPage/selectors';\nimport i18n from 'translation/resources';\nimport { CommonSelectList } from 'components';\nimport { setLanguage } from 'modules/LoginPage/loginPageMiddleware';\n\ntype LangSelectProps = {\n  menuToggle?: boolean;\n  customStyle?: boolean;\n};\n\nexport const LangSelect: FC<LangSelectProps> = ({ menuToggle, customStyle }) => {\n  const [displayLangList, setDisplayLangList] = useState(false);\n  const dispatch = useDispatch();\n  const currentLanguage = useSelector(selectCurrLanguage);\n\n  const onLangChange = (item: string) => {\n    setDisplayLangList(false);\n    dispatch(setLanguage(item));\n    i18n.changeLanguage(item);\n  };\n\n  const languages: string[] = LANGUAGES.filter((lang) => lang !== currentLanguage);\n\n  return (\n    <CommonSelectList\n      listItems={languages}\n      onClickHandler={onLangChange}\n      currItem={currentLanguage.toUpperCase()}\n      setDisplayList={setDisplayLangList}\n      displayList={displayLangList}\n      isLang\n      {...{ menuToggle, customStyle }}\n    />\n  );\n};\n"
  },
  {
    "path": "src/components/Header/components/MenuWrapper/components/Nav/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { APP_NAVIGATION_LINKS } from 'appConstants';\nimport { NavLink } from 'react-router-dom';\nimport { StyledNav, StyledNavList, StyledNavListItem, StyledHeaderActiveElement } from './styled';\nimport { TNavLink } from 'types';\n\ntype NavProps = {\n  newUserCheck: boolean;\n  navOnClickHandler: (e: React.MouseEvent<HTMLElement>, path: string) => void;\n  isUserAdmin: boolean;\n};\n\nexport const Nav: FC<NavProps> = ({ newUserCheck, navOnClickHandler, isUserAdmin }) => {\n  const { t } = useTranslation();\n\n  return (\n    <StyledNav>\n      <StyledNavList>\n        {Object.values(APP_NAVIGATION_LINKS).map((link: TNavLink, index: number) => {\n          const isNavLinkAvailable = !!(+newUserCheck + +link.isAlwaysVisible);\n          if (isNavLinkAvailable) {\n            if (link.name === 'Admin' && !isUserAdmin) return null;\n            return (\n              <StyledNavListItem key={JSON.stringify(link)} newUserCheck={newUserCheck}>\n                <NavLink\n                  to={Object.keys(APP_NAVIGATION_LINKS)[index]}\n                  exact\n                  activeClassName=\"activeNavLink\"\n                  onClick={(e) => navOnClickHandler(e, Object.keys(APP_NAVIGATION_LINKS)[index])}\n                >\n                  {t(link.name)}\n                  <StyledHeaderActiveElement />\n                </NavLink>\n              </StyledNavListItem>\n            );\n          }\n        })}\n      </StyledNavList>\n    </StyledNav>\n  );\n};\n"
  },
  {
    "path": "src/components/Header/components/MenuWrapper/components/Nav/styled.ts",
    "content": "import { WHITE_COLOR } from 'appConstants/colors';\nimport styled, { keyframes } from 'styled-components';\nimport { ReactComponent as HeaderActiveElement } from 'assets/svg/headerActiveElement.svg';\n\ntype TStyledNavListItemProps = {\n  newUserCheck: boolean;\n};\n\nconst open = keyframes`\n  from: { height: 0 }\n  to: { height: 100%}\n`;\n\nexport const StyledNav = styled.nav`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  align-self: flex-end;\n  margin-right: 60px;\n  font: 400 1rem/24px 'Poppins', sans-serif;\n`;\n\nexport const StyledNavList = styled.ul`\n  @media (max-width: 1430px) {\n    display: none;\n  }\n\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  margin: 0;\n  padding-inline-start: 0;\n  gap: 60px;\n`;\n\nexport const StyledHeaderActiveElement = styled(HeaderActiveElement)`\n  width: 87px;\n  height: 0;\n`;\n\nexport const StyledNavListItem = styled.li<TStyledNavListItemProps>`\n  list-style-type: none;\n\n  a {\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n    align-items: center;\n    height: 52px;\n    color: ${WHITE_COLOR};\n    text-decoration: none;\n\n    &:hover {\n      font-weight: 700;\n    }\n\n    svg {\n      height: 0;\n      margin-bottom: -5px;\n      transition: all 0.5s ease-in-out;\n      animation: ${open} 0.5s ease-in-out;\n    }\n  }\n\n  a.activeNavLink {\n    font-weight: 700;\n\n    svg {\n      height: 22px;\n      margin-bottom: 0;\n    }\n  }\n`;\n"
  },
  {
    "path": "src/components/Header/components/MenuWrapper/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\nimport { CoursesSelect } from './components/CoursesSelect';\nimport { Nav } from './components/Nav';\nimport { MenuButton, StyledMenuWrapper } from './styled';\nimport { LangSelect } from './components/LangSelect';\nimport { setBurgerMenuOpen } from 'modules/LoginPage/loginPageReducer';\nimport { selectIsBurgerMenuOpen } from 'modules/LoginPage/selectors';\n\ntype MenuWrapperProps = {\n  navOnClickHandler: (e: React.MouseEvent<HTMLElement>, path: string) => void;\n};\n\nexport const MenuWrapper: FC<MenuWrapperProps> = ({ navOnClickHandler }) => {\n  const dispatch = useDispatch();\n  const userData = useSelector(selectUserData);\n  const isBurgerMenuOpen = useSelector(selectIsBurgerMenuOpen);\n\n  const newUserCheck = !!userData?.courses.length;\n  const isUserAdmin = !!userData?.isAdmin;\n\n  const onClickMenuToggle = () => {\n    dispatch(setBurgerMenuOpen(!isBurgerMenuOpen));\n  };\n\n  return (\n    <StyledMenuWrapper>\n      <Nav {...{ newUserCheck, navOnClickHandler, isUserAdmin }} />\n      {newUserCheck && <CoursesSelect />}\n      <LangSelect />\n      <MenuButton onClick={onClickMenuToggle} />\n    </StyledMenuWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/Header/components/MenuWrapper/styled.ts",
    "content": "import styled from 'styled-components';\nimport { ReactComponent as MenuToggle } from 'assets/svg/menuToggle.svg';\n\nexport const StyledMenuWrapper = styled.div`\n  display: flex;\n  height: 60px;\n\n  @media (max-width: 1260px) {\n    height: 40px;\n  }\n  @media (max-width: 550px) {\n    margin-left: -30px;\n  }\n  @media (max-width: 440px) {\n    margin-left: -50px;\n  }\n`;\n\nexport const MenuButton = styled(MenuToggle)`\n  width: 0;\n  height: 0;\n  cursor: pointer;\n\n  @media (max-width: 1430px) {\n    width: 24px;\n    height: 24px;\n    margin: 8px 0 0 40px;\n  }\n  @media (max-width: 700px) {\n    width: 20px;\n    height: 20px;\n    margin: 10px 0 0 30px;\n  }\n  @media (max-width: 600px) {\n    margin-left: 0;\n  }\n  @media (max-width: 440px) {\n    width: 16px;\n    height: 16px;\n    margin-top: 12px;\n  }\n`;\n"
  },
  {
    "path": "src/components/Header/components/index.ts",
    "content": "export { MenuWrapper } from './MenuWrapper';\nexport { BurgerMenu } from './BurgerMenu';\n"
  },
  {
    "path": "src/components/Header/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { Link } from 'react-router-dom';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { RSLogo } from 'typography';\nimport { StyledHeader, Container } from './styled';\nimport { selectIsEditProfileDataChange, selectToken } from 'modules/LoginPage/selectors';\nimport { MenuWrapper, BurgerMenu } from './components';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\nimport { activeModalLeavePage } from 'modules/TeamsList/teamsListReducer';\nimport { setPathToThePage } from 'modules/LoginPage/loginPageReducer';\n\nexport const Header: FC = () => {\n  const dispatch = useDispatch();\n  const userData = useSelector(selectUserData);\n  const loginToken = useSelector(selectToken);\n  const isEditProfileDataChange = useSelector(selectIsEditProfileDataChange);\n  const newUserCheck = !!userData?.courses.length;\n\n  const navOnClickHandler = (e: React.MouseEvent<HTMLElement>, path: string) => {\n    if (isEditProfileDataChange) {\n      e.preventDefault();\n      dispatch(activeModalLeavePage(true));\n      dispatch(setPathToThePage(path));\n    }\n  };\n\n  return (\n    <>\n      <StyledHeader login={loginToken}>\n        <Container>\n          <Link to=\"/\">\n            <RSLogo login={loginToken} />\n          </Link>\n          {loginToken && <MenuWrapper {...{ navOnClickHandler }} />}\n        </Container>\n      </StyledHeader>\n      <BurgerMenu {...{ newUserCheck, navOnClickHandler }} />\n    </>\n  );\n};\n"
  },
  {
    "path": "src/components/Header/styled.ts",
    "content": "import styled from 'styled-components';\nimport { MAIN1_COLOR } from 'appConstants/colors';\nimport { GeneralAdaptiveFont } from 'typography';\n\ntype TStyledHeaderProps = {\n  login: string | null;\n};\n\nexport const StyledHeader = styled.header<TStyledHeaderProps>`\n  position: sticky;\n  display: flex;\n  justify-content: center;\n  align-items: flex-end;\n  height: 80px;\n  padding: ${({ login }) => (login ? '1.4% 4.2% 0' : '2.8% 4.2% 0 2.8%')};\n  background-color: ${({ login }) => (login ? MAIN1_COLOR : 'transparent')};\n  width: 100%;\n  z-index: 1;\n\n  @media (max-width: 1260px) {\n    align-items: center;\n  }\n`;\n\nexport const Container = styled.div`\n  display: flex;\n  justify-content: space-between;\n  width: 100%;\n  max-width: 1320px;\n  ${GeneralAdaptiveFont};\n`;\n"
  },
  {
    "path": "src/components/InputField/index.tsx",
    "content": "import React, { FC, InputHTMLAttributes } from 'react';\nimport { Input } from 'typography';\nimport { FieldWrapper, ValidationAlert, FLabel } from './styled';\nimport { useTranslation } from 'react-i18next';\nexport interface InputFieldProps extends InputHTMLAttributes<HTMLInputElement> {\n  labelText?: string;\n  placeholder?: string;\n  register?: any;\n  name: string;\n  message?: string | undefined;\n  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport const InputField: FC<InputFieldProps> = ({\n  labelText,\n  placeholder,\n  register,\n  name,\n  message,\n  onChange,\n}) => {\n  const { t } = useTranslation();\n  return (\n    <FieldWrapper>\n      <FLabel htmlFor={name}>{labelText ? t(labelText) : ''}</FLabel>\n      <Input\n        id={`id-${name}`}\n        name={name}\n        placeholder={placeholder ? t(placeholder) : ''}\n        ref={register}\n        autoComplete=\"off\"\n        onChange={onChange}\n      />\n      <ValidationAlert>{message ? t(message) : ''}</ValidationAlert>\n    </FieldWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/InputField/styled.ts",
    "content": "import styled from 'styled-components';\nimport { ALERT_COLOR } from 'appConstants/colors';\nimport { GeneralAdaptiveFont, Label } from 'typography';\n\nexport const FieldWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  margin-bottom: 0;\n`;\n\nexport const ValidationAlert = styled.div`\n  ${GeneralAdaptiveFont}\n  color: ${ALERT_COLOR};\n  font-size: 14px;\n  height: 22px;\n`;\n\nexport const FLabel = styled(Label)`\n  margin-bottom: 8px;\n`;\n"
  },
  {
    "path": "src/components/Loader/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { LoaderStyled, LoaderWrapper } from './styled';\n\nexport const Loader: FC = () => {\n  return (\n    <LoaderWrapper>\n      <LoaderStyled>\n        <div className=\"loader\">\n          <div className=\"loader-child loader-child-1\"></div>\n          <div className=\"loader-child loader-child-2\"></div>\n          <div className=\"loader-child loader-child-3\"></div>\n        </div>\n      </LoaderStyled>\n    </LoaderWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/Loader/styled.ts",
    "content": "import styled from 'styled-components';\nimport { MAIN1_COLOR } from 'appConstants/colors';\nimport { MainComponentHeight } from 'typography';\n\nexport const LoaderWrapper = styled.div`\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  transform: translate(-50%, -50%);\n  ${MainComponentHeight};\n`;\n\nexport const LoaderStyled = styled.div`\n  width: 25%;\n  .loader {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 100%;\n    height: 2.5em;\n    gap: 12px;\n    animation-duration: 1.4s;\n    animation-delay: 0.32s;\n    margin: auto;\n    text-align: center;\n\n    @media (max-width: 440px) {\n      gap: 9px;\n    }\n\n    .loader-child {\n      width: 1.8em;\n      height: 1.8em;\n      background-color: ${MAIN1_COLOR};\n\n      border-radius: 100%;\n      display: inline-block;\n      animation: loader-in 1.6s ease-in-out 0s infinite both;\n\n      @media (max-width: 1200px) {\n        width: 1.7em;\n        height: 1.7em;\n      }\n      @media (max-width: 550px) {\n        width: 1.4em;\n        height: 1.4em;\n      }\n      @media (max-width: 440px) {\n        width: 1em;\n        height: 1em;\n      }\n    }\n\n    .loader-child-1 {\n      animation-delay: -0.6s;\n    }\n    .loader-child-2 {\n      animation-delay: -0.4s;\n    }\n    .loader-child-3 {\n      animation-delay: -0.2s;\n    }\n  }\n\n  @keyframes loader-in {\n    0%,\n    80%,\n    100% {\n      transform: scale(0);\n    }\n    40% {\n      transform: scale(1);\n    }\n  }\n`;\n"
  },
  {
    "path": "src/components/Modal/index.module.css",
    "content": "/* setting absolute can break other modals */\n.overlay {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 999;\n  text-align: center;\n  background: var(--OVERLAY_COLOR);\n\n  overscroll-behavior: contain;\n}\n\n/* setting max width to container can break other modals */\n.container {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 440px;\n  margin: 11vh auto;\n  padding: 30px 40px;\n  text-align: center;\n  background: var(--WHITE_COLOR);\n  border: none;\n  border-radius: 20px;\n}\n\n.icon {\n  position: absolute;\n  top: 20px;\n  right: 20px;\n  z-index: 1;\n  width: 25px;\n  height: 25px;\n  cursor: pointer;\n}\n\n@media (max-width: 550px) {\n  .container {\n    width: 350px;\n  }\n\n  .icon {\n    top: 15px;\n    right: 20px;\n    width: 22px;\n    height: 22px;\n  }\n}\n\n@media (max-width: 440px) {\n  .container {\n    width: 300px;\n  }\n\n  .icon {\n    top: 15px;\n    right: 20px;\n    width: 20px;\n    height: 20px;\n  }\n}\n"
  },
  {
    "path": "src/components/Modal/index.tsx",
    "content": "import React, { FC, SyntheticEvent, useEffect, useRef } from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { ReactComponent as IconClose } from 'assets/svg/cross.svg';\nimport styled from 'styled-components';\nimport styles from './index.module.css';\nimport { PageTitle, Label, Button, InvertedButton, ButtonsBlock } from 'typography';\nimport { useTranslation } from 'react-i18next';\n\ntype ModalProps = {\n  title: string;\n  text: string;\n  text2?: string;\n  open: boolean;\n  hideOnOutsideClick?: boolean;\n  hideOnEsc?: boolean;\n  children?: React.ReactNode;\n  onClose(): void;\n  onSubmit?: (e: SyntheticEvent) => void;\n  okText?: string;\n  cancelText?: string;\n  isCrossIconVisible?: boolean;\n} & typeof defaultProps;\n\nconst defaultProps = {\n  hideOnOutsideClick: true,\n  hideOnEsc: true,\n};\n\nconst ModalWindow = styled.div`\n  left: 500px;\n  top: 315px;\n  background: #ffffff;\n  border-radius: 20px;\n`;\n\nexport const Modal: FC<ModalProps> = ({\n  title,\n  text,\n  text2,\n  open,\n  children,\n  hideOnOutsideClick,\n  hideOnEsc,\n  onClose,\n  onSubmit,\n  isCrossIconVisible = true,\n  okText,\n  cancelText,\n}) => {\n  const insideRef = useRef<HTMLDivElement>(null);\n  const { t } = useTranslation();\n\n  const close = (e: React.MouseEvent | MouseEvent) => {\n    e.stopPropagation();\n    onClose();\n  };\n\n  const onOutClick: React.MouseEventHandler<HTMLDivElement> = (e) => {\n    const curRef = insideRef.current;\n    if (hideOnOutsideClick && curRef && !curRef.contains(e.target as Node)) {\n      onClose();\n    }\n  };\n\n  useEffect(() => {\n    const listener = (e: KeyboardEvent) => {\n      if (e.key === 'Escape' || (!onSubmit && e.key === 'Enter')) {\n        onClose();\n      }\n    };\n\n    if (open && hideOnEsc) {\n      document.addEventListener('keydown', listener);\n    }\n\n    return () => document.removeEventListener('keydown', listener);\n  }, [open, onClose, hideOnEsc, onSubmit]);\n\n  useEffect(() => {\n    if (open) {\n      document.body.style.overflow = 'hidden';\n    } else {\n      document.body.style.overflow = '';\n    }\n\n    return () => {\n      document.body.style.overflow = '';\n    };\n  }, [open]);\n\n  if (!open) {\n    return null;\n  }\n\n  return ReactDOM.createPortal(\n    <div className={styles.overlay} onClick={onOutClick}>\n      <div className={styles.container} ref={insideRef}>\n        {isCrossIconVisible && <IconClose className={styles.icon} onClick={close} />}\n        <ModalWindow>\n          <PageTitle>{t(title)}</PageTitle>\n          <Label>{t(text)}</Label>\n          <p>\n            <Label>{text2 ? t(text2) : ''}</Label>\n          </p>\n          {children}\n          <ButtonsBlock>\n            {onSubmit ? (\n              cancelText ? (\n                <>\n                  <InvertedButton onClick={onClose}>{t(cancelText)}</InvertedButton>\n                  <Button\n                    onClick={(e) => {\n                      onSubmit(e);\n                    }}\n                  >\n                    {okText ? t(okText) : ''}\n                  </Button>\n                </>\n              ) : (\n                <Button\n                  onClick={(e) => {\n                    onSubmit(e);\n                  }}\n                >\n                  {okText ? t(okText) : ''}\n                </Button>\n              )\n            ) : (\n              <Button onClick={onClose}>{cancelText ? t(cancelText) : ''}</Button>\n            )}\n          </ButtonsBlock>\n        </ModalWindow>\n      </div>\n    </div>,\n    document.body\n  );\n};\n\nModal.defaultProps = defaultProps;\n"
  },
  {
    "path": "src/components/ModalCreateEditTeam/index.tsx",
    "content": "import React, { FC, useState, useEffect, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Modal } from 'components';\nimport { ModalInput } from 'typography';\nimport { ValidationAlert } from '../InputField/styled';\nimport { useTranslation } from 'react-i18next';\nimport { setSocialLink } from 'modules/TeamsList/teamsListReducer';\nimport { isFieldValid } from 'utils/isFieldValid';\n\ntype Props = {\n  title: string;\n  text: string;\n  open: boolean;\n  onSubmit?: () => void;\n  onClose: () => void;\n  value: string;\n  okText?: string;\n  validateRules?: any;\n} & typeof defaultProps;\n\nconst defaultProps = {\n  open: false,\n  okText: 'Create team',\n};\n\nexport const ModalCreateEditTeam: FC<Props> = ({\n  title,\n  text,\n  open,\n  okText,\n  value,\n  onClose,\n  onSubmit,\n  validateRules,\n}) => {\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n  const [isInputValid, setInputValid] = useState(false);\n  const [errorMessage, setErrorMessage] = useState('');\n\n  const onSubmitModal = useCallback(() => {\n    if (isInputValid && onSubmit) {\n      onSubmit();\n      onClose();\n    } else {\n      setErrorMessage('Please, enter link');\n    }\n  }, [onClose, onSubmit, isInputValid]);\n\n  const onChangeModal = (e: React.ChangeEvent<HTMLInputElement>) => {\n    dispatch(setSocialLink(e.target.value.trim()));\n    isFieldValid(\n      e.target.value.trim(),\n      validateRules,\n      !!validateRules,\n      setInputValid,\n      setErrorMessage\n    );\n  };\n\n  const onCloseModal = () => {\n    onClose();\n    setErrorMessage('');\n  };\n\n  useEffect(() => {\n    const listener = (e: KeyboardEvent) => {\n      if (e.key === 'Enter') {\n        onSubmitModal();\n      }\n    };\n    if (open) {\n      document.addEventListener('keydown', listener);\n    }\n    return () => document.removeEventListener('keydown', listener);\n  }, [onSubmitModal, open]);\n\n  return (\n    <Modal\n      {...{ title, text, open, okText }}\n      onClose={onCloseModal}\n      onSubmit={onSubmitModal}\n      hideOnOutsideClick\n      hideOnEsc\n    >\n      <ModalInput\n        name=\"inputValue\"\n        required\n        value={value.trim()}\n        autoComplete={'off'}\n        onChange={onChangeModal}\n        placeholder={t('Enter group link')}\n      />\n      {!isInputValid && <ValidationAlert>{t(errorMessage)}</ValidationAlert>}\n    </Modal>\n  );\n};\n"
  },
  {
    "path": "src/components/ModalCreated/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport styled from 'styled-components';\nimport { Modal } from 'components';\nimport { ModalInput, InvertedButton } from 'typography';\nimport { BG_COLOR } from 'appConstants/colors';\nimport CopyIcon from 'assets/svg/copy2clip.svg';\n\nconst InputWithCopy = styled.div`\n  position: relative;\n`;\n\nconst CopyButton = styled(InvertedButton)`\n  right: 40px;\n  bottom: 0;\n  padding: 19px 15px;\n  position: absolute;\n  background: ${BG_COLOR} url(${CopyIcon}) no-repeat center center;\n`;\n\ntype Props = {\n  title: string;\n  text: string;\n  text2?: string;\n  open: boolean;\n  onClose: () => void;\n  cancelText?: string;\n  password: string;\n} & typeof defaultProps;\n\nconst defaultProps = {\n  text2: '',\n};\n\nexport const ModalCreated: FC<Props> = ({\n  title,\n  text,\n  text2,\n  open,\n  cancelText,\n  onClose,\n  password,\n}) => {\n  const [isCopy, setIsCopy] = useState(false);\n\n  const CopyToClipboard = (text: string) => {\n    navigator.clipboard\n      .writeText(text)\n      .then(() => {\n        setIsCopy(true);\n        setTimeout(() => {\n          setIsCopy(false);\n        }, 1000);\n      })\n      .catch((err) => {\n        console.log('Something went wrong', err);\n      });\n  };\n  const onClickCopyButton = () => CopyToClipboard(password);\n\n  return (\n    <Modal {...{ title, text, text2, open, onClose, cancelText }} hideOnOutsideClick hideOnEsc>\n      <InputWithCopy>\n        <ModalInput name=\"InputValue\" value={password} readOnly blink={isCopy} />\n        <CopyButton onClick={onClickCopyButton} />\n      </InputWithCopy>\n    </Modal>\n  );\n};\n"
  },
  {
    "path": "src/components/ModalEditCourse/index.tsx",
    "content": "import React, { FC, useState, useEffect, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Modal } from 'components';\nimport { TeamButton } from 'typography';\nimport { useTranslation } from 'react-i18next';\nimport { activeModalEditCourse } from 'modules/TeamsList/teamsListReducer';\nimport { InputBlock } from 'modules/AdminPage/components/ContentWrapper/components/AddCourseBlock/components/InputsBlock';\nimport { Course } from 'types';\nimport { COURSE_NAME_VALIDATION, TEAM_SIZE_VALIDATION } from 'appConstants';\nimport { onChangeField } from 'modules/AdminPage/components/ContentWrapper/components/AddCourseBlock';\nimport { DASHBOARD_HEADER_BG_COLOR, MAIN1_COLOR } from 'appConstants/colors';\nimport { useUpdateCourseMutation } from 'hooks/graphql';\nimport { ErrorModal } from 'components/ErrorModal';\n\ntype Props = {\n  title: string;\n  text: string;\n  open: boolean;\n  okText?: string;\n  cancelText?: string;\n  courseEditMeta: Course;\n  checkIsCourseNameUniq: (courseName: string) => boolean;\n  setCourseEditMeta: (course: Course | null) => void;\n};\n\nconst isCourseInfoChanged = (\n  { name, teamSize, isActive }: Course,\n  newName: string,\n  newTeamSize: string,\n  newStatus: boolean\n) => name !== newName || `${teamSize}` !== newTeamSize || isActive !== newStatus;\n\nexport const ModalEditCourse: FC<Props> = ({\n  title,\n  text,\n  open,\n  okText,\n  cancelText,\n  courseEditMeta,\n  checkIsCourseNameUniq,\n  setCourseEditMeta,\n}) => {\n  const { t } = useTranslation();\n  const dispatch = useDispatch();\n\n  const [isCourseNameFieldValid, setIsCourseNameFieldValid] = useState(true);\n  const [isTeamSizeFieldValid, setIsTeamSizeFieldValid] = useState(true);\n  const [courseName, setCourseName] = useState(courseEditMeta.name);\n  const [teamSize, setTeamSize] = useState(`${courseEditMeta.teamSize ?? ''}`);\n  const [isCourseActive, setIsCourseActive] = useState(courseEditMeta.isActive);\n  const [courseNameErrorMessage, setCourseNameErrorMessage] = useState('');\n  const [teamSizeErrorMessage, setTeamSizeErrorMessage] = useState('');\n\n  const { updateCourse, errorM: errorUpdateCourse } = useUpdateCourseMutation({\n    course: {\n      id: courseEditMeta?.id || '',\n      name: courseName,\n      teamSize: +teamSize,\n      isActive: isCourseActive,\n    },\n  });\n\n  const onCloseModal = useCallback(() => {\n    setCourseEditMeta(null);\n    setCourseNameErrorMessage('');\n    setTeamSizeErrorMessage('');\n    dispatch(activeModalEditCourse(false));\n  }, [dispatch, setCourseEditMeta]);\n\n  const onSubmitModal = useCallback(() => {\n    if (isCourseNameFieldValid && isTeamSizeFieldValid) {\n      if (courseName && teamSize) {\n        const isCourseChanged = courseEditMeta\n          ? isCourseInfoChanged(courseEditMeta, courseName, teamSize, isCourseActive)\n          : true;\n        isCourseChanged && updateCourse();\n        onCloseModal();\n      } else {\n        if (!courseName) {\n          setIsCourseNameFieldValid(false);\n          setCourseNameErrorMessage(COURSE_NAME_VALIDATION.minLength.message);\n        }\n        if (!teamSize) {\n          setIsTeamSizeFieldValid(false);\n          setTeamSizeErrorMessage(TEAM_SIZE_VALIDATION.minLength.message);\n        }\n      }\n    }\n  }, [\n    onCloseModal,\n    courseEditMeta,\n    courseName,\n    isCourseActive,\n    isCourseNameFieldValid,\n    isTeamSizeFieldValid,\n    teamSize,\n    updateCourse,\n  ]);\n\n  useEffect(() => {\n    const listener = (e: KeyboardEvent) => {\n      if (e.key === 'Enter') {\n        onSubmitModal();\n      }\n    };\n    if (open) {\n      document.addEventListener('keydown', listener);\n    }\n    return () => document.removeEventListener('keydown', listener);\n  }, [onSubmitModal, open]);\n\n  const changeCourseStateButtonText = isCourseActive ? 'Terminate course' : 'Activate course';\n  const onChangeCourseState = () => setIsCourseActive(!isCourseActive);\n\n  if (errorUpdateCourse) return <ErrorModal error={errorUpdateCourse} />;\n\n  return (\n    <Modal\n      {...{ title, text, open, okText, cancelText }}\n      onClose={onCloseModal}\n      onSubmit={onSubmitModal}\n      hideOnOutsideClick\n      hideOnEsc\n    >\n      <InputBlock\n        inputLabel=\"New course name\"\n        value={courseName}\n        placeholder=\"Enter new course name\"\n        onChangeHandler={onChangeField(\n          COURSE_NAME_VALIDATION,\n          setIsCourseNameFieldValid,\n          setCourseNameErrorMessage,\n          setCourseName,\n          checkIsCourseNameUniq\n        )}\n        isFieldValid={isCourseNameFieldValid}\n        errorMessage={courseNameErrorMessage}\n        isModal\n      />\n      <InputBlock\n        inputLabel=\"New team size\"\n        value={teamSize}\n        placeholder=\"Enter new team size\"\n        onChangeHandler={onChangeField(\n          TEAM_SIZE_VALIDATION,\n          setIsTeamSizeFieldValid,\n          setTeamSizeErrorMessage,\n          setTeamSize\n        )}\n        isFieldValid={isTeamSizeFieldValid}\n        errorMessage={teamSizeErrorMessage}\n        isModal\n      />\n      <TeamButton\n        bgc={DASHBOARD_HEADER_BG_COLOR}\n        color={MAIN1_COLOR}\n        type=\"button\"\n        onClick={onChangeCourseState}\n      >\n        {t(changeCourseStateButtonText)}\n      </TeamButton>\n    </Modal>\n  );\n};\n"
  },
  {
    "path": "src/components/ModalExpel/index.tsx",
    "content": "import React, { FC, useEffect, useCallback } from 'react';\nimport { Modal } from 'components';\n\ntype Props = {\n  title: string;\n  text: string;\n  open: boolean;\n  onSubmit?: () => void;\n  onClose: () => void;\n  okText?: string;\n  isCrossIconVisible?: boolean;\n  cancelText?: string;\n};\n\nexport const ModalExpel: FC<Props> = ({\n  title,\n  text,\n  open,\n  okText,\n  cancelText,\n  isCrossIconVisible = true,\n  onClose,\n  onSubmit,\n}) => {\n  const onSubmitModal = useCallback(() => {\n    onClose();\n    if (onSubmit) {\n      onSubmit();\n    }\n  }, [onClose, onSubmit]);\n\n  useEffect(() => {\n    const listener = (e: KeyboardEvent) => {\n      if (e.key === 'Enter') {\n        onSubmitModal();\n      }\n    };\n    if (open) {\n      document.addEventListener('keydown', listener);\n    }\n    return () => document.removeEventListener('keydown', listener);\n  }, [onSubmitModal, open]);\n\n  return (\n    <Modal\n      {...{\n        title,\n        text,\n        open,\n        onClose,\n        okText,\n        isCrossIconVisible,\n        cancelText,\n      }}\n      onSubmit={onSubmitModal}\n      hideOnOutsideClick\n      hideOnEsc\n    />\n  );\n};\n"
  },
  {
    "path": "src/components/ModalJoin/index.tsx",
    "content": "import React, { FC, useCallback, useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Modal } from 'components';\nimport { ModalInput } from 'typography';\nimport { useTranslation } from 'react-i18next';\nimport { setTeamPassword } from 'modules/TeamsList/teamsListReducer';\n\ntype Props = {\n  title: string;\n  text: string;\n  open: boolean;\n  okText?: string;\n  value: string;\n  cancelText?: string;\n  onClose: () => void;\n  onSubmit?: (e: string) => void;\n  onChange?: () => void;\n};\n\nexport const ModalJoin: FC<Props> = ({\n  title,\n  text,\n  open,\n  okText,\n  value,\n  cancelText,\n  onClose,\n  onSubmit,\n  onChange,\n}) => {\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n\n  const onSubmitModal = useCallback(() => {\n    if (onSubmit && value) {\n      onSubmit(value);\n    }\n  }, [value, onSubmit]);\n\n  const onChangeModal = (e: React.ChangeEvent<HTMLInputElement>) => {\n    if (onChange) {\n      onChange();\n    }\n    dispatch(setTeamPassword(e.target.value));\n  };\n\n  useEffect(() => {\n    const listener = (e: KeyboardEvent) => {\n      if (e.key === 'Enter') {\n        onSubmitModal();\n      }\n    };\n    if (open) {\n      document.addEventListener('keydown', listener);\n    }\n    return () => document.removeEventListener('keydown', listener);\n  }, [onSubmitModal, open]);\n\n  return (\n    <Modal\n      {...{ title, text, open, onClose, okText, cancelText }}\n      onSubmit={onSubmitModal}\n      hideOnOutsideClick\n      hideOnEsc\n    >\n      <ModalInput\n        placeholder={t('Enter team password')}\n        name=\"InputValue\"\n        required\n        value={value}\n        onChange={onChangeModal}\n        type=\"password\"\n      />\n    </Modal>\n  );\n};\n"
  },
  {
    "path": "src/components/Pagination/index.tsx",
    "content": "import React, { FC } from 'react';\nimport ReactPaginate from 'react-paginate';\nimport './style.css';\nimport leftArrow from 'assets/svg/paginateArrowLeft.svg';\nimport rightArrow from 'assets/svg/paginateArrowRight.svg';\n\ntype PaginationProps = {\n  pageCount: number;\n  changePage: (page: number) => void;\n  page: number;\n};\n\nexport const Pagination: FC<PaginationProps> = ({ pageCount, changePage, page }) => {\n  return (\n    <ReactPaginate\n      previousLabel={<img src={leftArrow} alt=\"Previous\" />}\n      nextLabel={<img src={rightArrow} alt=\"Next\" />}\n      breakLabel={'...'}\n      pageCount={pageCount}\n      initialPage={page}\n      marginPagesDisplayed={1}\n      pageRangeDisplayed={2}\n      containerClassName={'pagination'}\n      pageClassName={'pageContainer'}\n      pageLinkClassName={'pageLink'}\n      activeClassName={'activePageContainer'}\n      activeLinkClassName={'activePageLink'}\n      onPageChange={(page) => changePage(page.selected)}\n    />\n  );\n};\n"
  },
  {
    "path": "src/components/Pagination/style.css",
    "content": ".pagination {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  margin: 40px auto 0;\n\n  gap: 10px;\n  padding-inline-start: 0;\n}\n\n.pagination li {\n  list-style: none;\n}\n\n.pagination li a {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 40px;\n  height: 40px;\n  padding: 8px;\n  outline: none;\n}\n\n.pageContainer,\n.previous,\n.next,\n.break {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: #ffffff;\n  border-radius: 10px;\n  cursor: pointer;\n}\n\n.previous a img,\n.next a img {\n  width: 12px;\n  height: 12px;\n}\n\n.previous.disabled,\n.next.disabled {\n  cursor: unset;\n  opacity: 0.7;\n}\n\n.activePageContainer {\n  background-color: #6550f6;\n  cursor: unset;\n}\n\n.pageLink,\n.break > a {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  font: 400 1rem/24px \"Poppins\", sans-serif;\n  color: #7e96c2;\n  text-decoration: none;\n}\n\n.activePageLink {\n  color: #ffffff;\n}\n\n@media (max-width: 1200px) and (min-width: 992px) {\n  .pagination {\n    margin: 35px auto 0;\n  }\n\n  .pageLink,\n  .break > a {\n    font-size: 0.95rem;\n  }\n}\n@media (max-width: 992px) {\n  .pagination {\n    margin: 30px auto 0;\n  }\n\n  .pageLink,\n  .break > a {\n    font-size: 0.9rem;\n  }\n\n  .pagination li a {\n    width: 35px;\n    height: 35px;\n  }\n}\n@media (max-width: 768px) {\n  .pagination {\n    margin: 30px auto 0;\n  }\n\n  .pageLink,\n  .break > a {\n    font-size: 0.825rem;\n  }\n\n  .pagination li a {\n    width: 30px;\n    height: 30px;\n  }\n\n  .previous a img,\n  .next a img {\n    width: 10px;\n    height: 10px;\n  }\n}\n@media (max-width: 550px) {\n  .pagination {\n    margin: 25px auto 0;\n  }\n\n  .pageLink,\n  .break > a {\n    font-size: 0.8rem;\n  }\n\n  .pagination li a {\n    width: 30px;\n    height: 30px;\n  }\n\n  .previous a img,\n  .next a img {\n    width: 10px;\n    height: 10px;\n  }\n}\n@media (max-width: 440px) {\n  .pagination {\n    margin: 20px auto 0;\n  }\n\n  .pageLink,\n  .break > a {\n    font-size: 0.68rem;\n  }\n\n  .pagination li a {\n    width: 25px;\n    height: 25px;\n  }\n\n  .previous a img,\n  .next a img {\n    width: 9px;\n    height: 9px;\n  }\n}\n"
  },
  {
    "path": "src/components/PrivateRoute/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { Redirect, Route } from 'react-router-dom';\n\ntype Props = {\n  isLoggedIn: boolean;\n  path: string;\n  component: FC<any>;\n  exact?: boolean;\n  newUserCheck?: boolean;\n};\n\nexport const PrivateRoute: FC<Props> = ({\n  component: Component,\n  isLoggedIn,\n  newUserCheck,\n  path,\n  exact,\n}) => {\n  return (\n    <Route\n      exact={exact}\n      path={path}\n      render={(props) => {\n        if (isLoggedIn && newUserCheck) {\n          return <Component {...props} />;\n        }\n        if (isLoggedIn && !newUserCheck) {\n          return <Redirect to={'/edit-profile'} />;\n        }\n        if (!isLoggedIn) {\n          return <Redirect to={{ pathname: '/login', state: { from: props.location } }} />;\n        }\n      }}\n    />\n  );\n};\n"
  },
  {
    "path": "src/components/SelectField/index.tsx",
    "content": "import React, { FC, SelectHTMLAttributes } from 'react';\nimport { Label, Select, SelectInner } from 'typography';\nimport { FieldWrapper } from './styled';\n//\n// for future\n// TODO: make separate SelectField component for other screens\n// now is not used\n//\ninterface SelectFieldProps extends SelectHTMLAttributes<HTMLSelectElement> {\n  labelText: string;\n  placeholder: string;\n  multi?: boolean;\n  register: any;\n}\n\nconst SelectField: FC<SelectFieldProps> = ({ labelText, placeholder, register, ...rest }) => {\n  return (\n    <FieldWrapper>\n      <Label>{labelText}</Label>\n      <Select>\n        <SelectInner placeholder={placeholder} ref={register} defaultValue=\"0\" {...rest}>\n          <option disabled hidden value=\"0\">\n            Select course\n          </option>\n          <option value=\"111\">222</option>\n          <option value=\"333\">444</option>\n        </SelectInner>\n      </Select>\n    </FieldWrapper>\n  );\n};\n"
  },
  {
    "path": "src/components/SelectField/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const FieldWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  margin-bottom: 20px;\n`;\n\nexport const PlaceholderOption = styled.option`\n  display: none;\n`;\n"
  },
  {
    "path": "src/components/TablePopup/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { StyledPopup, StyledPopupItem } from './styled';\n\ntype TablePopupProps = {\n  dataLength: number;\n  popupElements: string[];\n};\n\nexport const TablePopup: FC<TablePopupProps> = ({ popupElements, dataLength }) => {\n  return (\n    <StyledPopup dataLength={dataLength}>\n      {popupElements?.map((element: string) => (\n        <StyledPopupItem key={element}>{element}</StyledPopupItem>\n      ))}\n    </StyledPopup>\n  );\n};\n"
  },
  {
    "path": "src/components/TablePopup/styled.ts",
    "content": "import { WHITE_COLOR, DARK_TEXT_COLOR, TABLE_POPUP_BORDER_COLOR } from 'appConstants/colors';\nimport styled from 'styled-components';\nimport { GeneralAdaptiveFont } from 'typography';\n\ntype TStyledPopup = {\n  dataLength: number;\n};\n\nexport const StyledPopup = styled.div<TStyledPopup>`\n  position: absolute;\n  top: ${({ dataLength }) => dataLength < 0.5 && '95%'};\n  bottom: ${({ dataLength }) => dataLength > 0.5 && '95%'};\n  right: 0;\n  z-index: 2;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  padding: 10px;\n  font-size: 1rem;\n  color: ${DARK_TEXT_COLOR};\n  background-color: ${WHITE_COLOR};\n  border: 1px solid ${TABLE_POPUP_BORDER_COLOR};\n  border-radius: 10px;\n  ${GeneralAdaptiveFont};\n  @media (max-width: 440px) {\n    left: -5px;\n    padding: 5px;\n  }\n`;\n\nexport const StyledPopupItem = styled.p`\n  margin: 0;\n  line-height: 17px;\n  text-align: justify;\n`;\n"
  },
  {
    "path": "src/components/TourGuide/index.tsx",
    "content": "import React, { FC, useCallback, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { selectIsTourOpen } from 'modules/LoginPage/selectors';\nimport Tour, { ReactourStep } from 'reactour';\nimport { tourConfig } from './tourConfig';\nimport { setIsTourOpen } from 'modules/LoginPage/loginPageReducer';\nimport { MAIN1_COLOR } from 'appConstants/colors';\nimport leftArrow from 'assets/svg/paginateArrowLeft.svg';\nimport rightArrow from 'assets/svg/paginateArrowRight.svg';\nimport './style.css';\nimport { useHistory } from 'react-router';\nimport { useTranslation } from 'react-i18next';\n\nexport const TourGuide: FC = () => {\n  const [isButtonsVisible, setIsButtonsVisible] = useState(false);\n  const dispatch = useDispatch();\n  const isTourOpen = useSelector(selectIsTourOpen);\n  const history = useHistory();\n  const { t } = useTranslation();\n\n  const onRequestCloseHandler = () => dispatch(setIsTourOpen(false));\n\n  const tourConfigInfo = useCallback(\n    () => tourConfig(history, dispatch, t),\n    [history, dispatch, t]\n  );\n\n  return (\n    <Tour\n      onRequestClose={onRequestCloseHandler}\n      steps={tourConfigInfo() as ReactourStep[]}\n      isOpen={isTourOpen}\n      prevButton={<img src={leftArrow} alt=\"Previous\" />}\n      nextButton={<img src={rightArrow} alt=\"Next\" />}\n      accentColor={MAIN1_COLOR}\n      maskClassName=\"mask\"\n      disableDotsNavigation\n      disableKeyboardNavigation\n      showNavigationNumber={false}\n      showButtons={isButtonsVisible}\n      disableInteraction\n      lastStepNextButton={<div className=\"LastStepNextButton\" />}\n      getCurrentStep={(currStep) => setIsButtonsVisible(!!currStep)}\n      closeWithMask={false}\n      className=\"helper\"\n      rounded={20}\n    />\n  );\n};\n"
  },
  {
    "path": "src/components/TourGuide/style.css",
    "content": "span[data-tour-elem=\"badge\"] {\n  top: 20px;\n  left: 20px;\n  width: 30px;\n  height: 30px;\n  padding: 0;\n  font-weight: bold;\n  font-family: \"Poppins\", sans-serif;\n  border-radius: 50%;\n  box-shadow: none;\n}\n\n.reactour__helper.helper {\n  width: 440px;\n  max-width: 440px;\n  padding: 64px 20px 20px;\n  font-family: \"Poppins\", sans-serif;\n  text-align: justify;\n  box-shadow: none;\n}\n\n.reactour__helper.helper p {\n  text-align: center;\n}\n\n.reactour__helper.helper > .reactour__close {\n  top: 18px;\n  right: 18px;\n  width: 18px;\n  height: 18px;\n  color: #7e96c2;\n  background: center / contain url(\"../../assets/svg/cross.svg\") no-repeat;\n}\n\n.reactour__close > svg {\n  display: none;\n}\n\nbutton[data-tour-elem=\"right-arrow\"] {\n  order: 2;\n  margin-left: 0;\n}\n\nbutton[data-tour-elem=\"left-arrow\"] {\n  order: 1;\n  margin-right: 10px;\n  margin-left: auto;\n}\n\nbutton[data-tour-elem=\"right-arrow\"],\nbutton[data-tour-elem=\"left-arrow\"],\n.LastStepNextButton {\n  width: 40px;\n  height: 40px;\n  border-radius: 10px;\n}\n\nbutton[data-tour-elem=\"right-arrow\"],\nbutton[data-tour-elem=\"left-arrow\"] {\n  background-color: #f2f8fd;\n}\n\n.LastStepNextButton {\n  background-color: #ffffff;\n  cursor: default;\n}\n\nbutton[data-tour-elem=\"right-arrow\"] > img,\nbutton[data-tour-elem=\"left-arrow\"] > img {\n  margin: 0 auto;\n  background-color: transparent;\n}\n\ndiv[data-tour-elem=\"controls\"] {\n  align-items: flex-end;\n}\n\nnav > .reactour__dot {\n  background-color: #e1eefa;\n  border: none;\n}\n\nnav > .reactour__dot:disabled {\n  cursor: unset;\n}\n\nnav > .reactour__dot--is-active {\n  background-color: #6550f6;\n}\n\n.mask {\n  color: #363d48;\n  opacity: 0.4;\n}\n\n.linkToRepo {\n  font-weight: bold;\n  color: #6550f6;\n  text-decoration: none;\n  outline: none;\n}\n\n.linkToRepo:hover {\n  text-decoration: underline;\n}\n\n@media (max-width: 550px) {\n  .reactour__helper.helper {\n    width: 320px;\n    font-size: 0.9rem;\n    line-height: 1.1rem;\n  }\n}\n\n@media (max-width: 440px) {\n  .reactour__helper.helper {\n    width: 280px;\n    font-size: 0.8rem;\n    line-height: 1rem;\n  }\n  span[data-tour-elem=\"badge\"] {\n    line-height: 2.5;\n  }\n  div[data-tour-elem=\"controls\"] {\n    flex-wrap: wrap;\n    justify-content: center;\n  }\n  div[data-tour-elem=\"controls\"] > nav {\n    width: 100%;\n    margin-bottom: 10px;\n  }\n  button[data-tour-elem=\"left-arrow\"] {\n    margin-left: unset;\n  }\n}\n\n"
  },
  {
    "path": "src/components/TourGuide/styled.ts",
    "content": "import styled from 'styled-components';\nimport { MAIN1_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { TextSemiBold, GeneralAdaptiveFont, GeneralButtonPadding } from 'typography';\n\nexport const LinkButton = styled.a`\n  ${TextSemiBold};\n  margin-right: 0;\n  border-radius: 20px;\n  border: none;\n  text-decoration: none;\n  outline: none;\n  cursor: pointer;\n  background-color: ${MAIN1_COLOR};\n  color: ${WHITE_COLOR};\n  ${GeneralAdaptiveFont};\n  ${GeneralButtonPadding}\n`;\n"
  },
  {
    "path": "src/components/TourGuide/tourConfig.tsx",
    "content": "import { Button, InvertedButton, ButtonsBlock } from 'typography';\nimport { setIsTourOpen } from 'modules/LoginPage/loginPageReducer';\nimport { LINK_TO_REPO } from 'appConstants';\nimport { LinkButton } from './styled';\nimport { Dispatch } from 'redux';\nimport { History, LocationState } from 'history';\n\nexport const tourConfig = (\n  history: History<LocationState>,\n  dispatch: Dispatch,\n  t: (text: string) => string\n) => [\n  {\n    content: ({ goTo }: { goTo: (step: number) => void }) => (\n      <div>\n        <p>{t('Welcome to RSS Teams')}</p>\n        <ButtonsBlock>\n          <InvertedButton onClick={() => goTo(9)}>{t('Skip')}</InvertedButton>\n          <Button onClick={() => goTo(1)}>{t('Next')}</Button>\n        </ButtonsBlock>\n      </div>\n    ),\n    action: () => history.push('/'),\n  },\n  {\n    selector: '.secondStep',\n    content: t('You can create new team'),\n    action: () => history.push('/'),\n  },\n  {\n    selector: '.thirdStep',\n    content: t('Or join existing team'),\n    action: () => history.push('/'),\n  },\n  {\n    selector: '.fourthStep',\n    content: t('You can always leave the course'),\n    action: () => history.push('/'),\n  },\n  {\n    content: t('On Teams page you can see other teams'),\n    action: () => history.push('/'),\n  },\n  {\n    content: t('On Dashboard page'),\n    action: () => history.push('/students'),\n  },\n  {\n    selector: '.seventhStep',\n    content: t('With filter usage'),\n    position: 'bottom',\n    action: () => history.push('/students'),\n  },\n  {\n    selector: '.eighthStep',\n    content: t('With dropdown you can switch the course'),\n    position: 'bottom',\n    action: () => history.push('/students'),\n  },\n  {\n    content: t('On Edit profile page'),\n    action: () => history.push('/edit-profile'),\n  },\n  {\n    content: t('If you forget something'),\n    action: () => history.push('/tutorial'),\n  },\n  {\n    content: () => (\n      <div>\n        <p>\n          {t('Support us')}{' '}\n          <a href={LINK_TO_REPO} className=\"linkToRepo\" target=\"_blank\" rel=\"noreferrer\">\n            {t('our repo')}\n          </a>\n          !\n        </p>\n        <ButtonsBlock>\n          <LinkButton\n            onClick={() => {\n              dispatch(setIsTourOpen(false));\n            }}\n            href={LINK_TO_REPO}\n            target=\"_blank\"\n            rel=\"noreferrer\"\n          >\n            {t('Got it')}\n          </LinkButton>\n        </ButtonsBlock>\n      </div>\n    ),\n    action: () => history.push('/'),\n  },\n];\n"
  },
  {
    "path": "src/components/index.ts",
    "content": "export { App } from './App';\nexport { Loader } from './Loader';\nexport { PrivateRoute } from './PrivateRoute';\nexport { Header } from './Header';\nexport { InputField } from './InputField';\nexport { CourseField } from './CourseField';\nexport { Pagination } from './Pagination';\nexport { Modal } from './Modal';\nexport { ModalExpel } from './ModalExpel';\nexport { ModalJoin } from './ModalJoin';\nexport { ModalCreateEditTeam } from './ModalCreateEditTeam';\nexport { ModalCreated } from './ModalCreated';\nexport { TablePopup } from './TablePopup';\nexport { FilterForm } from './FilterForm';\nexport { FilterSelect } from './FilterSelect';\nexport { Footer } from './Footer';\nexport { ErrorModal } from './ErrorModal';\nexport { CommonSelectList } from './CommonSelectList';\nexport { TourGuide } from './TourGuide';\nexport { ModalEditCourse } from './ModalEditCourse';\n"
  },
  {
    "path": "src/graphql/mutations/addUserToTeamMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const ADD_USER_TO_TEAM_MUTATION = gql`\n  mutation addUserToTeam($data: AddUserToTeamInput!) {\n    addUserToTeam(data: $data) {\n      id\n      firstName\n      lastName\n      github\n      telegram\n      discord\n      score\n      country\n      city\n      isAdmin\n      courses {\n        id\n        name\n      }\n      teams {\n        id\n        password\n        number\n        courseId\n        socialLink\n        members {\n          id\n          firstName\n          lastName\n          github\n          telegram\n          discord\n          score\n          country\n          city\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/createCourseMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const CREATE_COURSE_MUTATION = gql`\n  mutation createCourse($course: CreateCourseInput!) {\n    createCourse(course: $course) {\n      id\n      name\n      teamSize\n      isActive\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/createTeamMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const CREATE_TEAM_MUTATION = gql`\n  mutation createTeam($team: CreateTeamInput!) {\n    createTeam(team: $team) {\n      id\n      password\n      number\n      courseId\n      socialLink\n      memberIds\n      members {\n        id\n        firstName\n        lastName\n        github\n        telegram\n        discord\n        score\n        country\n        city\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/index.ts",
    "content": "export { UPD_USER_MUTATION } from './updUserMutation';\nexport { ADD_USER_TO_TEAM_MUTATION } from './addUserToTeamMutation';\nexport { REMOVE_USER_FROM_TEAM_MUTATION } from './removeUserFromTeamMutation';\nexport { CREATE_TEAM_MUTATION } from './createTeamMutation';\nexport { UPDATE_TEAM_MUTATION } from './updateTeamMutation';\nexport { SORT_STUDENTS_MUTATION } from './sortStudentsMutation';\nexport { REMOVE_USER_FROM_COURSE_MUTATION } from './removeUserFromCourseMutation';\nexport { CREATE_COURSE_MUTATION } from './createCourseMutation';\nexport { UPDATE_COURSE_MUTATION } from './updateCourseMutation';\n"
  },
  {
    "path": "src/graphql/mutations/removeUserFromCourseMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const REMOVE_USER_FROM_COURSE_MUTATION = gql`\n  mutation removeUserFromCourse($data: RemoveUserFromCourseInput!) {\n    removeUserFromCourse(data: $data) {\n      id\n      firstName\n      lastName\n      github\n      telegram\n      discord\n      score\n      country\n      city\n      isAdmin\n      courses {\n        id\n        name\n      }\n      teams {\n        id\n        password\n        number\n        courseId\n        socialLink\n        members {\n          id\n          firstName\n          lastName\n          github\n          telegram\n          discord\n          score\n          country\n          city\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/removeUserFromTeamMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const REMOVE_USER_FROM_TEAM_MUTATION = gql`\n  mutation removeUserFromTeam($data: RemoveUserFromTeamInput!) {\n    removeUserFromTeam(data: $data) {\n      id\n      firstName\n      lastName\n      github\n      telegram\n      discord\n      score\n      country\n      city\n      avatar\n      isAdmin\n      courses {\n        id\n        name\n      }\n      email\n      courseIds\n      teamIds\n      teams {\n        id\n        password\n        number\n        courseId\n        socialLink\n        memberIds\n        members {\n          id\n          firstName\n          lastName\n          github\n          telegram\n          discord\n          score\n          country\n          city\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/sortStudentsMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const SORT_STUDENTS_MUTATION = gql`\n  mutation sortStudents($courseId: String!) {\n    sortStudents(courseId: $courseId)\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/updUserMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const UPD_USER_MUTATION = gql`\n  mutation updateUser($user: UpdateUserInput!) {\n    updateUser(user: $user) {\n      id\n      firstName\n      lastName\n      github\n      telegram\n      discord\n      score\n      country\n      city\n      isAdmin\n      courses {\n        id\n        name\n      }\n      teams {\n        id\n        password\n        number\n        courseId\n        socialLink\n        members {\n          id\n          firstName\n          lastName\n          github\n          telegram\n          discord\n          score\n          country\n          city\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/updateCourseMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const UPDATE_COURSE_MUTATION = gql`\n  mutation updateCourse($course: UpdateCourseInput!) {\n    updateCourse(course: $course) {\n      id\n      name\n      teamSize\n      isActive\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/mutations/updateTeamMutation.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const UPDATE_TEAM_MUTATION = gql`\n  mutation updateTeam($team: UpdateTeamInput!) {\n    updateTeam(team: $team) {\n      id\n      password\n      number\n      courseId\n      socialLink\n      memberIds\n      members {\n        id\n        firstName\n        lastName\n        github\n        telegram\n        discord\n        score\n        country\n        city\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/queries/coursesQuery.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const COURSES_QUERY = gql`\n  query getCourses {\n    courses {\n      id\n      name\n      teamSize\n      isActive\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/queries/index.ts",
    "content": "export { TEAMS_QUERY } from './teamsQuery';\nexport { USERS_QUERY } from './usersQuery';\n// export { USER_QUERY } from './userQuery';\nexport { WHOAMI_QUERY } from './whoAmIQuery';\nexport { COURSES_QUERY } from './coursesQuery';\n"
  },
  {
    "path": "src/graphql/queries/teamsQuery.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const TEAMS_QUERY = gql`\n  query getTeams($courseId: String!, $pagination: PaginationInput!) {\n    teams(courseId: $courseId, pagination: $pagination) {\n      count\n      results {\n        id\n        number\n        courseId\n        socialLink\n        members {\n          id\n          firstName\n          lastName\n          github\n          telegram\n          discord\n          score\n          country\n          city\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/queries/usersQuery.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const USERS_QUERY = gql`\n  query getUsers($courseId: String!, $pagination: PaginationInput!, $filter: UserFilterInput) {\n    users(courseId: $courseId, pagination: $pagination, filter: $filter) {\n      count\n      results {\n        id\n        firstName\n        lastName\n        github\n        telegram\n        discord\n        score\n        country\n        city\n        isAdmin\n        courses {\n          id\n          name\n        }\n        teams {\n          id\n          number\n          courseId\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/graphql/queries/whoAmIQuery.ts",
    "content": "import { gql } from '@apollo/client';\n\nexport const WHOAMI_QUERY = gql`\n  query getWhoAMi {\n    whoAmI {\n      id\n      firstName\n      lastName\n      github\n      telegram\n      discord\n      score\n      country\n      city\n      isAdmin\n      courses {\n        id\n        name\n      }\n      teams {\n        id\n        password\n        number\n        courseId\n        socialLink\n        members {\n          id\n          firstName\n          lastName\n          github\n          telegram\n          discord\n          score\n          country\n          city\n        }\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "src/hooks/graphql/index.ts",
    "content": "export { useTeamsQuery } from './queries/useTeamsQuery';\nexport { useUsersQuery } from './queries/useUsersQuery';\nexport { useWhoAmIQuery } from './queries/useWhoAmIQuery';\nexport { useCoursesQuery } from './queries/useCoursesQuery';\nexport { useUpdUserMutation } from './mutations/useUpdUserMutation';\nexport { useRemoveUserFromTeamMutation } from './mutations/useRemoveUserFromTeamMutation';\nexport { useExpelUserFromTeamMutation } from './mutations/useExpelUserFromTeamMutation';\nexport { useCreateTeamMutation } from './mutations/useCreateTeamMutation';\nexport { useAddUserToTeamMutation } from './mutations/useAddUserToTeamMutation';\nexport { useUpdateTeamMutation } from './mutations/useUpdateTeamMutation';\nexport { useSortStudentsMutation } from './mutations/useSortStudentsMutation';\nexport { useRemoveUserFromCourseMutation } from './mutations/useRemoveUserFromCourseMutation';\nexport { useCreateCourseMutation } from './mutations/useCreateCourseMutation';\nexport { useUpdateCourseMutation } from './mutations/useUpdateCourseMutation';\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useAddUserToTeamMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { ADD_USER_TO_TEAM_MUTATION } from 'graphql/mutations';\nimport { WHOAMI_QUERY } from 'graphql/queries';\nimport { AddUserToTeamInput } from 'types';\n\ntype Props = {\n  data: AddUserToTeamInput;\n};\n\nexport const useAddUserToTeamMutation = ({ data }: Props) => {\n  const [addUserToTeam, { loading, error }] = useMutation(ADD_USER_TO_TEAM_MUTATION, {\n    variables: {\n      data,\n    },\n\n    update(cache, { data: { addUserToTeam } }) {\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          addUserToTeam,\n        },\n      });\n    },\n  });\n  return {\n    addUserToTeam,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useCreateCourseMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { Course, CreateCourseInput } from 'types';\nimport { COURSES_QUERY } from 'graphql/queries';\nimport { CREATE_COURSE_MUTATION } from 'graphql/mutations';\n\ntype Props = {\n  course: CreateCourseInput;\n};\n\nexport const useCreateCourseMutation = ({ course }: Props) => {\n  const [createCourse, { loading, error }] = useMutation(CREATE_COURSE_MUTATION, {\n    variables: {\n      course,\n    },\n\n    update(cache, { data: { createCourse } }) {\n      const data: { courses: Course[] } | null = cache.readQuery({\n        query: COURSES_QUERY,\n      });\n\n      const updatedResults = data?.courses?.length\n        ? [createCourse, ...data?.courses]\n        : [createCourse];\n\n      cache.writeQuery({\n        query: COURSES_QUERY,\n        data: {\n          courses: updatedResults,\n        },\n      });\n    },\n  });\n  return {\n    createCourse,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useCreateTeamMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { CreateTeamInput, TeamList, User } from 'types';\nimport { TEAMS_QUERY, WHOAMI_QUERY } from 'graphql/queries';\nimport { CREATE_TEAM_MUTATION } from 'graphql/mutations';\nimport { TEAMS_PER_PAGE } from 'appConstants';\n\ntype Props = {\n  team: CreateTeamInput;\n};\n\nexport const useCreateTeamMutation = ({ team }: Props) => {\n  const { courseId, ownerId, socialLink, page } = team;\n  const dataForMutation = { courseId, ownerId, socialLink };\n  const [createTeam, { loading, error }] = useMutation(CREATE_TEAM_MUTATION, {\n    variables: {\n      team: dataForMutation,\n    },\n\n    update(cache, { data: { createTeam } }) {\n      const data: { teams: TeamList } | null = cache.readQuery({\n        query: TEAMS_QUERY,\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n      const userData: { whoAmI: User } | null = cache.readQuery({\n        query: WHOAMI_QUERY,\n      });\n\n      const updatedResults = data?.teams?.results.length\n        ? [...data?.teams?.results, createTeam]\n        : [createTeam];\n\n      const updatedUser = {\n        ...userData?.whoAmI,\n        teams: userData?.whoAmI?.teams.length\n          ? [...userData?.whoAmI?.teams, createTeam]\n          : [createTeam],\n      };\n\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          whoAmI: updatedUser,\n        },\n      });\n\n      cache.writeQuery({\n        query: TEAMS_QUERY,\n        data: {\n          teams: {\n            count: updatedResults.length,\n            results: updatedResults,\n          },\n        },\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n    },\n  });\n  return {\n    createTeam,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useExpelUserFromTeamMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { RemoveUserFromTeamInput, Team, TeamList, User } from 'types';\nimport { TEAMS_QUERY, WHOAMI_QUERY } from 'graphql/queries';\nimport { REMOVE_USER_FROM_TEAM_MUTATION } from 'graphql/mutations';\nimport { TEAMS_PER_PAGE } from 'appConstants';\n\ntype Props = {\n  data: RemoveUserFromTeamInput;\n};\n\nexport const useExpelUserFromTeamMutation = ({ data }: Props) => {\n  const { teamId, page, userId, courseId } = data;\n  const dataForMutation = { userId, teamId };\n  const [expelUserFromTeam, { loading, error }] = useMutation(REMOVE_USER_FROM_TEAM_MUTATION, {\n    variables: {\n      data: dataForMutation,\n    },\n\n    update(cache, { data: {} }) {\n      const data: { teams: TeamList } | null = cache.readQuery({\n        query: TEAMS_QUERY,\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n\n      const userData: { whoAmI: User } | null = cache.readQuery({\n        query: WHOAMI_QUERY,\n      });\n\n      const updatedRemovedResults = data?.teams.results.map((team: Team) => {\n        if (team.id === teamId) {\n          return {\n            ...team,\n            members: team.members.filter((member: User) => member.id !== userId),\n          };\n        }\n        return team;\n      });\n\n      const updatedTeams = (userData?.whoAmI.teams as Team[]).map((team: Team) => {\n        if (team.id === teamId) {\n          return {\n            ...team,\n            members: team.members.filter((member: User) => member.id !== userId),\n          };\n        }\n        return team;\n      });\n\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          ...userData?.whoAmI,\n          teams: updatedTeams,\n        },\n      });\n\n      cache.writeQuery({\n        query: TEAMS_QUERY,\n        data: {\n          teams: {\n            count: data?.teams?.count,\n            results: updatedRemovedResults,\n          },\n        },\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n    },\n  });\n  return {\n    expelUserFromTeam,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useRemoveUserFromCourseMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { CURRENT_COURSE, TEAMS_PER_PAGE } from 'appConstants';\nimport { REMOVE_USER_FROM_COURSE_MUTATION } from 'graphql/mutations';\nimport { TEAMS_QUERY, WHOAMI_QUERY } from 'graphql/queries';\nimport { setCourse } from 'modules/LoginPage/loginPageMiddleware';\nimport { setCommonError, setCurrCourse } from 'modules/LoginPage/loginPageReducer';\nimport { setUserData } from 'modules/StudentsTable/studentsTableReducer';\nimport { useDispatch } from 'react-redux';\nimport { RemoveUserFromCourseInput, Team, TeamList, User } from 'types';\n\ntype Props = {\n  data: RemoveUserFromCourseInput;\n};\n\nexport const useRemoveUserFromCourseMutation = ({\n  data: { page, courseId, userId, teamId },\n}: Props) => {\n  const dataForMutation = { courseId, userId, teamId };\n  const dispatch = useDispatch();\n  const [removeUserFromCourse, { loading, error }] = useMutation(REMOVE_USER_FROM_COURSE_MUTATION, {\n    variables: {\n      data: dataForMutation,\n    },\n\n    update(cache, { data: { removeUserFromCourse } }) {\n      const data: { teams: TeamList } | null = cache.readQuery({\n        query: TEAMS_QUERY,\n        variables: {\n          courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n\n      const updatedRemovedResults = data?.teams.results\n        .map((team: Team) => {\n          if (team.id === teamId) {\n            if (team.members.length === 1) {\n              return null;\n            }\n            return {\n              ...team,\n              members: team.members.filter((member: User) => member.id !== userId),\n            };\n          }\n          return team;\n        })\n        .filter((team: Team | null) => !!team);\n\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          removeUserFromCourse,\n        },\n      });\n\n      cache.writeQuery({\n        query: TEAMS_QUERY,\n        data: {\n          teams: {\n            count: data?.teams?.count,\n            results: updatedRemovedResults,\n          },\n        },\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n    },\n\n    onCompleted({ removeUserFromCourse }) {\n      if (!!removeUserFromCourse.courses[0]) {\n        dispatch(setCourse(removeUserFromCourse.courses[0]));\n      } else {\n        dispatch(setCurrCourse({ name: '', id: '' }));\n        localStorage.removeItem(CURRENT_COURSE);\n      }\n      dispatch(setUserData(removeUserFromCourse));\n    },\n    onError() {\n      dispatch(setCommonError(true));\n    },\n  });\n  return {\n    removeUserFromCourse,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useRemoveUserFromTeamMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { RemoveUserFromTeamInput, Team, TeamList, User } from 'types';\nimport { TEAMS_QUERY, WHOAMI_QUERY } from 'graphql/queries';\nimport { REMOVE_USER_FROM_TEAM_MUTATION } from 'graphql/mutations';\nimport { TEAMS_PER_PAGE } from 'appConstants';\n\ntype Props = {\n  data: RemoveUserFromTeamInput;\n};\n\nexport const useRemoveUserFromTeamMutation = ({ data }: Props) => {\n  const { teamId, page, userId, courseId } = data;\n  const dataForMutation = { userId, teamId };\n  const [removeUserFromTeam, { loading, error }] = useMutation(REMOVE_USER_FROM_TEAM_MUTATION, {\n    variables: {\n      data: dataForMutation,\n    },\n\n    update(cache, { data: { removeUserFromTeam } }) {\n      const data: { teams: TeamList } | null = cache.readQuery({\n        query: TEAMS_QUERY,\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n\n      const updatedRemovedResults = data?.teams.results\n        .map((team: Team) => {\n          if (team.id === teamId) {\n            return {\n              ...team,\n              members: team.members.filter((member: User) => member.id !== userId),\n            };\n          }\n          return team;\n        })\n        .filter((team: Team | undefined) => !!team?.members.length);\n\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          removeUserFromTeam,\n        },\n      });\n\n      cache.writeQuery({\n        query: TEAMS_QUERY,\n        data: {\n          teams: {\n            count: updatedRemovedResults?.length,\n            results: updatedRemovedResults,\n          },\n        },\n        variables: {\n          courseId: courseId,\n          pagination: { skip: page * TEAMS_PER_PAGE, take: TEAMS_PER_PAGE },\n        },\n      });\n    },\n  });\n  return {\n    removeUserFromTeam,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useSortStudentsMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { SORT_STUDENTS_MUTATION } from 'graphql/mutations';\n\ntype Props = {\n  courseId: string;\n};\n\nexport const useSortStudentsMutation = ({ courseId }: Props) => {\n  const [sortStudents, { loading, error }] = useMutation(SORT_STUDENTS_MUTATION, {\n    variables: {\n      courseId,\n    },\n  });\n  return {\n    sortStudents,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useUpdUserMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { UPD_USER_MUTATION } from 'graphql/mutations';\nimport { WHOAMI_QUERY } from 'graphql/queries';\nimport { UpdateUserInput } from 'types';\n\ntype Props = {\n  user: UpdateUserInput;\n};\n\nexport const useUpdUserMutation = ({ user }: Props) => {\n  const formattedUser = { ...user, score: Number(user.score) };\n  const [updateUser, { loading, error }] = useMutation(UPD_USER_MUTATION, {\n    variables: {\n      user: formattedUser,\n    },\n    update(cache, { data: { updateUser } }) {\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          updateUser,\n        },\n      });\n    },\n  });\n  return {\n    updateUser,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useUpdateCourseMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { UpdateCourseInput, Course } from 'types';\nimport { COURSES_QUERY } from 'graphql/queries';\nimport { UPDATE_COURSE_MUTATION } from 'graphql/mutations';\n\ntype Props = {\n  course: UpdateCourseInput;\n};\n\nexport const useUpdateCourseMutation = ({ course }: Props) => {\n  const { id } = course;\n  const [updateCourse, { loading, error }] = useMutation(UPDATE_COURSE_MUTATION, {\n    variables: {\n      course,\n    },\n\n    update(cache, { data: { updateCourse } }) {\n      const data: { courses: Course[] } | null = cache.readQuery({\n        query: COURSES_QUERY,\n      });\n\n      const updatedResults = data?.courses?.map((course: Course) => {\n        if (course.id === id) {\n          return updateCourse;\n        }\n        return course;\n      });\n\n      cache.writeQuery({\n        query: COURSES_QUERY,\n        data: {\n          courses: updatedResults,\n        },\n      });\n    },\n  });\n  return {\n    updateCourse,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/mutations/useUpdateTeamMutation.ts",
    "content": "import { useMutation } from '@apollo/client';\nimport { UpdateTeamInput, User, Team } from 'types';\nimport { WHOAMI_QUERY } from 'graphql/queries';\nimport { UPDATE_TEAM_MUTATION } from 'graphql/mutations';\n\ntype Props = {\n  team: UpdateTeamInput;\n};\n\nexport const useUpdateTeamMutation = ({ team }: Props) => {\n  const { id } = team;\n  const [updateTeam, { loading, error }] = useMutation(UPDATE_TEAM_MUTATION, {\n    variables: {\n      team,\n    },\n\n    update(cache, { data: { updateTeam } }) {\n      const userData: { whoAmI: User } | null = cache.readQuery({\n        query: WHOAMI_QUERY,\n      });\n\n      const updatedUserTeam = (userData?.whoAmI.teams as Team[]).map((team: Team) => {\n        if (team.id === id) {\n          return updateTeam;\n        }\n        return team;\n      });\n\n      cache.writeQuery({\n        query: WHOAMI_QUERY,\n        data: {\n          whoAmI: {\n            ...userData?.whoAmI,\n            teams: updatedUserTeam,\n          },\n        },\n      });\n    },\n  });\n  return {\n    updateTeam,\n    loadingM: loading,\n    errorM: error,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/queries/useCoursesQuery.ts",
    "content": "import { useQuery } from '@apollo/client';\n\nimport { COURSES_QUERY } from 'graphql/queries';\n\nexport const useCoursesQuery = () => {\n  const { data, loading, error } = useQuery(COURSES_QUERY);\n  const isLoaded = !loading && data?.courses;\n\n  return {\n    loading: !isLoaded,\n    error,\n    courses: data?.courses,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/queries/useTeamsQuery.ts",
    "content": "import { useQuery } from '@apollo/client';\nimport { TEAMS_PER_PAGE } from 'appConstants';\n\nimport { TEAMS_QUERY } from 'graphql/queries';\ntype Props = {\n  reactCourseId: string;\n  skip?: boolean;\n  page?: number;\n};\n\nexport const useTeamsQuery = ({ reactCourseId, skip = false, page = 0 }: Props) => {\n  const { data, loading, error } = useQuery(TEAMS_QUERY, {\n    skip,\n    variables: {\n      courseId: reactCourseId,\n      pagination: {\n        skip: page * TEAMS_PER_PAGE,\n        take: TEAMS_PER_PAGE,\n      },\n    },\n  });\n  const isLoaded = !loading && !!data;\n  return {\n    loadingT: !isLoaded,\n    errorT: error,\n    teams: data?.teams,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/queries/useUsersQuery.ts",
    "content": "import { useQuery } from '@apollo/client';\nimport { USERS_PER_PAGE } from 'appConstants';\n\nimport { USERS_QUERY } from 'graphql/queries';\nimport { UserFilterInput } from 'types';\n\ntype Props = {\n  reactCourseId: string;\n  skip?: boolean;\n  page?: number;\n  filter?: UserFilterInput;\n};\n\nexport const useUsersQuery = ({ reactCourseId, skip = false, page = 0, filter }: Props) => {\n  const { data, loading, error } = useQuery(USERS_QUERY, {\n    skip,\n    variables: {\n      filter,\n      courseId: reactCourseId,\n      pagination: {\n        skip: page * USERS_PER_PAGE,\n        take: USERS_PER_PAGE,\n      },\n    },\n  });\n  const isLoaded = !loading && !!data;\n\n  return {\n    loadingU: !isLoaded,\n    errorU: error,\n    users: data?.users,\n  };\n};\n"
  },
  {
    "path": "src/hooks/graphql/queries/useWhoAmIQuery.ts",
    "content": "import { useQuery } from '@apollo/client';\nimport { WHOAMI_QUERY } from 'graphql/queries';\n\ntype Props = {\n  skip: boolean;\n};\n\nexport const useWhoAmIQuery = ({ skip = false }: Props) => {\n  const {\n    data,\n    loading: loadingW,\n    error,\n  } = useQuery(WHOAMI_QUERY, {\n    skip,\n  });\n\n  return {\n    loadingW,\n    errorW: error,\n    whoAmI: data?.whoAmI,\n  };\n};\n"
  },
  {
    "path": "src/index.tsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { BrowserRouter as Router } from 'react-router-dom';\nimport { AppState } from 'store';\nimport { ApolloProvider, ApolloClient, createHttpLink, InMemoryCache, from } from '@apollo/client';\nimport { setContext } from '@apollo/client/link/context';\nimport { App } from './components';\nimport { AUTH_TOKEN, BACKEND_LINK, UNAUTHORIZED_ERROR_MESSAGE } from 'appConstants';\nimport reportWebVitals from './reportWebVitals';\nimport 'typography/normalize.css';\nimport 'typography/fonts.css';\nimport 'typography/common.css';\nimport './translation/resources';\nimport ErrorBoundary from 'components/ErrorBoundary';\nimport { onError } from '@apollo/client/link/error';\n\nconst httpLink = createHttpLink({\n  uri: BACKEND_LINK,\n});\n\nconst unauthorizedLink = onError(({ graphQLErrors }) => {\n  const isUserUnauthorized = !!graphQLErrors?.find(\n    ({ message }) => message === UNAUTHORIZED_ERROR_MESSAGE\n  );\n\n  if (isUserUnauthorized) {\n    location.reload();\n    sessionStorage.removeItem(AUTH_TOKEN);\n  }\n});\n\nconst authLink = setContext((_, { headers }) => {\n  const token = sessionStorage.getItem(AUTH_TOKEN);\n  return {\n    headers: {\n      ...headers,\n      authorization: token ? `Bearer ${token}` : '',\n    },\n  };\n});\n\nconst client = new ApolloClient({\n  link: from([unauthorizedLink, authLink, httpLink]),\n  cache: new InMemoryCache({\n    typePolicies: {\n      User: {\n        fields: {\n          teams: {\n            merge(_, incoming) {\n              return incoming;\n            },\n          },\n          courses: {\n            merge(_, incoming) {\n              return incoming;\n            },\n          },\n        },\n      },\n      Team: {\n        fields: {\n          members: {\n            merge(_, incoming) {\n              return incoming;\n            },\n          },\n        },\n      },\n      Query: {\n        fields: {\n          teams: {\n            merge(_, incoming) {\n              return incoming;\n            },\n          },\n        },\n      },\n    },\n  }),\n  connectToDevTools: true,\n});\n\nReactDOM.render(\n  <ErrorBoundary>\n    <ApolloProvider client={client}>\n      <Router>\n        <AppState>\n          <App />\n        </AppState>\n      </Router>\n    </ApolloProvider>\n  </ErrorBoundary>,\n  document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/AddCourseBlock/components/InputsBlock/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { ModalInput, Label } from 'typography';\nimport { ValidationAlert } from 'components/InputField/styled';\nimport { InputWrapper, FieldWrapper } from './styled';\n\ninterface InputBlockProps {\n  inputLabel: string;\n  value: string;\n  placeholder: string;\n  onChangeHandler: (e: React.ChangeEvent<HTMLInputElement>) => void;\n  isFieldValid: boolean;\n  errorMessage: string;\n  isModal?: boolean;\n}\n\nexport const InputBlock: FC<InputBlockProps> = ({\n  inputLabel,\n  value,\n  placeholder,\n  onChangeHandler,\n  isFieldValid,\n  errorMessage,\n  isModal,\n}) => {\n  const { t } = useTranslation();\n\n  return (\n    <InputWrapper isModal={isModal}>\n      <Label marginBottom=\"0px\">{t(inputLabel)}</Label>\n      <FieldWrapper>\n        <ModalInput\n          name=\"inputValue\"\n          required\n          value={value}\n          mt=\"0px\"\n          autoComplete={'off'}\n          onChange={onChangeHandler}\n          placeholder={t(placeholder)}\n        />\n        {!isFieldValid && <ValidationAlert>{t(errorMessage)}</ValidationAlert>}\n      </FieldWrapper>\n    </InputWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/AddCourseBlock/components/InputsBlock/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const InputWrapper = styled.div<{ isModal?: boolean }>`\n  display: flex;\n  ${({ isModal }) => isModal && 'flex-direction: column;'}\n  justify-content: space-between;\n  align-items: center;\n  width: 100%;\n  height: fit-content;\n  ${({ isModal }) => isModal && 'margin-bottom: 40px;'}\n  gap: ${({ isModal }) => (isModal ? '5px' : '20px')};\n\n  @media (max-width: 580px) {\n    ${({ isModal }) => isModal && 'margin-bottom: 30px;'}\n    label {\n      ${({ isModal }) => !isModal && 'display: none;'}\n    }\n  }\n`;\n\nexport const FieldWrapper = styled.div`\n  position: relative;\n  display: flex;\n  flex-direction: column;\n\n  & > div:nth-child(2) {\n    position: absolute;\n    top: 100%;\n  }\n`;\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/AddCourseBlock/index.tsx",
    "content": "import React, { FC, useCallback, useState } from 'react';\nimport { MAIN2_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { useTranslation } from 'react-i18next';\nimport { TeamButton } from 'typography';\nimport { InputBlock } from './components/InputsBlock';\nimport { AddCourseBlockWrapper, InputsBlockWrapper } from './styled';\nimport { isFieldValid } from 'utils/isFieldValid';\nimport { COURSE_NAME_VALIDATION, TEAM_SIZE_VALIDATION } from 'appConstants';\nimport { useCreateCourseMutation } from 'hooks/graphql';\nimport { ErrorModal, Modal } from 'components';\nimport { activeModalCreatedCourse } from 'modules/TeamsList/teamsListReducer';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { selectIsActiveModalCreatedCourse } from 'modules/TeamsList/selectors';\n\nexport const onChangeField =\n  (\n    validateRules: any,\n    setInputValid: (isValid: boolean) => void,\n    setErrorMessage: (errorMessage: string) => void,\n    setInputValue: (value: string) => void,\n    isValueUniq?: (value: string) => boolean\n  ) =>\n  (e: React.ChangeEvent<HTMLInputElement>) => {\n    isFieldValid(\n      e.target.value.trim(),\n      validateRules,\n      !!validateRules,\n      setInputValid,\n      setErrorMessage,\n      isValueUniq\n    );\n    setInputValue(e.target.value);\n  };\n\nexport const AddCourseBlock: FC<{ checkIsCourseNameUniq: (courseName: string) => boolean }> = ({\n  checkIsCourseNameUniq,\n}) => {\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n  const isActiveModalCreatedCourse = useSelector(selectIsActiveModalCreatedCourse);\n  const [isCourseNameFieldValid, setIsCourseNameFieldValid] = useState(true);\n  const [isTeamSizeFieldValid, setIsTeamSizeFieldValid] = useState(true);\n  const [courseName, setCourseName] = useState('');\n  const [teamSize, setTeamSize] = useState('');\n  const [courseNameErrorMessage, setCourseNameErrorMessage] = useState('');\n  const [teamSizeErrorMessage, setTeamSizeErrorMessage] = useState('');\n\n  const { createCourse, errorM: errorCreateCourse } = useCreateCourseMutation({\n    course: {\n      name: courseName,\n      teamSize: +teamSize,\n      isActive: true,\n    },\n  });\n\n  const onAddNewCourse = useCallback(() => {\n    if (isCourseNameFieldValid && isTeamSizeFieldValid) {\n      if (courseName && teamSize) {\n        createCourse().then(() => {\n          dispatch(activeModalCreatedCourse(true));\n        });\n      } else {\n        if (!courseName) {\n          setIsCourseNameFieldValid(false);\n          setCourseNameErrorMessage(COURSE_NAME_VALIDATION.minLength.message);\n        }\n        if (!teamSize) {\n          setIsTeamSizeFieldValid(false);\n          setTeamSizeErrorMessage(TEAM_SIZE_VALIDATION.minLength.message);\n        }\n      }\n    }\n  }, [isCourseNameFieldValid, isTeamSizeFieldValid, courseName, teamSize, createCourse, dispatch]);\n\n  if (errorCreateCourse) return <ErrorModal error={errorCreateCourse} />;\n\n  return (\n    <>\n      <AddCourseBlockWrapper>\n        <InputsBlockWrapper>\n          <InputBlock\n            inputLabel=\"Course name\"\n            value={courseName}\n            placeholder=\"Enter course name\"\n            onChangeHandler={onChangeField(\n              COURSE_NAME_VALIDATION,\n              setIsCourseNameFieldValid,\n              setCourseNameErrorMessage,\n              setCourseName,\n              checkIsCourseNameUniq\n            )}\n            isFieldValid={isCourseNameFieldValid}\n            errorMessage={courseNameErrorMessage}\n          />\n          <InputBlock\n            inputLabel=\"Team size\"\n            value={teamSize}\n            placeholder=\"Enter team size\"\n            onChangeHandler={onChangeField(\n              TEAM_SIZE_VALIDATION,\n              setIsTeamSizeFieldValid,\n              setTeamSizeErrorMessage,\n              setTeamSize\n            )}\n            isFieldValid={isTeamSizeFieldValid}\n            errorMessage={teamSizeErrorMessage}\n          />\n        </InputsBlockWrapper>\n        <TeamButton bgc={MAIN2_COLOR} color={WHITE_COLOR} type=\"button\" onClick={onAddNewCourse}>\n          {t('Add new course')}\n        </TeamButton>\n      </AddCourseBlockWrapper>\n      <Modal\n        title=\"Course was created\"\n        text=\"If you want to change something in new course\"\n        onClose={() => {\n          setCourseName('');\n          setTeamSize('');\n          dispatch(activeModalCreatedCourse(false));\n        }}\n        cancelText=\"Got it!\"\n        open={isActiveModalCreatedCourse}\n        hideOnOutsideClick\n        hideOnEsc\n      ></Modal>\n    </>\n  );\n};\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/AddCourseBlock/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const AddCourseBlockWrapper = styled.div`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  height: 250px;\n  gap: 4%;\n\n  @media (max-width: 850px) {\n    flex-direction: column;\n  }\n`;\n\nexport const InputsBlockWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  width: fit-content;\n  height: fit-content;\n  gap: 20px;\n\n  @media (max-width: 850px) {\n    margin-bottom: 30px;\n  }\n`;\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/CoursesList/components/Course/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useDispatch } from 'react-redux';\nimport { CourseButton } from 'typography';\nimport { CourseWrapper } from './styled';\nimport { activeModalEditCourse, activeModalSortStudents } from 'modules/TeamsList/teamsListReducer';\nimport { Course } from 'types';\n\ninterface ICourseItem {\n  index: number;\n  id: string;\n  name: string;\n  teamSize: number | null;\n  isActive: boolean;\n  setCourseInfoToSort: (course: Partial<Course>) => void;\n  setCourseEditMeta: (course: Course | null) => void;\n}\n\nexport const CourseItem: FC<ICourseItem> = ({\n  index,\n  id,\n  name,\n  teamSize,\n  isActive,\n  setCourseInfoToSort,\n  setCourseEditMeta,\n}) => {\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n  const courseOrder = index + 1;\n  const courseState = isActive ? 'Active(status)' : 'Terminate(status)';\n\n  const onClickSortStudents = () => {\n    setCourseInfoToSort({ id, name });\n    dispatch(activeModalSortStudents(true));\n  };\n\n  const onClickEditCourse = () => {\n    setCourseEditMeta({ id, name, isActive, teamSize });\n    dispatch(activeModalEditCourse(true));\n  };\n\n  return (\n    <CourseWrapper>\n      <div className=\"TableItem--0\">{courseOrder}</div>\n      <div className=\"TableItem--1\">{name}</div>\n      <div className=\"TableItem--4\">{teamSize ?? t('Unset')}</div>\n      <div className=\"TableItem--9\">{t(courseState)}</div>\n      <CourseButton onClick={onClickEditCourse}>{t('Edit course')}</CourseButton>\n      <CourseButton onClick={onClickSortStudents}>{t('Sort students')}</CourseButton>\n    </CourseWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/CoursesList/components/Course/styled.ts",
    "content": "import styled from 'styled-components';\nimport { BG_COLOR } from 'appConstants/colors';\nimport { GeneralAdaptiveFont } from 'typography';\n\nexport const CourseWrapper = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 90%;\n  background-color: ${BG_COLOR};\n  padding: 20px;\n  border-radius: 20px;\n\n  & > div:nth-child(1) {\n    font-weight: 600;\n  }\n\n  & > div {\n    ${GeneralAdaptiveFont};\n  }\n\n  @media (max-width: 1100px) {\n    flex-direction: column;\n    width: 40%;\n    gap: 10px;\n\n    & > div:nth-child(1) {\n      text-align: left;\n    }\n\n    button,\n    div {\n      width: 90%;\n      text-align: center;\n    }\n  }\n\n  @media (max-width: 768px) {\n    width: 80%;\n  }\n\n  @media (max-width: 450px) {\n    gap: 5px;\n  }\n`;\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/CoursesList/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { CoursesListWrapper } from './styled';\nimport { CourseItem } from './components/Course';\nimport { Course } from 'types';\nimport { ErrorModal, ModalEditCourse, ModalExpel } from 'components';\nimport { useDispatch, useSelector } from 'react-redux';\nimport {\n  selectIsActiveModalEditCourse,\n  selectIsActiveModalSortStudents,\n} from 'modules/TeamsList/selectors';\nimport { activeModalSortStudents } from 'modules/TeamsList/teamsListReducer';\nimport { useSortStudentsMutation } from 'hooks/graphql';\nimport { useState } from 'react';\n\nexport const CoursesList: FC<{\n  courses: Course[];\n  checkIsCourseNameUniq: (courseName: string) => boolean;\n}> = ({ courses, checkIsCourseNameUniq }) => {\n  const [courseInfoToSort, setCourseInfoToSort] = useState<Partial<Course> | null>(null);\n  const [courseEditMeta, setCourseEditMeta] = useState<Course | null>(null);\n  const dispatch = useDispatch();\n  const isActiveModalSortStudents = useSelector(selectIsActiveModalSortStudents);\n  const isActiveModalEditCourse = useSelector(selectIsActiveModalEditCourse);\n\n  const { sortStudents, errorM: errorSortStudents } = useSortStudentsMutation({\n    courseId: courseInfoToSort?.id || '',\n  });\n\n  const onSubmitSortStudents = () => {\n    sortStudents();\n  };\n\n  if (errorSortStudents) return <ErrorModal error={errorSortStudents} />;\n\n  return (\n    <>\n      <CoursesListWrapper>\n        {courses.map((course: Course, index: number) => (\n          <CourseItem\n            key={course.id}\n            id={course.id}\n            name={course.name}\n            index={index}\n            isActive={course.isActive}\n            teamSize={course.teamSize}\n            setCourseInfoToSort={setCourseInfoToSort}\n            setCourseEditMeta={setCourseEditMeta}\n          />\n        ))}\n      </CoursesListWrapper>\n      <ModalExpel\n        title={courseInfoToSort?.name ?? 'Sort students'}\n        text=\"Sort students?\"\n        open={isActiveModalSortStudents}\n        onSubmit={onSubmitSortStudents}\n        isCrossIconVisible={false}\n        onClose={() => dispatch(activeModalSortStudents(false))}\n        okText=\"Yes\"\n        cancelText=\"No\"\n      />\n      {!!courseEditMeta && (\n        <ModalEditCourse\n          title=\"Edit course\"\n          text=\"Please, enter new course information\"\n          open={isActiveModalEditCourse}\n          okText=\"Save\"\n          cancelText=\"Close\"\n          courseEditMeta={courseEditMeta}\n          checkIsCourseNameUniq={checkIsCourseNameUniq}\n          setCourseEditMeta={setCourseEditMeta}\n        />\n      )}\n    </>\n  );\n};\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/CoursesList/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const CoursesListWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n  gap: 20px;\n\n  @media (max-width: 1100px) and (min-width: 768px) {\n    flex-wrap: wrap;\n    flex-direction: row;\n    align-items: stretch;\n  }\n`;\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/components/ShowCourseSelect/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { SHOW_COURSES_OPTIONS } from 'appConstants';\nimport { CommonSelectList } from 'components';\n\ninterface ShowCourseSelectProps {\n  currentOption: string;\n  setCurrentOption: (newOption: string) => void;\n}\n\nexport const ShowCourseSelect: FC<ShowCourseSelectProps> = ({\n  currentOption,\n  setCurrentOption,\n}) => {\n  const [isSelectOpen, setIsSelectOpen] = useState(false);\n\n  const onOptionChange = (item: { id: string; name: string }) => {\n    setCurrentOption(item.name);\n  };\n\n  const options: { id: string; name: string }[] = SHOW_COURSES_OPTIONS.filter(\n    (option) => option.name !== currentOption\n  );\n\n  return (\n    <CommonSelectList\n      title=\"Show\"\n      listItems={options}\n      onClickHandler={onOptionChange}\n      currItem={currentOption}\n      displayList={isSelectOpen}\n      setDisplayList={setIsSelectOpen}\n      customStyle\n      showOptionsSelect\n    />\n  );\n};\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/index.tsx",
    "content": "import React, { FC, useState, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { AdminPageContentWrapper, ListTitle, CourseListSettings } from './styled';\nimport { HeaderDecor } from 'modules/TeamsList/components/Teams/components/MyTeam/styled';\nimport { AddCourseBlock } from './components/AddCourseBlock';\nimport { CoursesList } from './components/CoursesList';\nimport { useCoursesQuery } from 'hooks/graphql';\nimport { ErrorModal, Loader } from 'components';\nimport { Course } from 'types';\nimport { ShowCourseSelect } from './components/ShowCourseSelect';\nimport { ModalInput } from 'typography';\nimport { SHOW_COURSES_OPTIONS } from 'appConstants';\n\nconst filterCourseList = (courses: Course[], filter: string, searchValue?: string) => {\n  switch (filter) {\n    case 'Active':\n      return courses.filter(\n        ({ isActive, name }) => isActive && (searchValue ? name.includes(searchValue) : true)\n      );\n    case 'Terminated':\n      return courses.filter(\n        ({ isActive, name }) => !isActive && (searchValue ? name.includes(searchValue) : true)\n      );\n    case 'All':\n    default:\n      return searchValue ? courses.filter(({ name }) => name.includes(searchValue)) : courses;\n  }\n};\n\nexport const AdminPageWrapper: FC = () => {\n  const { t } = useTranslation();\n  const { loading, courses, error } = useCoursesQuery();\n  const [currentShowCoursesOption, setCurrentShowCoursesOption] = useState(\n    SHOW_COURSES_OPTIONS[0].name\n  );\n  const [searchValue, setSearchValue] = useState('');\n\n  const checkIsCourseNameUniq = (courseName: string) => {\n    return !courses.find(({ name }: Course) => name === courseName);\n  };\n\n  const filteredCourseList = useMemo(\n    () => filterCourseList(courses, currentShowCoursesOption, searchValue),\n    [courses, currentShowCoursesOption, searchValue]\n  );\n\n  if (error) return <ErrorModal error={error} />;\n  if (loading) return <Loader />;\n\n  return (\n    <AdminPageContentWrapper>\n      <HeaderDecor />\n      <AddCourseBlock checkIsCourseNameUniq={checkIsCourseNameUniq} />\n      <ListTitle>{t('Courses list')}</ListTitle>\n      <CourseListSettings>\n        <ShowCourseSelect\n          currentOption={currentShowCoursesOption}\n          setCurrentOption={setCurrentShowCoursesOption}\n        />\n        <ModalInput\n          name=\"inputValue\"\n          required\n          value={searchValue}\n          mt=\"0px\"\n          autoComplete={'off'}\n          onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n            setSearchValue(e.target.value.trimLeft())\n          }\n          placeholder={t('Search course')}\n        />\n      </CourseListSettings>\n      <CoursesList courses={filteredCourseList} checkIsCourseNameUniq={checkIsCourseNameUniq} />\n    </AdminPageContentWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/AdminPage/components/ContentWrapper/styled.ts",
    "content": "import { DARK_TEXT_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport styled from 'styled-components';\nimport { H2AdaptiveFont } from 'typography';\n\nexport const AdminPageContentWrapper = styled.div`\n  position: relative;\n  z-index: 0;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  max-width: 1320px;\n  min-height: 75vh;\n  padding: 20px 0;\n  background-color: ${WHITE_COLOR};\n  border-radius: 20px;\n`;\n\nexport const ListTitle = styled.h4`\n  ${H2AdaptiveFont}\n  font-size: 25px;\n  color: ${DARK_TEXT_COLOR};\n  text-align: center;\n`;\n\nexport const CourseListSettings = styled.div`\n  position: relative;\n  display: flex;\n  justify-content: flex-end;\n  padding: 10px 5% 30px;\n\n  @media (max-width: 1100px) {\n    justify-content: flex-start;\n    padding: 10px 9% 80px;\n  }\n  @media (max-width: 768px) {\n    padding: 10px 10% 80px;\n  }\n`;\n"
  },
  {
    "path": "src/modules/AdminPage/components/index.ts",
    "content": "export { AdminPageWrapper } from './ContentWrapper';\n"
  },
  {
    "path": "src/modules/AdminPage/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { TeamsTitleWrapper } from 'modules/TeamsList/styled';\nimport { useTranslation } from 'react-i18next';\nimport { ContentPageWrapper } from 'typography';\nimport { StudentTableWrapper, TableTitle } from 'modules/StudentsTable/styled';\nimport { AdminPageWrapper } from './components';\n\nexport const AdminPage: FC = () => {\n  const { t } = useTranslation();\n\n  return (\n    <ContentPageWrapper>\n      <StudentTableWrapper>\n        <TeamsTitleWrapper>\n          <TableTitle>{t('Admin page')}</TableTitle>\n        </TeamsTitleWrapper>\n        <AdminPageWrapper />\n      </StudentTableWrapper>\n    </ContentPageWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/EditProfile/components/UserCourseListItem/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useSelector } from 'react-redux';\nimport { MinusButton, UserCourseListItemStyled } from './styled';\nimport { Course, Team } from 'types';\nimport { ReactComponent as CrossSvgIcon } from 'assets/svg/cross.svg';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\nimport { useRemoveUserFromCourseMutation } from 'hooks/graphql';\n\ntype TUserCourseListItem = {\n  isUserRegisteredCourse: boolean;\n  onSub: (c: IOldCourses) => void;\n  course: Course;\n};\n\nexport interface IOldCourses extends Course {\n  isNew: boolean;\n}\n\nexport const UserCourseListItem: FC<TUserCourseListItem> = ({\n  children,\n  isUserRegisteredCourse,\n  onSub,\n  course,\n}) => {\n  const userData = useSelector(selectUserData);\n\n  const { removeUserFromCourse } = useRemoveUserFromCourseMutation({\n    data: {\n      courseId: course.id,\n      userId: userData.id,\n      teamId: userData.teams.find((team: Team) => team.courseId === course.id)?.id ?? null,\n      page: 0,\n    },\n  });\n  const onClickHandler = isUserRegisteredCourse\n    ? () => {\n        onSub({ ...course, isNew: false });\n        removeUserFromCourse();\n      }\n    : () => {\n        onSub({ ...course, isNew: true });\n      };\n\n  return (\n    <UserCourseListItemStyled>\n      <div>{children}</div>\n      <MinusButton type=\"button\" active={false} onClick={onClickHandler}>\n        <CrossSvgIcon />\n      </MinusButton>\n    </UserCourseListItemStyled>\n  );\n};\n"
  },
  {
    "path": "src/modules/EditProfile/components/UserCourseListItem/styled.ts",
    "content": "import styled from 'styled-components';\nimport { BG_COLOR, DARK_TEXT_COLOR } from 'appConstants/colors';\nimport { PlusButton } from 'components/CourseField/styled';\nimport { GeneralAdaptiveFont } from 'typography';\n\nexport const UserCourseListItemStyled = styled.div`\n  display: flex;\n\n  div {\n    flex-grow: 1;\n    padding: 8px 15px;\n    margin-bottom: 20px;\n    border-radius: 10px;\n    background-color: ${BG_COLOR};\n    color: ${DARK_TEXT_COLOR};\n    ${GeneralAdaptiveFont}\n  }\n`;\n\nexport const MinusButton = styled(PlusButton)`\n  background-image: none;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n`;\n"
  },
  {
    "path": "src/modules/EditProfile/formFields.ts",
    "content": "import { INPUT_VALUES_EDIT_PROFILE } from 'appConstants';\nimport { Course } from 'types';\nimport { InputFieldProps } from '../../components/InputField';\n\nexport const formFields: InputFieldProps[] = [\n  {\n    name: 'firstName',\n    labelText: 'First Name',\n    placeholder: 'Enter first name',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[A-Za-z]+$/i,\n        message: 'This input is letters only.',\n      },\n      minLength: {\n        value: 2,\n        message: 'Minimal length is 2.',\n      },\n      maxLength: {\n        value: 15,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'lastName',\n    labelText: 'Last Name',\n    placeholder: 'Enter last name',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[A-Za-z]+$/i,\n        message: 'This input is letters only.',\n      },\n      minLength: {\n        value: 2,\n        message: 'Minimal length is 2.',\n      },\n      maxLength: {\n        value: 20,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'discord',\n    labelText: 'Discord',\n    placeholder: 'Enter discord',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[A-Za-z0-9@#-_() ]+$/i,\n        message: 'This input is letters and digits only.',\n      },\n      minLength: {\n        value: 3,\n        message: 'Minimal length is 3.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'telegram',\n    labelText: 'Telegram',\n    placeholder: 'Enter telegram',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[A-Za-z0-9-_ ]+$/i,\n        message: 'This input is letters and digits only.',\n      },\n      minLength: {\n        value: 3,\n        message: 'Minimal length is 3.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'city',\n    labelText: 'City',\n    placeholder: 'Enter city',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[A-Za-z\\- ]+$/i,\n        message: 'This input is letters only.',\n      },\n      minLength: {\n        value: 2,\n        message: 'Minimal length is 2.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'country',\n    labelText: 'Country',\n    placeholder: 'Enter country',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[A-Za-z\\- ]+$/i,\n        message: 'This input is letters only.',\n      },\n      minLength: {\n        value: 2,\n        message: 'Minimal length is 2.',\n      },\n      maxLength: {\n        value: 30,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n  {\n    name: 'score',\n    labelText: 'Score',\n    placeholder: 'Enter score',\n    register: {\n      required: 'This is required.',\n      pattern: {\n        value: /^[1-9]+\\d*$/i,\n        message: 'This input is number only.',\n      },\n      minLength: {\n        value: 1,\n        message: 'Minimal length is 1.',\n      },\n      maxLength: {\n        value: 5,\n        message: 'This input exceed maxLength.',\n      },\n    },\n  },\n];\n\nexport const checkIsCoursesEqual = (newCourses: Course[], userCourses: Course[]) => {\n  return (\n    JSON.stringify(newCourses.map((newCourse) => newCourse.name).sort()) ===\n    JSON.stringify(userCourses.map((userCourse) => userCourse.name).sort())\n  );\n};\n\nexport const checkIsFormFieldsEqual = (inputValues: any, userData: any) => {\n  let isEqual = true;\n  INPUT_VALUES_EDIT_PROFILE.forEach((item: string) => {\n    if (inputValues[item] !== userData[item]) {\n      isEqual = false;\n    }\n  });\n  return isEqual;\n};\n"
  },
  {
    "path": "src/modules/EditProfile/index.tsx",
    "content": "import React, { FC, useEffect, useMemo, useState } from 'react';\nimport { Redirect, useHistory } from 'react-router-dom';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { FieldError, useForm } from 'react-hook-form';\nimport { Loader, InputField, CourseField, ErrorModal, ModalExpel } from 'components';\nimport { useCoursesQuery, useUpdUserMutation } from 'hooks/graphql';\nimport { Button, AdditionalWrapper } from 'typography';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\nimport { selectIsCommonError, selectPathToThePage, selectToken } from 'modules/LoginPage/selectors';\nimport { Course, UpdateUserInput, User } from 'types';\nimport { checkIsCoursesEqual, formFields, checkIsFormFieldsEqual } from './formFields';\nimport {\n  EditProfileWrapper,\n  InputsWrapper,\n  ButtonWrapper,\n  FormWrapper,\n  UserCoursesListTitle,\n  FormTitle,\n  CoursesWrapper,\n  CommonWrapper,\n} from './styled';\nimport { BG_COLOR, MAIN1_COLOR } from 'appConstants/colors';\nimport { INPUT_VALUES_EDIT_PROFILE } from 'appConstants';\nimport { IOldCourses, UserCourseListItem } from './components/UserCourseListItem';\nimport { useTranslation } from 'react-i18next';\nimport { setUserData } from 'modules/StudentsTable/studentsTableReducer';\nimport { setCourse } from 'modules/LoginPage/loginPageMiddleware';\nimport { setEditProfileDataChange } from 'modules/LoginPage/loginPageReducer';\nimport { activeModalLeavePage } from 'modules/TeamsList/teamsListReducer';\nimport { selectIsActiveModalLeavePage } from 'modules/TeamsList/selectors';\n\nexport const EditProfile: FC = () => {\n  const history = useHistory();\n  const loginToken = useSelector(selectToken);\n  const userData = useSelector(selectUserData);\n  const isCommonError = useSelector(selectIsCommonError);\n  const { t } = useTranslation();\n  const isActiveModalLeavePage = useSelector(selectIsActiveModalLeavePage);\n  const pathToThePage = useSelector(selectPathToThePage);\n\n  const oldCourses: IOldCourses[] = userData.courses.map((course: Course) => ({\n    ...course,\n    isNew: true,\n  }));\n\n  const [userCourses, setUserCourses] = useState<IOldCourses[]>(oldCourses);\n  const { loading, courses, error } = useCoursesQuery();\n  const defaultData = useMemo(\n    () => ({\n      id: userData.id,\n      firstName: userData.firstName || '',\n      lastName: userData.lastName || '',\n      discord: userData.discord || '',\n      telegram: userData.telegram || '',\n      city: userData.city || '',\n      country: userData.country || '',\n      courseIds: [],\n      score: userData.score || 9999,\n    }),\n    [userData]\n  );\n  const [inputValues, setInputValues] = useState<UpdateUserInput>(defaultData);\n\n  const { updateUser, loadingM, errorM } = useUpdUserMutation({\n    user: {\n      ...inputValues,\n      courseIds: userCourses.map(({ id }: Course) => id),\n    },\n  });\n\n  const [isValidCoursesList, setValidCoursesList] = useState(true);\n\n  const dispatch = useDispatch();\n\n  const isUserNew = !!userData.courses.length;\n\n  const currentCourses = courses?.filter(\n    ({ isActive, name }: Course) =>\n      isActive && !userCourses.find((uItem: Course) => uItem.name === name)\n  );\n\n  const { register, handleSubmit, errors, reset } = useForm<UpdateUserInput>({\n    defaultValues: inputValues,\n    mode: 'onChange',\n  });\n\n  const changeInputValue = (e: React.ChangeEvent<HTMLInputElement>): void => {\n    const { name, value } = e.target;\n    setInputValues({\n      ...inputValues,\n      [name]: value.trim(),\n    });\n    dispatch(\n      setEditProfileDataChange(\n        !checkIsFormFieldsEqual(\n          {\n            ...inputValues,\n            [name]: value.trim(),\n          },\n          userData\n        )\n      )\n    );\n  };\n\n  const onSubmit = () => {\n    if (userCourses.length) {\n      updateUser().then(({ data: { updateUser } }) => {\n        const newCurrentCourse =\n          updateUser.courses.find(\n            (course: Course) => course.id === userCourses[userCourses.length - 1].id\n          ) ?? updateUser.courses[0];\n        dispatch(setCourse(newCurrentCourse));\n        dispatch(setUserData(updateUser));\n        history.push('/');\n      });\n    } else {\n      setValidCoursesList(false);\n    }\n    dispatch(setEditProfileDataChange(false));\n  };\n\n  const localCourseUpdate = (course: IOldCourses) => {\n    if (course) {\n      setUserCourses([...userCourses, course]);\n      setValidCoursesList(true);\n      dispatch(setEditProfileDataChange(true));\n    }\n  };\n\n  const localCourseSub = (course: IOldCourses) => {\n    if (course) {\n      const copyCourses: IOldCourses[] = [...userCourses];\n\n      const index = copyCourses.findIndex((item: IOldCourses) => {\n        return item.id === course.id;\n      });\n\n      if (index >= 0) {\n        copyCourses.splice(index, 1);\n      }\n\n      if (checkIsCoursesEqual(copyCourses, userData.courses)) {\n        dispatch(setEditProfileDataChange(false));\n      }\n\n      setUserCourses([...copyCourses]);\n      setValidCoursesList(true);\n    }\n  };\n\n  const onSubmitLeavePage = () => {\n    history.push(pathToThePage);\n    dispatch(setEditProfileDataChange(false));\n  };\n\n  useEffect(() => {\n    if (userData.id !== '' && !inputValues.id) {\n      setInputValues(defaultData);\n      setUserCourses(oldCourses);\n      reset(defaultData);\n      dispatch(setEditProfileDataChange(false));\n    }\n  }, [reset, inputValues, defaultData, userData, oldCourses, dispatch]);\n\n  if (!loginToken) return <Redirect to={'/login'} />;\n  if (error || errorM || isCommonError) return <ErrorModal error={error || errorM} />;\n  if (loading || loadingM) return <Loader />;\n\n  return (\n    <FormWrapper>\n      <CommonWrapper>\n        <EditProfileWrapper autoComplete=\"off\" onSubmit={handleSubmit(onSubmit)}>\n          <FormTitle>{t('Enter your profile information')}</FormTitle>\n          <InputsWrapper>\n            {formFields.map((item, index) => {\n              return (\n                <InputField\n                  key={JSON.stringify(item)}\n                  name={item.name}\n                  value={userData[INPUT_VALUES_EDIT_PROFILE[index] as keyof User] as string}\n                  labelText={item.labelText}\n                  placeholder={item.placeholder}\n                  aria-invalid={\n                    (errors[\n                      INPUT_VALUES_EDIT_PROFILE[index] as keyof UpdateUserInput\n                    ] as FieldError)\n                      ? 'true'\n                      : 'false'\n                  }\n                  message={\n                    (\n                      errors[\n                        INPUT_VALUES_EDIT_PROFILE[index] as keyof UpdateUserInput\n                      ] as FieldError\n                    )?.message\n                  }\n                  onChange={changeInputValue}\n                  register={register(item.register)}\n                />\n              );\n            })}\n            <CoursesWrapper>\n              <UserCoursesListTitle>{t('Course')}</UserCoursesListTitle>\n              {userCourses.map((item: IOldCourses) => {\n                return (\n                  <UserCourseListItem\n                    key={item.id}\n                    isUserRegisteredCourse={item.isNew}\n                    course={item}\n                    onSub={localCourseSub}\n                  >\n                    {item.name}\n                  </UserCourseListItem>\n                );\n              })}\n              {currentCourses.length !== 0 && (\n                <CourseField\n                  name=\"courses\"\n                  placeholder={t('Select course')}\n                  register={register}\n                  multi\n                  onAdd={localCourseUpdate}\n                  courses={currentCourses}\n                  isValid={isValidCoursesList}\n                />\n              )}\n              {userCourses.length === 0 && currentCourses.length === 0 && (\n                <span>No courses available, try again later</span>\n              )}\n            </CoursesWrapper>\n          </InputsWrapper>\n          <ButtonWrapper>\n            {isUserNew && (\n              <Button\n                type=\"button\"\n                bgc={BG_COLOR}\n                color={MAIN1_COLOR}\n                mr=\"20px\"\n                onClick={history.goBack}\n              >\n                {t('Cancel')}\n              </Button>\n            )}\n            <Button>{isUserNew ? t('Submit') : t('Save')}</Button>\n          </ButtonWrapper>\n        </EditProfileWrapper>\n        <AdditionalWrapper />\n      </CommonWrapper>\n      <ModalExpel\n        title=\"Data is unsaved\"\n        text=\"Are you sure want to leave page without saving data\"\n        open={isActiveModalLeavePage}\n        onSubmit={onSubmitLeavePage}\n        isCrossIconVisible={false}\n        onClose={() => dispatch(activeModalLeavePage(false))}\n        okText=\"Yes\"\n        cancelText=\"No\"\n      />\n    </FormWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/EditProfile/styled.ts",
    "content": "import styled from 'styled-components';\nimport { BG_COLOR, DARK_TEXT_COLOR, LIGHT_TEXT_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport {\n  PageTitle,\n  H1AdaptiveFont,\n  GeneralAdaptiveFont,\n  ScrollBar,\n  MainComponentHeight,\n} from 'typography';\n\nexport const EditProfileWrapper = styled.form`\n  background-color: ${WHITE_COLOR};\n  width: 680px;\n  padding: 30px;\n  border-radius: 20px;\n  margin: 75px 0 15px;\n  @media screen and (max-width: 768px) {\n    width: 320px;\n    padding: 15px 10px;\n    flex-direction: column;\n    margin: 50px 0 30px;\n  }\n\n  @media (max-width: 440px) {\n    width: 280px;\n  }\n`;\n\nexport const FormWrapper = styled.div`\n  position: relative;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n  overflow-y: scroll;\n  ${ScrollBar};\n  ${MainComponentHeight};\n`;\n\nexport const FormTitle = styled(PageTitle)`\n  margin-top: 0;\n  margin-bottom: 32px;\n  ${H1AdaptiveFont};\n`;\n\nexport const InputsWrapper = styled.div`\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  flex-wrap: wrap;\n  margin-bottom: 10px;\n  @media screen and (max-width: 768px) {\n    flex-direction: column;\n  }\n`;\n\nexport const ButtonWrapper = styled.div`\n  display: flex;\n  justify-content: flex-end;\n`;\n\nexport const CoursesWrapper = styled.div`\n  max-width: 300px;\n  width: 100%;\n`;\nexport const UserCoursesListTitle = styled.div`\n  color: ${LIGHT_TEXT_COLOR};\n  margin-bottom: 10px;\n  ${GeneralAdaptiveFont}\n`;\n\nexport const UserCourseListItem = styled.div`\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  border-radius: 10px;\n  background-color: ${BG_COLOR};\n  color: ${DARK_TEXT_COLOR};\n`;\n\nexport const CommonWrapper = styled.div`\n  position: absolute;\n  top: 0;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n`;\n"
  },
  {
    "path": "src/modules/LoginPage/components/LoginInfoBlock/index.tsx",
    "content": "import React, { FC } from 'react';\nimport {\n  StyledLoginInfoBlock,\n  StyledLoginTitle,\n  StyledLoginRegistrationLink,\n  StyledLoginTextWrapper,\n} from './styled';\nimport { AUTH_BACKEND_LINK } from 'appConstants';\nimport { useTranslation } from 'react-i18next';\n\nexport const LoginInfoBlock: FC = () => {\n  const { t } = useTranslation();\n  return (\n    <StyledLoginInfoBlock>\n      <StyledLoginTitle>{t('Sign in')}</StyledLoginTitle>\n      <StyledLoginRegistrationLink href={AUTH_BACKEND_LINK}>\n        {t('Sign in with Github')}\n      </StyledLoginRegistrationLink>\n      <StyledLoginTextWrapper>\n        <p>{t('Don’t have github account?')}</p>\n        <a href={AUTH_BACKEND_LINK}>{t('Sign up')}</a>\n      </StyledLoginTextWrapper>\n    </StyledLoginInfoBlock>\n  );\n};\n"
  },
  {
    "path": "src/modules/LoginPage/components/LoginInfoBlock/styled.ts",
    "content": "import styled from 'styled-components';\nimport { WHITE_COLOR, DARK_TEXT_COLOR, MAIN1_COLOR } from 'appConstants/colors';\nimport { GeneralAdaptiveFont, GeneralButtonPadding, H1AdaptiveFont } from 'typography';\n\nexport const StyledLoginInfoBlock = styled.div`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  margin-left: 12%;\n  padding: 20px;\n  font-size: 1rem;\n  color: ${DARK_TEXT_COLOR};\n  background-color: ${WHITE_COLOR};\n  border-radius: 20px;\n  gap: 30px;\n  ${GeneralAdaptiveFont};\n\n  @media (max-width: 992px) {\n    margin: 0 auto;\n  }\n  @media (max-width: 768px) {\n    padding: 20px 15px;\n    gap: 25px;\n  }\n  @media (max-width: 550px) {\n    gap: 20px;\n  }\n  @media (max-width: 440px) {\n    gap: 15px;\n  }\n`;\n\nexport const StyledLoginTitle = styled.h2`\n  margin: 0;\n  font-weight: 600;\n  ${H1AdaptiveFont};\n`;\n\nexport const StyledLoginRegistrationLink = styled.a`\n  display: inline-block;\n  margin-top: 10px;\n  text-align: center;\n  color: ${WHITE_COLOR};\n  text-decoration: none;\n  background-color: ${MAIN1_COLOR};\n  border-radius: 20px;\n  ${GeneralButtonPadding}\n`;\n\nexport const StyledLoginTextWrapper = styled.div`\n  display: flex;\n  font-weight: normal;\n  line-height: 150%;\n  gap: 10px;\n\n  p {\n    margin: 0;\n  }\n\n  a {\n    font-weight: 500;\n    color: ${MAIN1_COLOR};\n    text-decoration: none;\n  }\n`;\n"
  },
  {
    "path": "src/modules/LoginPage/components/index.ts",
    "content": "export { LoginInfoBlock } from './LoginInfoBlock';\n"
  },
  {
    "path": "src/modules/LoginPage/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useSelector } from 'react-redux';\nimport { Redirect } from 'react-router-dom';\nimport { selectToken } from './selectors';\nimport { StyledLoginImage, StyledLoginPage, StyledLoginPageItemsWrapper } from './styled';\nimport { LoginInfoBlock } from './components';\n\nexport const LoginPage: FC = () => {\n  const loginToken = useSelector(selectToken);\n\n  if (loginToken) return <Redirect to=\"/\" />;\n\n  return (\n    <StyledLoginPage>\n      <StyledLoginPageItemsWrapper>\n        <LoginInfoBlock />\n      </StyledLoginPageItemsWrapper>\n      <StyledLoginImage />\n    </StyledLoginPage>\n  );\n};\n"
  },
  {
    "path": "src/modules/LoginPage/loginPageMiddleware.ts",
    "content": "import { CURRENT_LANG, CURRENT_COURSE, TOUR_OPENING } from 'appConstants';\nimport { Course } from 'types';\nimport { setCurrCourse, setCurrLang } from './loginPageReducer';\n\nexport const setLanguage = (currentLanguage: string) => {\n  return (dispatch: (actionCreator: any) => void) => {\n    localStorage.setItem(CURRENT_LANG, currentLanguage);\n    dispatch(setCurrLang(currentLanguage));\n  };\n};\n\nexport const setCourse = (currentCourse: Course) => {\n  return (dispatch: (actionCreator: any) => void) => {\n    localStorage.setItem(CURRENT_COURSE, JSON.stringify(currentCourse));\n    dispatch(setCurrCourse(currentCourse));\n  };\n};\n\nexport const setTourOpening = (tourOpening: string) => {\n  return () => {\n    localStorage.setItem(TOUR_OPENING, tourOpening);\n  };\n};\n"
  },
  {
    "path": "src/modules/LoginPage/loginPageReducer.ts",
    "content": "import {\n  DEFAULT_LANGUAGE,\n  SET_COMMON_ERROR,\n  SET_CURR_COURSE,\n  SET_CURR_LANG,\n  SET_TOKEN,\n  SET_BURGER_MENU_OPEN,\n  SET_EDIT_PROFILE_DATA_CHANGE,\n  SET_PATH_TO_THE_PAGE,\n  SET_IS_TOUR_OPEN,\n} from 'appConstants';\nimport { createActions, handleActions } from 'redux-actions';\nimport { StateLoginPage } from 'types';\n\nexport const loginPageState = {\n  loginToken: null,\n  currCourse: {\n    id: '',\n    name: '',\n    teamSize: null,\n    isActive: true,\n  },\n  currLanguage: DEFAULT_LANGUAGE,\n  isCommonError: false,\n  isBurgerMenuOpen: false,\n  isEditProfileDataChange: false,\n  pathToThePage: '',\n  isTourOpen: false,\n};\n\nexport const {\n  setToken,\n  setCurrCourse,\n  setCurrLang,\n  setCommonError,\n  setBurgerMenuOpen,\n  setEditProfileDataChange,\n  setPathToThePage,\n  setIsTourOpen,\n} = createActions({\n  SET_TOKEN: (loginToken) => ({ loginToken }),\n  SET_CURR_COURSE: (currCourse) => ({ currCourse }),\n  SET_CURR_LANG: (currLanguage) => ({ currLanguage }),\n  SET_COMMON_ERROR: (isCommonError) => ({ isCommonError }),\n  SET_BURGER_MENU_OPEN: (isBurgerMenuOpen) => ({ isBurgerMenuOpen }),\n  SET_EDIT_PROFILE_DATA_CHANGE: (isEditProfileDataChange) => ({\n    isEditProfileDataChange,\n  }),\n  SET_PATH_TO_THE_PAGE: (pathToThePage) => ({\n    pathToThePage,\n  }),\n  SET_IS_TOUR_OPEN: (isTourOpen) => ({\n    isTourOpen,\n  }),\n});\n\nexport const loginPageReducer = handleActions<StateLoginPage, any>(\n  {\n    [SET_TOKEN]: (state, { payload: { loginToken } }) => ({\n      ...state,\n      loginToken,\n    }),\n    [SET_CURR_COURSE]: (state, { payload: { currCourse } }) => ({\n      ...state,\n      currCourse,\n    }),\n    [SET_CURR_LANG]: (state, { payload: { currLanguage } }) => ({\n      ...state,\n      currLanguage,\n    }),\n    [SET_COMMON_ERROR]: (state, { payload: { isCommonError } }) => ({\n      ...state,\n      isCommonError,\n    }),\n    [SET_BURGER_MENU_OPEN]: (state, { payload: { isBurgerMenuOpen } }) => ({\n      ...state,\n      isBurgerMenuOpen,\n    }),\n    [SET_EDIT_PROFILE_DATA_CHANGE]: (state, { payload: { isEditProfileDataChange } }) => ({\n      ...state,\n      isEditProfileDataChange,\n    }),\n    [SET_PATH_TO_THE_PAGE]: (state, { payload: { pathToThePage } }) => ({\n      ...state,\n      pathToThePage,\n    }),\n    [SET_IS_TOUR_OPEN]: (state, { payload: { isTourOpen } }) => ({\n      ...state,\n      isTourOpen,\n    }),\n  },\n  loginPageState\n);\n"
  },
  {
    "path": "src/modules/LoginPage/selectors.ts",
    "content": "import { State } from 'types';\n\nexport const selectToken = (state: State) => state.loginPageReducer.loginToken;\n\nexport const selectCurrCourse = (state: State) => state.loginPageReducer.currCourse;\n\nexport const selectCurrLanguage = (state: State) => state.loginPageReducer.currLanguage;\n\nexport const selectIsCommonError = (state: State) => state.loginPageReducer.isCommonError;\n\nexport const selectIsBurgerMenuOpen = (state: State) => state.loginPageReducer.isBurgerMenuOpen;\n\nexport const selectIsEditProfileDataChange = (state: State) =>\n  state.loginPageReducer.isEditProfileDataChange;\n\nexport const selectPathToThePage = (state: State) => state.loginPageReducer.pathToThePage;\n\nexport const selectIsTourOpen = (state: State) => state.loginPageReducer.isTourOpen;\n"
  },
  {
    "path": "src/modules/LoginPage/styled.ts",
    "content": "import styled from 'styled-components';\nimport { MAIN1_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { ReactComponent as LoginImage } from 'assets/svg/loginImage.svg';\n\nexport const StyledLoginPage = styled.div`\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n  height: 100vh;\n  margin: 0 auto;\n  background: linear-gradient(90deg, ${WHITE_COLOR} 75%, ${MAIN1_COLOR} 75%);\n`;\n\nexport const StyledLoginPageItemsWrapper = styled.div`\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  max-width: 1440px;\n  height: 100%;\n  overflow: hidden;\n`;\n\nexport const StyledLoginImage = styled(LoginImage)`\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: -1;\n  width: auto;\n  height: 100%;\n\n  @media (max-width: 991px) {\n    left: 50%;\n    transform: translate(-50%, 0%);\n  }\n`;\n"
  },
  {
    "path": "src/modules/NotFoundPage/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { ContentPageWrapper, PageTitle } from 'typography';\nimport { NotFoundPageWrapper } from './styled';\n\nexport const NotFoundPage: FC = () => {\n  const { t } = useTranslation();\n  return (\n    <ContentPageWrapper>\n      <NotFoundPageWrapper>\n        <PageTitle>{t('Not found!')}</PageTitle>\n      </NotFoundPageWrapper>\n    </ContentPageWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/NotFoundPage/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const NotFoundPageWrapper = styled.div`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n  height: 100%;\n`;\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/components/TableRow/components/TableItem/index.tsx",
    "content": "import React, { FC, MouseEvent, useState } from 'react';\nimport { TablePopup } from 'components/TablePopup';\nimport { StyledTableItem } from './styled';\n\ntype TableItemProps = {\n  item: string;\n  index: number;\n  dataLength: number;\n};\n\nexport const TableItem: FC<TableItemProps> = ({ item, index, dataLength }) => {\n  const [tableItemCursor, setTableItemCursor] = useState(false);\n  const [showPopup, setShowPopup] = useState(false);\n  const [popupElements, setPopupElements] = useState<string[]>([]);\n\n  const mouseOverHandler = (event: MouseEvent<HTMLElement>) => {\n    const target = event.target as HTMLDivElement;\n    if (target.scrollWidth !== target.clientWidth) {\n      setShowPopup(true);\n      setPopupElements(target?.textContent?.split(',') as string[]);\n      setTableItemCursor(true);\n    }\n  };\n\n  const mouseLeaveHandler = () => {\n    setShowPopup(false);\n    setPopupElements([]);\n    setTableItemCursor(false);\n  };\n\n  return (\n    <StyledTableItem\n      className={`TableItem--${index}`}\n      onMouseOver={mouseOverHandler}\n      onMouseOut={mouseLeaveHandler}\n      tableItemCursor={tableItemCursor}\n    >\n      <div className={`TableItem__first-element`}>{item}</div>\n      {showPopup && <TablePopup {...{ popupElements, dataLength }} />}\n    </StyledTableItem>\n  );\n};\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/components/TableRow/components/TableItem/styled.ts",
    "content": "import styled from 'styled-components';\n\ntype TStyledTableItem = {\n  tableItemCursor: boolean;\n};\n\nexport const StyledTableItem = styled.div<TStyledTableItem>`\n  position: relative;\n  max-width: 140px;\n  cursor: ${({ tableItemCursor }) => (tableItemCursor ? 'pointer' : 'unset')};\n  .TableItem__first-element {\n    width: 100%;\n    margin: 0;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n  }\n`;\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/components/TableRow/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { ListChildComponentProps } from 'react-window';\nimport { TableItem } from './components/TableItem';\nimport { StyledTableRow } from './styled';\n\nexport const TableRow: FC<ListChildComponentProps> = ({ data, index, style }) => {\n  const optimalItemIndexCount = 2;\n  return (\n    <StyledTableRow style={style}>\n      {data[index].map((item: string, ind: number) => (\n        <TableItem\n          item={item}\n          index={ind}\n          dataLength={index > optimalItemIndexCount ? index / (data.length - 1) : 0}\n          key={`TableItemKey-${ind}`}\n        />\n      ))}\n    </StyledTableRow>\n  );\n};\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/components/TableRow/styled.ts",
    "content": "import { BG_COLOR, DARK_TEXT_COLOR } from 'appConstants/colors';\nimport styled from 'styled-components';\n\nexport const StyledTableRow = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 20px;\n  font-weight: 400;\n  line-height: 150%;\n  color: ${DARK_TEXT_COLOR};\n  border-radius: 10px;\n  &:nth-child(2n) {\n    background-color: ${BG_COLOR};\n  }\n\n  @media (max-width: 768px) {\n    padding: 10px;\n  }\n  @media (max-width: 440px) {\n    padding: 5px;\n  }\n`;\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/index.tsx",
    "content": "import React, { FC, useMemo, ReactText } from 'react';\nimport { useSelector } from 'react-redux';\nimport { FixedSizeList as List } from 'react-window';\nimport AutoSizer from 'react-virtualized-auto-sizer';\nimport { StyledTableBody } from './styled';\nimport './styles.css';\nimport { User, Course, Team } from 'types';\nimport { USERS_PER_PAGE } from 'appConstants';\nimport { TableRow } from './components/TableRow';\nimport { selectCurrCourse } from 'modules/LoginPage/selectors';\nimport { useTranslation } from 'react-i18next';\n\ntype TableBodyProps = {\n  users: User[];\n  page: number;\n};\n\nexport const TableBody: FC<TableBodyProps> = ({ users, page }) => {\n  const currCourse = useSelector(selectCurrCourse);\n  const { t } = useTranslation();\n\n  const usersData: Array<string[] | ReactText[]> = useMemo(\n    () =>\n      users.map((user: User, index: number) => {\n        return [\n          `${index + 1 + page * USERS_PER_PAGE}`,\n          `${user.firstName} ${user.lastName || null}`,\n          `${user.score}`,\n          user.teams.find((team: Team) => team.courseId === currCourse.id)\n            ? `${user.teams.find((team: Team) => team.courseId === currCourse.id)?.number}`\n            : (t('No team yet.') as string),\n          user.telegram || `${t('No')} telegram.`,\n          user.discord || `${t('No')} discord.`,\n          user.github || `${t('No')} GitHub.`,\n          `${user.country},\n          ${user.city}`,\n          user.courses.length\n            ? user.courses.map((course: Course) => course.name).join(', ')\n            : (t('No courses.') as string),\n        ];\n      }),\n    [users, page, currCourse.id, t]\n  );\n\n  return (\n    <StyledTableBody>\n      <AutoSizer>\n        {({ height, width }) => (\n          <List\n            className=\"List\"\n            height={height}\n            itemSize={64}\n            itemCount={usersData.length}\n            itemData={usersData}\n            width={width}\n          >\n            {TableRow}\n          </List>\n        )}\n      </AutoSizer>\n    </StyledTableBody>\n  );\n};\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const StyledTableBody = styled.div`\n  display: flex;\n  width: 100%;\n  height: 100%;\n`;\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableBody/styles.css",
    "content": ".List {\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  height: 100%;\n  overflow-y: scroll !important;\n}\n\n.List::-webkit-scrollbar {\n  width: 10px;\n  background-color: var(--WHITE_COLOR);\n}\n\n.List::-webkit-scrollbar-thumb {\n  background-color: var(--SCROLL_THUMB_COLOR);\n  border-radius: 20px;\n}\n\n.TableItem--0 {\n  width: 3.5%;\n}\n\n.TableItem--1 {\n  width: 16%;\n}\n\n.TableItem--2 {\n  width: 5%;\n}\n\n.TableItem--3 {\n  width: 14%;\n}\n\n.TableItem--4,\n.TableItem--5,\n.TableItem--6 {\n  width: 9.93%;\n}\n\n.TableItem--7, .TableItem--8 {\n  width: 14%;\n}\n\n.TableItem--9 {\n  width: 11%;\n}\n\n@media (max-width: 1320px) {\n  .TableItem--0 {\n    width: 4%;\n  }\n\n  .TableItem--1 {\n    width: 16%;\n  }\n\n  .TableItem--2 {\n    width: 6%;\n  }\n\n  .TableItem--3 {\n    width: 14%;\n  }\n\n  .TableItem--8 {\n    width: 15%;\n  }\n}\n\n@media (max-width: 1200px) {\n  .TableRow {\n    font-size: 0.95rem;\n  }\n\n  .TableItem--0 {\n    width: 4.5%;\n  }\n\n  .TableItem--1 {\n    width: 18%;\n  }\n\n  .TableItem--2 {\n    width: 6%;\n  }\n\n  .TableItem--3 {\n    width: 15%;\n  }\n\n  .TableItem--7 {\n    display: none;\n  }\n\n  .TableItem--8 {\n    width: 15%;\n  }\n}\n\n@media (max-width: 992px) {\n  .TableRow {\n    font-size: 0.9rem;\n  }\n\n  .TableItem--0 {\n    width: 6%;\n  }\n\n  .TableItem--1 {\n    width: 20.5%;\n  }\n\n  .TableItem--2 {\n    width: 7%;\n  }\n\n  .TableItem--3 {\n    width: 17%;\n  }\n\n  .TableItem--4 {\n    width: 11%;\n  }\n\n  .TableItem--5,\n  .TableItem--7 {\n    display: none;\n  }\n\n  .TableItem--8 {\n    width: 20%;\n  }\n}\n\n@media (max-width: 768px) {\n  .TableRow {\n    padding: 10px;\n    font-size: 0.825rem;\n  }\n\n  .TableItem--0 {\n    width: 9%;\n  }\n\n  .TableItem--1 {\n    width: 28%;\n  }\n\n  .TableItem--3 {\n    width: 25%;\n  }\n\n  .TableItem--4 {\n    width: 17.5%;\n  }\n\n  .TableItem--2,\n  .TableItem--5,\n  .TableItem--7,\n  .TableItem--6 {\n    display: none;\n  }\n\n  .TableItem--8 {\n    width: 20.5%;\n  }\n}\n\n@media (max-width: 550px) {\n  .TableRow {\n    padding: 10px;\n    font-size: 0.8rem;\n  }\n\n  .TableItem--0 {\n    width: 11%;\n  }\n\n  .TableItem--1 {\n    width: 33%;\n  }\n\n  .TableItem--4 {\n    width: 21.5%;\n  }\n\n  .TableItem--2,\n  .TableItem--3,\n  .TableItem--5,\n  .TableItem--7,\n  .TableItem--6 {\n    display: none;\n  }\n\n  .TableItem--8 {\n    width: 27.5%;\n  }\n}\n\n@media (max-width: 440px) {\n  .TableRow {\n    padding: 5px;\n    font-size: 0.68rem;\n  }\n\n  .TableItem--0 {\n    width: 12%;\n  }\n\n  .TableItem--1 {\n    width: 36%;\n  }\n\n  .TableItem--4 {\n    width: 23%;\n  }\n\n  .TableItem--2,\n  .TableItem--3,\n  .TableItem--5,\n  .TableItem--7,\n  .TableItem--6 {\n    display: none;\n  }\n\n  .TableItem--8 {\n    width: 24.5%;\n  }\n}\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableHead/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { TABLE_HEADERS } from 'appConstants';\nimport { StyledTableHead, StyledTableHeadRow, StyledTableHeader } from './styled';\nimport { useTranslation } from 'react-i18next';\n\nexport const TableHead: FC = () => {\n  const { t } = useTranslation();\n  return (\n    <StyledTableHead>\n      <StyledTableHeadRow>\n        {TABLE_HEADERS.map((tableHeader: string, index: number) => (\n          <StyledTableHeader className={`TableItem--${index}`} key={tableHeader}>\n            {t(tableHeader)}\n          </StyledTableHeader>\n        ))}\n      </StyledTableHeadRow>\n    </StyledTableHead>\n  );\n};\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/TableHead/styled.ts",
    "content": "import styled from 'styled-components';\nimport { LIGHT_TEXT_COLOR, DASHBOARD_HEADER_BG_COLOR } from 'appConstants/colors';\n\nexport const StyledTableHead = styled.div`\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  margin-right: 10px;\n  padding: 10px 20px;\n  color: ${LIGHT_TEXT_COLOR};\n  background-color: ${DASHBOARD_HEADER_BG_COLOR};\n  border-radius: 10px;\n  @media (max-width: 768px) {\n    padding: 10px;\n  }\n  @media (max-width: 440px) {\n    padding: 5px;\n  }\n`;\n\nexport const StyledTableHeadRow = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 100%;\n`;\n\nexport const StyledTableHeader = styled.div`\n  max-width: 140px;\n  height: auto;\n  margin: 0;\n  font-weight: 600;\n  line-height: 150%;\n  text-align: start;\n`;\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/components/index.ts",
    "content": "export { TableBody } from './TableBody';\nexport { TableHead } from './TableHead';\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { TableBody, TableHead } from './components';\nimport { StyledTable } from './styled';\nimport { User } from 'types';\n\ntype DashboardProps = {\n  users: User[];\n  page: number;\n};\n\nexport const Dashboard: FC<DashboardProps> = ({ users, page }) => {\n  return (\n    <StyledTable>\n      <TableHead />\n      <TableBody {...{ users, page }} />\n    </StyledTable>\n  );\n};\n"
  },
  {
    "path": "src/modules/StudentsTable/components/Dashboard/styled.ts",
    "content": "import styled from 'styled-components';\nimport { WHITE_COLOR } from 'appConstants/colors';\nimport { GeneralAdaptiveFont } from 'typography';\n\nexport const StyledTable = styled.div`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  max-width: 1320px;\n  height: 75vh;\n  margin: 0 auto;\n  padding: 10px;\n  padding-right: 0;\n  font-size: 1rem;\n  background-color: ${WHITE_COLOR};\n  border-radius: 20px;\n  ${GeneralAdaptiveFont};\n`;\n"
  },
  {
    "path": "src/modules/StudentsTable/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { USERS_PER_PAGE } from 'appConstants';\nimport { Loader, Pagination, FilterForm, ErrorModal } from 'components';\nimport { useUsersQuery } from 'hooks/graphql';\nimport { selectCurrCourse } from 'modules/LoginPage/selectors';\nimport { Dashboard } from './components/Dashboard';\nimport { StudentTableWrapper, TableTitle } from './styled';\nimport { TeamsTitleWrapper } from 'modules/TeamsList/styled';\nimport { FilterButton } from 'components/FilterForm/styled';\nimport filterIcon from 'assets/svg/filterIcon.svg';\nimport crossIcon from 'assets/svg/cross.svg';\nimport { WHITE_COLOR } from 'appConstants/colors';\nimport { defaultFilterData, filterSelectFields } from 'components/FilterForm/filterFormFields';\nimport { selectFilterData } from './selectors';\nimport { TFilterForm } from 'types';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { setFilterData } from './studentsTableReducer';\nimport { ContentPageWrapper } from 'typography';\n\nexport const StudentsTable: FC = () => {\n  const [page, setPage] = useState<number>(0);\n  const [isFilterOpen, setIsFilterOpen] = useState(false);\n  const [inputValues, setInputValues] = useState<TFilterForm>(defaultFilterData);\n  const { t } = useTranslation();\n  const { register, handleSubmit, errors, reset } = useForm<TFilterForm>({\n    defaultValues: inputValues,\n    mode: 'onChange',\n  });\n\n  const dispatch = useDispatch();\n\n  const currCourse = useSelector(selectCurrCourse);\n  const filterData = useSelector(selectFilterData);\n\n  const { loadingU, errorU, users } = useUsersQuery({\n    filter: {\n      ...filterData,\n      sortingOrder: (\n        filterSelectFields[0][1].find((item) => item[0] === filterData.sortingOrder) as string[]\n      )[1],\n      teamFilter: (\n        filterSelectFields[1][1].find((item) => item[0] === filterData.teamFilter) as [\n          string,\n          boolean\n        ]\n      )[1],\n    },\n    reactCourseId: currCourse.id,\n    page,\n  });\n\n  const loading = loadingU;\n  const error = errorU;\n\n  if (error) return <ErrorModal error={error} />;\n  if (loading) return <Loader />;\n\n  const pageCount: number = Math.ceil(users.count / USERS_PER_PAGE);\n  const isValuesEqual =\n    Object.values(defaultFilterData).toString() !== Object.values(filterData).toString();\n  const onClickClearBtnHandler = () => {\n    setInputValues(defaultFilterData);\n    dispatch(setFilterData(defaultFilterData));\n    setPage(0);\n    setIsFilterOpen(false);\n  };\n  const onClickOpenFilterBtnHandler = () => {\n    setIsFilterOpen(!isFilterOpen);\n    reset(filterData);\n    setInputValues(filterData);\n  };\n\n  return (\n    <ContentPageWrapper>\n      <StudentTableWrapper>\n        <TeamsTitleWrapper>\n          <TableTitle>{t('Dashboard')}</TableTitle>\n          {isValuesEqual && !isFilterOpen && (\n            <FilterButton clearBtn outerBtn onClick={onClickClearBtnHandler}>\n              {<img src={crossIcon} alt=\"clear filter icon\" />}\n              {t('Clear filter')}\n            </FilterButton>\n          )}\n          <FilterButton\n            onClick={onClickOpenFilterBtnHandler}\n            bgColor={WHITE_COLOR}\n            className=\"seventhStep\"\n          >\n            {<img src={filterIcon} alt=\"Filter icon\" />} {t('Filter')}\n          </FilterButton>\n          {isFilterOpen && (\n            <FilterForm\n              {...{\n                inputValues,\n                setInputValues,\n                setIsFilterOpen,\n                setPage,\n                register,\n                handleSubmit,\n                errors,\n                reset,\n              }}\n            />\n          )}\n        </TeamsTitleWrapper>\n        <Dashboard users={users.results} page={page} />\n        {!!users.results.length && (\n          <Pagination pageCount={pageCount} changePage={setPage} page={page} />\n        )}\n      </StudentTableWrapper>\n    </ContentPageWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/StudentsTable/selectors.ts",
    "content": "import { State } from 'types';\n\nexport const selectUserData = (state: State) => state.studentsTableReducer.userData;\n\nexport const selectFilterData = (state: State) => state.studentsTableReducer.filterData;\n"
  },
  {
    "path": "src/modules/StudentsTable/studentsTableReducer.ts",
    "content": "import { SET_USER_DATA, SET_FILTER_DATA } from 'appConstants';\nimport { StateStudentsTable } from 'types';\nimport { defaultFilterData } from 'components/FilterForm/filterFormFields';\nimport { createActions, handleActions } from 'redux-actions';\n\nexport const studentsTableState = {\n  userData: {\n    id: '',\n    firstName: '',\n    lastName: '',\n    github: '',\n    telegram: null,\n    discord: '',\n    score: 1000,\n    country: '',\n    city: '',\n    avatar: '',\n    isAdmin: false,\n    courses: [],\n    email: '',\n    courseIds: [''],\n    teamIds: [''],\n    teams: [],\n  },\n  filterData: defaultFilterData,\n};\n\nexport const { setUserData, setFilterData } = createActions({\n  SET_USER_DATA: (userData) => ({ userData }),\n  SET_FILTER_DATA: (filterData) => ({ filterData }),\n});\n\nexport const studentsTableReducer = handleActions<StateStudentsTable, any>(\n  {\n    [SET_USER_DATA]: (state, { payload: { userData } }) => ({\n      ...state,\n      userData,\n    }),\n    [SET_FILTER_DATA]: (state, { payload: { filterData } }) => ({\n      ...state,\n      filterData,\n    }),\n  },\n  studentsTableState\n);\n"
  },
  {
    "path": "src/modules/StudentsTable/styled.ts",
    "content": "import styled from 'styled-components';\nimport { DARK_TEXT_COLOR } from 'appConstants/colors';\nimport { ScrollBar } from 'typography';\n\nexport const StudentTableWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  width: 100%;\n  height: fit-content;\n  max-width: 1440px;\n  padding: 0 4% 60px;\n  overflow-y: scroll;\n  ${ScrollBar};\n  @media screen and (max-width: 768px) {\n    padding-bottom: 50px;\n  }\n`;\n\nexport const TableTitle = styled.h1`\n  align-self: flex-start;\n  width: 80%;\n  margin: 40px 0;\n  font: 700 30px/45px 'Poppins', sans-serif;\n  color: ${DARK_TEXT_COLOR};\n\n  @media (max-width: 1200px) {\n    font-size: 26px;\n    line-height: 35px;\n  }\n  @media (max-width: 992px) {\n    margin: 35px 0;\n    font-size: 24px;\n    line-height: 30px;\n  }\n  @media (max-width: 768px) {\n    margin: 30px 0;\n    font-size: 22px;\n    line-height: 25px;\n  }\n  @media (max-width: 550px) {\n    margin: 30px 0;\n    font-size: 20px;\n    line-height: 25px;\n  }\n  @media (max-width: 440px) {\n    margin: 20px 0;\n    font-size: 17px;\n    line-height: 20px;\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/TeamListModals/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { ModalExpel, ModalJoin, ModalCreateEditTeam, ModalCreated } from 'components';\nimport { MODAL_INPUT_VALIDATION } from 'appConstants';\nimport {\n  selectIsActiveModalCreated,\n  selectIsActiveModalCreateTeam,\n  selectIsActiveModalExpel,\n  selectIsActiveModalJoin,\n  selectIsActiveModalLeave,\n  selectIsActiveModalRemoveCourse,\n  selectIsActiveModalUpdateSocialLink,\n  selectSocialLink,\n  selectTeamPassword,\n} from '../../selectors';\nimport { Team, User } from 'types';\nimport { setUserData } from 'modules/StudentsTable/studentsTableReducer';\nimport {\n  setSocialLink,\n  setTeamPassword,\n  activeModalExpel,\n  activeModalLeave,\n  activeModalJoin,\n  activeModalCreateTeam,\n  activeModalCreated,\n  activeModalUpdateSocialLink,\n  activeModalRemoveCourse,\n} from 'modules/TeamsList/teamsListReducer';\n\ntype TeamListModalsProps = {\n  addUserToTeam: any;\n  removeUserFromTeam: any;\n  expelUserFromTeam: any;\n  createTeam: any;\n  updateTeam: any;\n  removeUserFromCourse: any;\n};\n\nexport const TeamListModals: FC<TeamListModalsProps> = ({\n  addUserToTeam,\n  removeUserFromTeam,\n  expelUserFromTeam,\n  createTeam,\n  updateTeam,\n  removeUserFromCourse,\n}) => {\n  const [textJoinModal, setTextJoinModal] = useState<string>('Please, enter your team password.');\n  const dispatch = useDispatch();\n  const isActiveModalExpel = useSelector(selectIsActiveModalExpel);\n  const isActiveModalLeave = useSelector(selectIsActiveModalLeave);\n  const isActiveModalJoin = useSelector(selectIsActiveModalJoin);\n  const isActiveModalCreateTeam = useSelector(selectIsActiveModalCreateTeam);\n  const isActiveModalCreated = useSelector(selectIsActiveModalCreated);\n  const isActiveModalUpdateSocialLink = useSelector(selectIsActiveModalUpdateSocialLink);\n  const isActiveModalRemoveCourse = useSelector(selectIsActiveModalRemoveCourse);\n  const teamPassword = useSelector(selectTeamPassword);\n  const socialLink = useSelector(selectSocialLink);\n\n  const onSubmitJoinModal = async (e: string) => {\n    addUserToTeam().then(({ data: { addUserToTeam } }: { data: { addUserToTeam: User } }) => {\n      const isPasswordIncorrect =\n        !addUserToTeam.teams || !addUserToTeam.teams.find((team: Team) => team.password === e);\n      if (isPasswordIncorrect) {\n        setTextJoinModal('Wrong password!');\n      } else {\n        setTextJoinModal('Please, enter your team password.');\n        dispatch(setUserData(addUserToTeam));\n        dispatch(activeModalJoin(false));\n        dispatch(setTeamPassword(''));\n      }\n    });\n  };\n\n  const onSubmitLeaveModal = () => {\n    removeUserFromTeam().then(\n      ({ data: { removeUserFromTeam } }: { data: { removeUserFromTeam: User } }) => {\n        dispatch(setUserData(removeUserFromTeam));\n      }\n    );\n  };\n\n  const onSubmitExpelModal = () => {\n    expelUserFromTeam();\n  };\n\n  const onSubmitRemoveCourseModal = () => {\n    removeUserFromCourse();\n  };\n\n  const onSubmitCreateTeam = () => {\n    createTeam().then(({ data: { createTeam } }: { data: { createTeam: Team } }) => {\n      dispatch(setTeamPassword(createTeam.password));\n      dispatch(activeModalCreated(true));\n    });\n  };\n\n  const onSubmitUpdateSocialLink = () => {\n    updateTeam();\n  };\n\n  return (\n    <>\n      <ModalExpel\n        title=\"Leave team\"\n        text=\"Are you sure want to leave team?\"\n        open={isActiveModalLeave}\n        onSubmit={onSubmitLeaveModal}\n        onClose={() => dispatch(activeModalLeave(false))}\n        okText=\"Yes\"\n        cancelText=\"No\"\n      />\n      <ModalExpel\n        title=\"Expel User\"\n        text=\"Are you sure want to expel user?\"\n        open={isActiveModalExpel}\n        onSubmit={onSubmitExpelModal}\n        onClose={() => dispatch(activeModalExpel(false))}\n        okText=\"Yes\"\n        cancelText=\"No\"\n      />\n      <ModalExpel\n        title=\"Leave course\"\n        text=\"Are you sure to leave this course?\"\n        open={isActiveModalRemoveCourse}\n        onSubmit={onSubmitRemoveCourseModal}\n        onClose={() => dispatch(activeModalRemoveCourse(false))}\n        okText=\"Yes\"\n        cancelText=\"No\"\n      />\n      {/*Create team*/}\n      <ModalCreateEditTeam\n        title=\"Create team\"\n        text=\"Please, enter your team telegram / discord / viber / ets. group link.\"\n        open={isActiveModalCreateTeam}\n        value={socialLink}\n        onSubmit={onSubmitCreateTeam}\n        onClose={() => {\n          dispatch(activeModalCreateTeam(false));\n          dispatch(setSocialLink(''));\n        }}\n        okText=\"Create team\"\n        validateRules={MODAL_INPUT_VALIDATION}\n      />\n      <ModalJoin\n        title=\"Join team\"\n        text={textJoinModal}\n        open={isActiveModalJoin}\n        onSubmit={onSubmitJoinModal}\n        value={teamPassword}\n        onChange={() => setTextJoinModal('Please, enter your team password.')}\n        onClose={() => {\n          setTextJoinModal('Please, enter your team password.');\n          dispatch(activeModalJoin(false));\n          dispatch(setTeamPassword(''));\n        }}\n        okText=\"Join team\"\n      />\n      <ModalCreated\n        title=\"New team created!\"\n        text=\"You are automatically added there.\"\n        text2=\"If you want to invite friends - tell them your team password:\"\n        open={isActiveModalCreated}\n        onClose={() => dispatch(activeModalCreated(false))}\n        cancelText=\"Got it!\"\n        password={teamPassword}\n      />\n      {/*Edit Team*/}\n      <ModalCreateEditTeam\n        title=\"Link to group\"\n        text=\"Please, enter new group link.\"\n        open={isActiveModalUpdateSocialLink}\n        value={socialLink}\n        onSubmit={onSubmitUpdateSocialLink}\n        validateRules={MODAL_INPUT_VALIDATION}\n        onClose={() => {\n          dispatch(activeModalUpdateSocialLink(false));\n          dispatch(setSocialLink(''));\n        }}\n        okText=\"Update link\"\n      />\n    </>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/TeamListModals/useCommonMutations.ts",
    "content": "import { useSelector } from 'react-redux';\nimport { selectSocialLink, selectTeamMemberExpelId, selectTeamPassword } from '../../selectors';\nimport { Team } from 'types';\nimport {\n  useAddUserToTeamMutation,\n  useRemoveUserFromTeamMutation,\n  useExpelUserFromTeamMutation,\n  useCreateTeamMutation,\n  useUpdateTeamMutation,\n  useRemoveUserFromCourseMutation,\n} from 'hooks/graphql';\nimport { selectCurrCourse } from 'modules/LoginPage/selectors';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\n\nexport const useCommonMutations = (page: number) => {\n  const currCourse = useSelector(selectCurrCourse);\n  const userData = useSelector(selectUserData);\n  const teamMemberId = useSelector(selectTeamMemberExpelId);\n  const teamPassword = useSelector(selectTeamPassword);\n  const socialLink = useSelector(selectSocialLink);\n\n  const { addUserToTeam, errorM: errorAdd } = useAddUserToTeamMutation({\n    data: {\n      userId: userData.id,\n      courseId: currCourse.id,\n      teamPassword,\n    },\n  });\n\n  const {\n    removeUserFromTeam,\n    errorM: errorRemoveTeam,\n    loadingM: loadingRemoveTeam,\n  } = useRemoveUserFromTeamMutation({\n    data: {\n      teamId: userData.teams.find((team: Team) => team.courseId === currCourse.id)?.id ?? '',\n      userId: userData.id,\n      courseId: currCourse.id,\n      page,\n    },\n  });\n\n  const {\n    expelUserFromTeam,\n    errorM: errorExpel,\n    loadingM: loadingExpel,\n  } = useExpelUserFromTeamMutation({\n    data: {\n      teamId: userData.teams.find((team: Team) => team.courseId === currCourse.id)?.id ?? '',\n      userId: teamMemberId,\n      courseId: currCourse.id,\n      page,\n    },\n  });\n\n  const {\n    createTeam,\n    errorM: errorCreateTeam,\n    loadingM: loadingCreateTeam,\n  } = useCreateTeamMutation({\n    team: {\n      socialLink,\n      courseId: currCourse.id,\n      ownerId: userData.id,\n      page,\n    },\n  });\n\n  const {\n    updateTeam,\n    errorM: errorUpdateTeam,\n    loadingM: loadingUpdateTeam,\n  } = useUpdateTeamMutation({\n    team: {\n      socialLink,\n      id: userData.teams.find((team: Team) => team.courseId === currCourse.id)?.id ?? '',\n    },\n  });\n\n  const {\n    removeUserFromCourse,\n    errorM: errorRemoveCourse,\n    loadingM: loadingRemoveCourse,\n  } = useRemoveUserFromCourseMutation({\n    data: {\n      courseId: currCourse.id,\n      userId: userData.id,\n      teamId: userData.teams.find((team: Team) => team.courseId === currCourse.id)?.id ?? null,\n      page,\n    },\n  });\n\n  const commonMutationError = [\n    errorAdd,\n    errorCreateTeam,\n    errorExpel,\n    errorRemoveCourse,\n    errorRemoveTeam,\n    errorUpdateTeam,\n  ].find((item) => !!item);\n\n  const isLoading = [\n    loadingCreateTeam,\n    loadingExpel,\n    loadingRemoveCourse,\n    loadingRemoveTeam,\n    loadingUpdateTeam,\n  ].some((item) => !!item);\n\n  return {\n    addUserToTeam,\n    removeUserFromTeam,\n    expelUserFromTeam,\n    createTeam,\n    updateTeam,\n    removeUserFromCourse,\n    commonMutationError,\n    isLoading,\n  };\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MemberListToggle/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { MembersListToggleStyled, Chevron } from './styled';\nimport { ReactComponent as ChevronArrow } from 'assets/svg/chevron-arrow.svg';\nimport { useTranslation } from 'react-i18next';\n\ntype MembersListToggle = {\n  countMembers: number;\n  isOpen: boolean;\n  onToggleList: () => void;\n  color?: string;\n};\n\nexport const MembersListToggle: FC<MembersListToggle> = ({\n  countMembers,\n  isOpen,\n  onToggleList,\n  color,\n}) => {\n  const { t } = useTranslation();\n  return (\n    <MembersListToggleStyled\n      onClick={() => {\n        !!countMembers && onToggleList();\n      }}\n      color={color}\n    >\n      <div>\n        {countMembers || 0} {countMembers === 1 ? t('member') : t('members')}\n      </div>\n      <Chevron open={isOpen}>\n        <ChevronArrow />\n      </Chevron>\n    </MembersListToggleStyled>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MemberListToggle/styled.ts",
    "content": "import styled from 'styled-components';\nimport { WHITE_COLOR } from 'appConstants/colors';\nimport { SVGArrowAdaptive } from 'typography';\n\ntype ChevronProps = {\n  open: boolean;\n};\n\nexport const MembersListToggleStyled = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 134px;\n  cursor: pointer;\n  color: ${({ color }) => color || WHITE_COLOR};\n\n  path {\n    stroke: currentColor;\n  }\n\n  @media (max-width: 992px) {\n    width: 115px;\n  }\n  @media (max-width: 768px) {\n    width: 105px;\n  }\n  @media (max-width: 440px) {\n    width: 85px;\n  }\n`;\n\nexport const Chevron = styled.div<ChevronProps>`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  transform: rotateX(${({ open }) => (open ? '180deg' : '0deg')});\n  margin-left: 10px;\n  transition: all 0.3s;\n\n  svg {\n    ${SVGArrowAdaptive};\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/components/MyTeamInfoBlock/components/MyTeamInfoLine/index.tsx",
    "content": "import React, { FC, MouseEvent, useState } from 'react';\nimport { InfoLineStyled, CopyClipboardButton } from './styled';\nimport { TablePopup } from 'components/TablePopup';\n\ntype MyTeamInfoLine = {\n  value?: string;\n  hoverHandler?: () => void;\n};\n\nexport const MyTeamInfoLine: FC<MyTeamInfoLine> = ({ value }) => {\n  const [showPopup, setShowPopup] = useState(false);\n  const [isCopy, setIsCopy] = useState(false);\n  const copyInfo = (value: string) => {\n    navigator.clipboard\n      .writeText(value)\n      .then(() => {\n        setIsCopy(true);\n        setTimeout(() => {\n          setIsCopy(false);\n        }, 1000);\n      })\n      .catch((err) => {\n        console.log(err);\n      });\n  };\n\n  const mouseOverHandler = (event: MouseEvent<HTMLElement>) => {\n    const target = event.target as HTMLDivElement;\n    if (target.scrollWidth !== target.clientWidth) {\n      setShowPopup(true);\n    }\n  };\n\n  const currValue: string = value || '';\n  return (\n    <InfoLineStyled blink={isCopy}>\n      <div\n        className={'info__text'}\n        onMouseOver={mouseOverHandler}\n        onMouseLeave={() => setShowPopup(false)}\n      >\n        {currValue}\n      </div>\n      {showPopup && <TablePopup dataLength={0} popupElements={[currValue]} />}\n      <CopyClipboardButton onClick={() => copyInfo(currValue)} />\n    </InfoLineStyled>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/components/MyTeamInfoBlock/components/MyTeamInfoLine/styled.tsx",
    "content": "import styled from 'styled-components';\nimport { WHITE_COLOR } from 'appConstants/colors';\nimport { TextBold, GeneralAdaptiveFont, SVGParamsAdaptive } from 'typography';\nimport { ReactComponent as CopyIcon } from 'assets/svg/copy.svg';\n\ntype TInfoLineStyled = {\n  blink: boolean;\n};\n\nexport const InfoLineStyled = styled.div<TInfoLineStyled>`\n  ${TextBold};\n  color: ${WHITE_COLOR};\n  display: flex;\n  align-items: center;\n  border-radius: 5px;\n\n  .info__text {\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    animation: ${({ blink }) => (blink ? 'blink 1s' : 'none')};\n    border-radius: 3px;\n    padding: 0 7px;\n    margin-left: -7px;\n    ${GeneralAdaptiveFont};\n  }\n\n  @keyframes blink {\n    from {\n      background: rgb(101, 80, 246, 0.5);\n    }\n    to {\n      background: rgba(101, 80, 246, 0);\n    }\n  }\n`;\n\nexport const CopyClipboardButton = styled(CopyIcon)`\n  cursor: pointer;\n  margin-left: 3px;\n  ${SVGParamsAdaptive};\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/components/MyTeamInfoBlock/components/NotificationPopup/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { NotificationPopupStyled } from './styled';\n\nconst NotificationPopup: FC = ({ children }) => {\n  return <NotificationPopupStyled>{children}</NotificationPopupStyled>;\n};\n\nexport default NotificationPopup;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/components/MyTeamInfoBlock/components/NotificationPopup/styled.ts",
    "content": "import styled from 'styled-components';\nimport { LIGHT_TEXT_COLOR, WHITE_COLOR } from 'appConstants/colors';\n\nexport const NotificationPopupStyled = styled.div`\n  position: absolute;\n  top: 153%;\n  right: 0;\n  width: 240px;\n  background-color: ${WHITE_COLOR};\n  color: ${LIGHT_TEXT_COLOR};\n  border-radius: 10px;\n  padding: 20px 20px;\n  z-index: 1;\n\n  &::after {\n    content: '';\n    position: absolute;\n    top: 0;\n    right: 8px;\n    transform: rotateZ(59deg) skew(33deg);\n    height: 22px;\n    width: 22px;\n    border-radius: 4px;\n    background-color: ${WHITE_COLOR};\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/components/MyTeamInfoBlock/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { StyledMyTeamInfoBlock, InfoButton } from './styled';\nimport { MyTeamInfoLine } from './components/MyTeamInfoLine';\nimport { ReactComponent as InfoIcon } from 'assets/svg/info.svg';\nimport { ReactComponent as EditIcon } from 'assets/svg/edit.svg';\nimport NotificationPopup from './components/NotificationPopup';\nimport { useTranslation } from 'react-i18next';\nimport { activeModalUpdateSocialLink } from 'modules/TeamsList/teamsListReducer';\n\ntype MyTeamInfoBlockProps = {\n  title: string;\n  icon: 'info' | 'edit';\n  value: string;\n};\n\nexport const MyTeamInfoBlock: FC<MyTeamInfoBlockProps> = ({ title, icon, value }) => {\n  const dispatch = useDispatch();\n  const [hover, setHover] = useState(false);\n  const { t } = useTranslation();\n  return (\n    <StyledMyTeamInfoBlock>\n      <div className=\"infoBlock__title\">{t(title)}</div>\n      <MyTeamInfoLine value={value} />\n      {icon === 'info' ? (\n        <InfoButton onMouseOver={() => setHover(true)} onMouseOut={() => setHover(false)}>\n          <InfoIcon />\n          {hover && (\n            <NotificationPopup>{t('The password is required to join the team.')}</NotificationPopup>\n          )}\n        </InfoButton>\n      ) : (\n        <InfoButton onClick={() => dispatch(activeModalUpdateSocialLink(true))}>\n          <EditIcon />\n        </InfoButton>\n      )}\n    </StyledMyTeamInfoBlock>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/components/MyTeamInfoBlock/styled.ts",
    "content": "import styled, { css } from 'styled-components';\nimport { WHITE_COLOR, MAIN2_LIGHT_COLOR, MAIN2_COLOR } from 'appConstants/colors';\nimport { TextRegular, GeneralAdaptiveFont, SVGParamsAdaptive } from 'typography';\n\nexport const StyledMyTeamInfoBlock = styled.div`\n  position: relative;\n  max-width: 300px;\n  width: 100%;\n  border-radius: 10px;\n  padding: 20px;\n  color: ${WHITE_COLOR};\n  background-color: ${MAIN2_LIGHT_COLOR};\n\n  .infoBlock__title {\n    ${TextRegular};\n    color: ${WHITE_COLOR};\n    margin-bottom: 10px;\n    ${GeneralAdaptiveFont};\n  }\n\n  @media (max-width: 992px) {\n    max-width: 50%;\n  }\n  @media (max-width: 580px) {\n    max-width: 100%;\n  }\n`;\n\nconst InfoBlockButton = css`\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 32px;\n  height: 32px;\n  padding: 8px;\n  background: ${MAIN2_COLOR};\n  fill: ${WHITE_COLOR};\n  cursor: pointer;\n  border-radius: 5px;\n`;\n\nexport const InfoButton = styled.div`\n  ${InfoBlockButton};\n\n  svg {\n    ${SVGParamsAdaptive};\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { StyledMyTeam, HeaderDecor, TableWrapper } from './styled';\nimport { TeamButton } from 'typography';\nimport { DARK_TEXT_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { Team } from 'types';\nimport { MembersListToggle } from '../MemberListToggle';\nimport { MyTeamInfoBlock } from './components/MyTeamInfoBlock';\nimport { TeamUserTable } from '../TeamUserTable';\nimport { useTranslation } from 'react-i18next';\nimport { activeModalLeave, activeModalRemoveCourse } from 'modules/TeamsList/teamsListReducer';\n\ntype MyTeamProps = {\n  team: Team;\n  userId: string;\n};\n\nexport const MyTeam: FC<MyTeamProps> = ({ team, userId }) => {\n  const [isOpen, setOpenState] = useState(false);\n  const { t } = useTranslation();\n\n  const dispatch = useDispatch();\n  const toggleListHandler = () => setOpenState(!isOpen);\n  const leaveTeam = () => dispatch(activeModalLeave(true));\n  const removeCourse = () => dispatch(activeModalRemoveCourse(true));\n\n  const countMember = team?.members?.length;\n  return (\n    <StyledMyTeam open={isOpen}>\n      <div className=\"myTeam__header\">\n        <h2 className=\"myTeam__title\">\n          {t('My team - Team')} {team.number}\n        </h2>\n        <div className=\"myTeam__info-wrapper\">\n          <MyTeamInfoBlock title=\"Invitation password\" value={team.password} icon=\"info\" />\n          <MyTeamInfoBlock title=\"Link to group\" value={team.socialLink} icon=\"edit\" />\n        </div>\n        <div className=\"myTeam__leave\">\n          <TeamButton\n            bgc={WHITE_COLOR}\n            color={DARK_TEXT_COLOR}\n            type=\"button\"\n            onClick={removeCourse}\n          >\n            {t('Leave course')}\n          </TeamButton>\n        </div>\n        <div className=\"myTeam__button\">\n          <TeamButton bgc={WHITE_COLOR} color={DARK_TEXT_COLOR} type=\"button\" onClick={leaveTeam}>\n            {t('Leave team')}\n          </TeamButton>\n        </div>\n        <div className=\"myTeam__toggle\">\n          <MembersListToggle\n            isOpen={isOpen}\n            countMembers={countMember}\n            onToggleList={toggleListHandler}\n          />\n        </div>\n        <HeaderDecor />\n      </div>\n      <TableWrapper open={isOpen}>\n        {isOpen && <TeamUserTable members={team.members} isMyTeam userId={userId} />}\n      </TableWrapper>\n    </StyledMyTeam>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/MyTeam/styled.ts",
    "content": "import styled from 'styled-components';\nimport { ReactComponent as HeaderDecoration } from 'assets/svg/team-header-decorations.svg';\nimport { MAIN2_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { PageSubTitle } from 'typography';\n\ntype StyledMyTeamProps = {\n  open: boolean;\n};\n\ntype TableWrapperProps = {\n  open: boolean;\n};\n\nexport const StyledMyTeam = styled.div<StyledMyTeamProps>`\n  margin-bottom: 40px;\n\n  .myTeam__header {\n    position: relative;\n    color: ${WHITE_COLOR};\n    background-color: ${MAIN2_COLOR};\n    border-radius: 20px;\n    z-index: 0;\n    padding: 30px;\n    display: grid;\n    grid-template-columns: 1fr 215px 215px;\n    grid-template-rows: auto 1fr;\n    grid-template-areas: 'title leave button' 'info info toggle';\n\n    @media (max-width: 992px) {\n      grid-template-columns: 1fr 200px 200px;\n      grid-template-rows: auto auto auto;\n      grid-template-areas: 'title leave button' 'info info info' 'toggle toggle toggle';\n      font-size: 0.9rem;\n    }\n\n    @media (max-width: 650px) {\n      grid-template-columns: 1fr 100px 187px;\n      grid-template-rows: auto auto auto auto;\n      grid-template-areas: 'title title button' 'title title leave' 'info info info' 'toggle toggle toggle';\n      font-size: 0.825rem;\n    }\n\n    @media (max-width: 440px) {\n      grid-template-columns: 1fr 115px 160px;\n      font-size: 0.68rem;\n    }\n\n    @media (max-width: 350px) {\n      padding: 20px;\n      grid-template-columns: 1fr 60px 145px;\n      grid-template-rows: auto auto auto auto;\n    }\n\n    @media (max-width: 580px) {\n      overflow: hidden;\n    }\n\n    .myTeam__title {\n      grid-area: title;\n      ${PageSubTitle};\n      margin: 5px 0 37px;\n      @media (max-width: 550px) {\n        font-size: 0.9rem;\n      }\n    }\n\n    .myTeam__info-wrapper {\n      grid-area: info;\n      display: flex;\n      gap: 30px;\n\n      @media (max-width: 580px) {\n        flex-direction: column;\n      }\n    }\n    .myTeam__leave,\n    .myTeam__button {\n      display: flex;\n      justify-content: flex-end;\n      align-items: flex-start;\n      margin: 0 0 10px 10px;\n      button {\n        width: 100%;\n      }\n      @media (max-width: 650px) {\n        margin: 0 0 10px;\n      }\n      @media (max-width: 440px) {\n        margin: 0 0 10px 10px;\n      }\n    }\n    .myTeam__leave {\n      grid-area: leave;\n    }\n    .myTeam__button {\n      grid-area: button;\n    }\n    .myTeam__toggle {\n      grid-area: toggle;\n      display: flex;\n      justify-content: flex-end;\n      align-items: flex-end;\n      @media (max-width: 992px) {\n        margin-top: 20px;\n      }\n    }\n  }\n\n  .myTeam__table-wrapper {\n    background-color: ${WHITE_COLOR};\n    margin-bottom: ${({ open }) => (open ? '40px' : '0')};\n    margin-top: ${({ open }) => (open ? '-20px' : '0')};\n    ${({ open }) => (open ? 'padding: 60px 30px 30px' : null)};\n    border-bottom-left-radius: 20px;\n    border-bottom-right-radius: 20px;\n    transition: all 0.3s;\n  }\n`;\n\nexport const TableWrapper = styled.div<TableWrapperProps>`\n  background-color: ${WHITE_COLOR};\n  margin-bottom: ${({ open }) => (open ? '40px' : '0')};\n  margin-top: ${({ open }) => (open ? '-20px' : '0')};\n  ${({ open }) => (open ? 'padding: 60px 30px 30px' : null)};\n  border-bottom-left-radius: 20px;\n  border-bottom-right-radius: 20px;\n  transition: all 0.3s;\n\n  @media screen and (max-width: 768px) {\n    overflow-x: ${({ open }) => (open ? 'scroll' : 'auto')};\n  }\n\n  @media (max-width: 440px) {\n    ${({ open }) => (open ? 'padding: 40px 15px 30px' : null)};\n  }\n`;\n\nexport const HeaderDecor = styled(HeaderDecoration)`\n  top: 0;\n  width: 220px;\n  height: 160px;\n  position: absolute;\n  right: 0;\n  z-index: -1;\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamItem/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { TeamItemStyled, TeamItemTableWrapper } from './styled';\nimport { User } from 'types';\nimport { MembersListToggle } from '../MemberListToggle';\nimport { LIGHT_TEXT_COLOR } from 'appConstants/colors';\nimport { TeamUserTable } from '../TeamUserTable';\n\ntype TeamItemProps = {\n  name: string;\n  description?: string;\n  countMember: number;\n  members: User[];\n};\n\nexport const TeamItem: FC<TeamItemProps> = ({ name, countMember, description, members }) => {\n  const [isOpen, setToggle] = useState(false);\n  const toggleListHandler = () => {\n    setToggle(!isOpen);\n  };\n  return (\n    <TeamItemStyled>\n      <div className=\"teamItem__header\">\n        <div className=\"teamItem__name\">{name}</div>\n        {description && <div className=\"teamItem__description\">{description}</div>}\n        <MembersListToggle\n          countMembers={countMember}\n          isOpen={isOpen}\n          onToggleList={toggleListHandler}\n          color={LIGHT_TEXT_COLOR}\n        />\n      </div>\n      <TeamItemTableWrapper open={isOpen}>\n        {isOpen && <TeamUserTable members={members} secondTable />}\n      </TeamItemTableWrapper>\n    </TeamItemStyled>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamItem/styled.tsx",
    "content": "import styled from 'styled-components';\nimport { TextRegular, TextSemiBold, GeneralAdaptiveFont } from 'typography';\nimport { WHITE_COLOR } from 'appConstants/colors';\nimport { TableWrapper } from '../MyTeam/styled';\n\nexport const TeamItemStyled = styled.div`\n  background: ${WHITE_COLOR};\n  border-radius: 20px;\n  margin-bottom: 20px;\n\n  .teamItem__header {\n    padding: 20px 30px;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    ${GeneralAdaptiveFont};\n  }\n\n  .teamItem__name {\n    ${TextSemiBold};\n    ${GeneralAdaptiveFont};\n  }\n  .teamItem__description {\n    ${TextRegular};\n    flex-grow: 1;\n  }\n`;\n\nexport const TeamItemTableWrapper = styled(TableWrapper)`\n  margin-top: ${({ open }) => (open ? '-20px' : '0')};\n  ${({ open }) => (open ? 'padding: 20px 30px 20px' : null)};\n\n  @media (max-width: 440px) {\n    ${({ open }) => (open ? 'padding: 20px 15px 20px' : null)};\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/components/TableRow/components/ExpelButton/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { SmallCrossIcon, StyledExpelButton } from './styled';\n\ntype ExpelButtonProps = {\n  onClickHandler?: () => void;\n};\n\nexport const ExpelButton: FC<ExpelButtonProps> = ({ onClickHandler }) => {\n  return (\n    <StyledExpelButton onClick={onClickHandler}>\n      <SmallCrossIcon />\n      Expel\n    </StyledExpelButton>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/components/TableRow/components/ExpelButton/styled.ts",
    "content": "import styled from 'styled-components';\nimport { ReactComponent as Cross } from 'assets/svg/cross-small.svg';\nimport { MAIN1_COLOR } from 'appConstants/colors';\nimport { SVGArrowAdaptive } from 'typography';\n\ntype StyledExpelButtonProps = {\n  color?: string;\n};\n\nexport const StyledExpelButton = styled.div<StyledExpelButtonProps>`\n  width: 63px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  cursor: pointer;\n  color: ${({ color }) => (color ? color : MAIN1_COLOR)};\n\n  @media (max-width: 550px) {\n    width: 55px;\n  }\n`;\n\nexport const SmallCrossIcon = styled(Cross)`\n  width: 12px;\n  height: 12px;\n  ${SVGArrowAdaptive};\n\n  @media (max-width: 992px) and (min-width: 768px) {\n    width: 11px;\n    height: 11px;\n  }\n\n  path {\n    stroke: currentColor;\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/components/TableRow/components/TableCell/index.tsx",
    "content": "import React, { FC } from 'react';\n\ntype TTableCell = {\n  value: any;\n  isSocialLink?: boolean;\n};\n\nconst formatSocialLinks = (link: string | null): string =>\n  link ? '@' + link.replace('@', '') : '';\n\nexport const TableCell: FC<TTableCell> = ({ value, isSocialLink = false }) => {\n  return <td>{isSocialLink ? formatSocialLinks(value) : value}</td>;\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/components/TableRow/components/index.ts",
    "content": "export { TableCell } from './TableCell';\nexport { ExpelButton } from './ExpelButton';\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/components/TableRow/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { User } from 'types';\nimport { TableCell } from './components';\nimport { ExpelButton } from './components';\nimport { useDispatch } from 'react-redux';\nimport { activeModalExpel, setTeamMemberExpelId } from 'modules/TeamsList/teamsListReducer';\n\ntype TableRowProps = {\n  member: User;\n  count: number;\n  isMyTeam?: boolean;\n  userId?: string;\n  secondTable?: boolean;\n};\n\nexport const TableRow: FC<TableRowProps> = ({\n  member,\n  count,\n  isMyTeam,\n  userId,\n  secondTable = false,\n}) => {\n  const { firstName, lastName, score, telegram, discord, github, country, city, id } = member;\n  const dispatch = useDispatch();\n  return (\n    <tr className={secondTable ? 'SecondTable' : 'FirstTable'}>\n      <TableCell value={count.toString(10)} />\n      <TableCell value={`${firstName} ${lastName}`} />\n      <TableCell value={score} />\n      <TableCell value={telegram} isSocialLink />\n      <TableCell value={discord} isSocialLink />\n      <TableCell value={github} isSocialLink />\n      <TableCell value={`${city}, ${country}`} />\n      {isMyTeam && (\n        <TableCell\n          value={\n            id !== userId && (\n              <ExpelButton\n                onClickHandler={() => {\n                  dispatch(activeModalExpel(true));\n                  dispatch(setTeamMemberExpelId(id));\n                }}\n              />\n            )\n          }\n        />\n      )}\n    </tr>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { StyledTeamUserTable } from './styled';\nimport { User } from 'types';\nimport { TableRow } from './components/TableRow';\nimport { TABLE_TEAMS_HEADERS } from 'appConstants';\nimport { useTranslation } from 'react-i18next';\n\ntype TeamUserTableProps = {\n  members?: User[];\n  isMyTeam?: boolean;\n  userId?: string;\n  secondTable?: boolean;\n};\n\nexport const TeamUserTable: FC<TeamUserTableProps> = ({\n  members,\n  isMyTeam,\n  userId,\n  secondTable = false,\n}) => {\n  const { t } = useTranslation();\n  return (\n    <StyledTeamUserTable>\n      <thead>\n        <tr className={secondTable ? 'SecondTable' : 'FirstTable'}>\n          {TABLE_TEAMS_HEADERS.map((columnName: string) => {\n            return !isMyTeam && columnName === 'Action' ? null : (\n              <th key={columnName}>{t(columnName)}</th>\n            );\n          })}\n        </tr>\n      </thead>\n      <tbody>\n        {members &&\n          members.map((member: User, index: number) => {\n            return (\n              <TableRow\n                key={member.id}\n                count={index + 1}\n                {...{ secondTable, userId, isMyTeam, member }}\n              />\n            );\n          })}\n      </tbody>\n    </StyledTeamUserTable>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamUserTable/styled.tsx",
    "content": "import styled, { css } from 'styled-components';\nimport {\n  DASHBOARD_HEADER_BG_COLOR,\n  LIGHT_TEXT_COLOR,\n  DARK_TEXT_COLOR,\n  BG_COLOR,\n} from 'appConstants/colors';\nimport { TextBold, GeneralAdaptiveFont } from 'typography';\n\nconst AdaptiveFirstCellBorderRadius = css`\n  border-bottom-left-radius: 10px;\n  border-top-left-radius: 10px;\n`;\n\nconst AdaptiveLastCellBorderRadius = css`\n  border-bottom-right-radius: 10px;\n  border-top-right-radius: 10px;\n`;\n\nconst AdaptiveCellVisible = css`\n  &:first-child {\n    ${AdaptiveFirstCellBorderRadius}\n  }\n\n  &:last-child {\n    ${AdaptiveLastCellBorderRadius}\n  }\n\n  @media (max-width: 992px) {\n    &:nth-child(5),\n    &:nth-child(6) {\n      display: none;\n    }\n  }\n  @media (max-width: 650px) {\n    &:nth-child(7) {\n      display: none;\n    }\n  }\n  @media (max-width: 500px) {\n    &:nth-child(3) {\n      display: none;\n    }\n  }\n`;\n\nexport const StyledTeamUserTable = styled.table`\n  width: 100%;\n  border-collapse: collapse;\n  transition: all 0.3s ease-in-out;\n  ${GeneralAdaptiveFont}\n\n  thead {\n    background-color: ${DASHBOARD_HEADER_BG_COLOR};\n    color: ${LIGHT_TEXT_COLOR};\n\n    & .SecondTable th:nth-child(4) {\n      @media (max-width: 650px) {\n        ${AdaptiveLastCellBorderRadius}\n      }\n    }\n\n    & .FirstTable th:nth-child(4) {\n      @media (max-width: 440px) {\n        display: none;\n      }\n    }\n\n    th {\n      padding: 10px;\n      text-align: left;\n      ${AdaptiveCellVisible}\n    }\n  }\n\n  tr.FirstTable td:nth-child(4) {\n    @media (max-width: 440px) {\n      display: none;\n    }\n  }\n\n  tr.SecondTable td:nth-child(4) {\n    @media (max-width: 650px) {\n      ${AdaptiveLastCellBorderRadius}\n    }\n  }\n\n  tr:nth-child(even) {\n    background-color: ${BG_COLOR};\n  }\n  td {\n    color: ${DARK_TEXT_COLOR};\n    padding: 10px;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    max-width: 150px;\n    ${AdaptiveCellVisible}\n\n    &:nth-child(2) {\n      ${TextBold};\n      font-weight: bold;\n      ${GeneralAdaptiveFont}\n    }\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamsHeader/index.tsx",
    "content": "import React, { FC } from 'react';\nimport {\n  TeamsHeaderStyled,\n  TeamsHeaderRightStyled,\n  TeamsHeaderSubtitleStyled,\n  TeamsHeaderButtonsBlockStyled,\n  TeamHeaderLeftStyled,\n  HeaderManPic,\n  TeamHeaderTitle,\n} from './styled';\nimport { TeamButton } from 'typography';\nimport { DARK_TEXT_COLOR, WHITE_COLOR } from 'appConstants/colors';\nimport { useDispatch } from 'react-redux';\nimport { useTranslation } from 'react-i18next';\nimport {\n  activeModalJoin,\n  activeModalCreateTeam,\n  activeModalRemoveCourse,\n} from 'modules/TeamsList/teamsListReducer';\n\nexport const TeamsHeader: FC = () => {\n  const dispatch = useDispatch();\n  const { t } = useTranslation();\n  const buttonsInfo: {\n    name: string;\n    callback: () => void;\n    className: string;\n  }[] = [\n    {\n      name: 'Create team',\n      callback: () => dispatch(activeModalCreateTeam(true)),\n      className: 'secondStep',\n    },\n    {\n      name: 'Join team',\n      callback: () => dispatch(activeModalJoin(true)),\n      className: 'thirdStep',\n    },\n    {\n      name: 'Leave course',\n      callback: () => dispatch(activeModalRemoveCourse(true)),\n      className: 'fourthStep',\n    },\n  ];\n\n  return (\n    <TeamsHeaderStyled>\n      <TeamsHeaderRightStyled>\n        <TeamHeaderTitle>{t('Become a member of the team!')}</TeamHeaderTitle>\n        <TeamsHeaderSubtitleStyled>{t('To become a member')}</TeamsHeaderSubtitleStyled>\n        <TeamsHeaderButtonsBlockStyled>\n          {buttonsInfo.map((item) => {\n            return (\n              <TeamButton\n                bgc={WHITE_COLOR}\n                color={DARK_TEXT_COLOR}\n                type=\"button\"\n                onClick={item.callback}\n                className={item.className}\n                key={JSON.stringify(item)}\n              >\n                {t(item.name)}\n              </TeamButton>\n            );\n          })}\n        </TeamsHeaderButtonsBlockStyled>\n      </TeamsHeaderRightStyled>\n      <TeamHeaderLeftStyled>\n        <HeaderManPic />\n      </TeamHeaderLeftStyled>\n    </TeamsHeaderStyled>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/TeamsHeader/styled.ts",
    "content": "import styled from 'styled-components';\nimport { WHITE_COLOR, MAIN2_COLOR } from 'appConstants/colors';\nimport { ReactComponent as HeaderMan } from 'assets/svg/teams-man.svg';\nimport { PageSubTitle, TextRegular, H2AdaptiveFont, GeneralAdaptiveFont } from 'typography';\n\nexport const TeamsHeaderStyled = styled.div`\n  padding: 30px;\n  position: relative;\n  color: ${WHITE_COLOR};\n  background-color: ${MAIN2_COLOR};\n  border-radius: 20px;\n  z-index: 0;\n  margin-bottom: 40px;\n\n  @media (max-width: 580px) {\n    overflow: hidden;\n  }\n`;\n\nexport const TeamHeaderTitle = styled.h2`\n  ${PageSubTitle};\n  ${H2AdaptiveFont};\n  margin: 5px 0 18px;\n`;\n\nexport const TeamsHeaderRightStyled = styled.div`\n  max-width: 631px;\n  width: 100%;\n`;\n\nexport const TeamsHeaderSubtitleStyled = styled.div`\n  ${TextRegular};\n  ${GeneralAdaptiveFont};\n  color: ${WHITE_COLOR};\n  margin-bottom: 30px;\n`;\n\nexport const TeamsHeaderButtonsBlockStyled = styled.div`\n  display: flex;\n  gap: 20px;\n\n  @media (max-width: 680px) {\n    gap: 10px;\n  }\n\n  @media (max-width: 580px) {\n    flex-direction: column;\n    align-content: center;\n    justify-content: center;\n  }\n`;\n\nexport const TeamHeaderLeftStyled = styled.div`\n  position: absolute;\n  right: 0;\n  top: 0;\n  bottom: 0;\n  max-width: 631px;\n  width: 100%;\n  z-index: -1;\n`;\n\nexport const HeaderManPic = styled(HeaderMan)`\n  position: absolute;\n  right: 40px;\n  bottom: 0;\n  width: 440px;\n  height: 254px;\n  z-index: -1;\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/components/index.ts",
    "content": "export { TeamsHeader } from './TeamsHeader';\nexport { MyTeam } from './MyTeam';\nexport { TeamItem } from './TeamItem';\n"
  },
  {
    "path": "src/modules/TeamsList/components/Teams/index.tsx",
    "content": "import React, { FC } from 'react';\n\nimport { TeamsHeader, MyTeam, TeamItem } from './components';\nimport { Team, TeamList } from 'types';\nimport { TableTitle } from 'modules/StudentsTable/styled';\nimport { TeamsTitleWrapper } from 'modules/TeamsList/styled';\nimport { useTranslation } from 'react-i18next';\n\ntype TeamsProps = {\n  teams: TeamList;\n  myTeam?: Team;\n  userId: string;\n};\n\nexport const Teams: FC<TeamsProps> = ({ teams, myTeam, userId }) => {\n  const { t } = useTranslation();\n  return (\n    <>\n      <TeamsTitleWrapper>\n        <TableTitle>{t('Teams')}</TableTitle>\n      </TeamsTitleWrapper>\n      {myTeam ? <MyTeam team={myTeam} userId={userId} /> : <TeamsHeader />}\n      {!!teams.count &&\n        teams.results.map((team) => (\n          <TeamItem\n            key={team.id}\n            name={`${t('Team')} ${team.number}`}\n            countMember={team.members.length}\n            members={team.members}\n          />\n        ))}\n    </>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/components/index.ts",
    "content": "export { Teams } from './Teams';\nexport { TeamListModals } from './TeamListModals';\n"
  },
  {
    "path": "src/modules/TeamsList/index.tsx",
    "content": "import React, { FC, useState } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { useTeamsQuery } from 'hooks/graphql';\nimport { Loader, ErrorModal, Pagination } from 'components';\nimport { selectUserData } from 'modules/StudentsTable/selectors';\nimport { selectCurrCourse } from 'modules/LoginPage/selectors';\nimport { StyledTeams } from './styled';\nimport { TEAMS_PER_PAGE, TOUR_OPENING } from 'appConstants';\nimport { Team } from 'types';\nimport { TeamListModals, Teams } from './components';\nimport { useCommonMutations } from './components/TeamListModals/useCommonMutations';\nimport { AdditionalWrapper, ContentPageWrapper } from 'typography';\nimport { setIsTourOpen } from 'modules/LoginPage/loginPageReducer';\nimport { setTourOpening } from 'modules/LoginPage/loginPageMiddleware';\n\nexport const TeamsList: FC = () => {\n  const [page, setPage] = useState(0);\n  const currCourse = useSelector(selectCurrCourse);\n  const userData = useSelector(selectUserData);\n  const dispatch = useDispatch();\n  const userTeam = userData.teams?.find((team: Team) => team.courseId === currCourse.id);\n\n  const { loadingT, errorT, teams } = useTeamsQuery({\n    reactCourseId: currCourse.id,\n    page,\n  });\n\n  const loading = loadingT;\n  const error = errorT;\n  const {\n    addUserToTeam,\n    removeUserFromTeam,\n    expelUserFromTeam,\n    createTeam,\n    updateTeam,\n    removeUserFromCourse,\n    commonMutationError,\n    isLoading,\n  } = useCommonMutations(page);\n\n  if (!localStorage.getItem(TOUR_OPENING) && !userTeam) {\n    dispatch(setIsTourOpen(true));\n  }\n  dispatch(setTourOpening(TOUR_OPENING));\n\n  if (error || commonMutationError) return <ErrorModal error={error || commonMutationError} />;\n  if (loading || isLoading) return <Loader />;\n\n  const pageCount: number = Math.ceil(teams.count / TEAMS_PER_PAGE);\n\n  return (\n    <ContentPageWrapper>\n      <StyledTeams>\n        <Teams teams={teams} myTeam={userTeam} userId={userData.id} />\n        {!!teams.results.length && (\n          <Pagination pageCount={pageCount} changePage={setPage} page={page} />\n        )}\n        <AdditionalWrapper />\n      </StyledTeams>\n\n      <TeamListModals\n        {...{\n          addUserToTeam,\n          removeUserFromTeam,\n          expelUserFromTeam,\n          createTeam,\n          updateTeam,\n          removeUserFromCourse,\n        }}\n      />\n    </ContentPageWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/TeamsList/selectors.ts",
    "content": "import { State } from 'types';\n\nexport const selectIsActiveModalExpel = (state: State) => state.teamsListReducer.isActiveModalExpel;\n\nexport const selectIsActiveModalLeave = (state: State) => state.teamsListReducer.isActiveModalLeave;\n\nexport const selectIsActiveModalJoin = (state: State) => state.teamsListReducer.isActiveModalJoin;\n\nexport const selectIsActiveModalCreateTeam = (state: State) =>\n  state.teamsListReducer.isActiveModalCreateTeam;\n\nexport const selectIsActiveModalCreated = (state: State) =>\n  state.teamsListReducer.isActiveModalCreated;\n\nexport const selectIsActiveModalRemoveCourse = (state: State) =>\n  state.teamsListReducer.isActiveModalRemoveCourse;\n\nexport const selectIsActiveModalUpdateSocialLink = (state: State) =>\n  state.teamsListReducer.isActiveModalUpdateSocialLink;\n\nexport const selectIsActiveModalSortStudents = (state: State) =>\n  state.teamsListReducer.isActiveModalSortStudents;\n\nexport const selectIsActiveModalLeavePage = (state: State) =>\n  state.teamsListReducer.isActiveModalLeavePage;\n\nexport const selectIsActiveModalCreatedCourse = (state: State) =>\n  state.teamsListReducer.isActiveModalCreatedCourse;\n\nexport const selectIsActiveModalEditCourse = (state: State) =>\n  state.teamsListReducer.isActiveModalEditCourse;\n\nexport const selectTeamMemberExpelId = (state: State) => state.teamsListReducer.teamMemberExpelId;\n\nexport const selectTeamPassword = (state: State) => state.teamsListReducer.teamPassword;\n\nexport const selectSocialLink = (state: State) => state.teamsListReducer.socialLink;\n"
  },
  {
    "path": "src/modules/TeamsList/styled.ts",
    "content": "import styled from 'styled-components';\n\nexport const StyledTeams = styled.div`\n  max-width: 1320px;\n  width: 92%;\n`;\n\nexport const TeamsTitleWrapper = styled.div`\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  width: 100%;\n\n  h1 {\n    width: auto;\n  }\n`;\n"
  },
  {
    "path": "src/modules/TeamsList/teamsListReducer.ts",
    "content": "import {\n  SET_SOCIAL_LINK,\n  SET_TEAM_PASSWORD,\n  SET_TEAM_MEMBER_EXPEL_ID,\n  ACTIVE_MODAL_EXPEL,\n  ACTIVE_MODAL_LEAVE,\n  ACTIVE_MODAL_JOIN,\n  ACTIVE_MODAL_CREATE_TEAM,\n  ACTIVE_MODAL_CREATED,\n  ACTIVE_MODAL_UPDATE_SOCIAL_LINK,\n  ACTIVE_MODAL_REMOVE_COURSE,\n  ACTIVE_MODAL_SORT_STUDENTS,\n  ACTIVE_MODAL_LEAVE_PAGE,\n  ACTIVE_MODAL_CREATED_COURSE,\n  ACTIVE_MODAL_EDIT_COURSE,\n} from 'appConstants';\nimport { StateTeamsList } from 'types';\nimport { createActions, handleActions } from 'redux-actions';\n\nexport const teamsListState = {\n  socialLink: '',\n  teamPassword: '',\n  teamMemberExpelId: '',\n  isActiveModalExpel: false,\n  isActiveModalLeave: false,\n  isActiveModalJoin: false,\n  isActiveModalCreateTeam: false,\n  isActiveModalCreated: false,\n  isActiveModalUpdateSocialLink: false,\n  isActiveModalRemoveCourse: false,\n  isActiveModalSortStudents: false,\n  isActiveModalLeavePage: false,\n  isActiveModalCreatedCourse: false,\n  isActiveModalEditCourse: false,\n};\n\nexport const {\n  setSocialLink,\n  setTeamPassword,\n  setTeamMemberExpelId,\n  activeModalExpel,\n  activeModalLeave,\n  activeModalJoin,\n  activeModalCreateTeam,\n  activeModalCreated,\n  activeModalUpdateSocialLink,\n  activeModalRemoveCourse,\n  activeModalSortStudents,\n  activeModalLeavePage,\n  activeModalCreatedCourse,\n  activeModalEditCourse,\n} = createActions({\n  SET_SOCIAL_LINK: (socialLink) => ({ socialLink }),\n  SET_TEAM_PASSWORD: (teamPassword) => ({ teamPassword }),\n  SET_TEAM_MEMBER_EXPEL_ID: (teamMemberExpelId) => ({ teamMemberExpelId }),\n  ACTIVE_MODAL_EXPEL: (isActiveModalExpel) => ({ isActiveModalExpel }),\n  ACTIVE_MODAL_LEAVE: (isActiveModalLeave) => ({ isActiveModalLeave }),\n  ACTIVE_MODAL_JOIN: (isActiveModalJoin) => ({\n    isActiveModalJoin,\n  }),\n  ACTIVE_MODAL_CREATE_TEAM: (isActiveModalCreateTeam) => ({\n    isActiveModalCreateTeam,\n  }),\n  ACTIVE_MODAL_CREATED: (isActiveModalCreated) => ({ isActiveModalCreated }),\n  ACTIVE_MODAL_UPDATE_SOCIAL_LINK: (isActiveModalUpdateSocialLink) => ({\n    isActiveModalUpdateSocialLink,\n  }),\n  ACTIVE_MODAL_REMOVE_COURSE: (isActiveModalRemoveCourse) => ({\n    isActiveModalRemoveCourse,\n  }),\n  ACTIVE_MODAL_SORT_STUDENTS: (isActiveModalSortStudents) => ({\n    isActiveModalSortStudents,\n  }),\n  ACTIVE_MODAL_LEAVE_PAGE: (isActiveModalLeavePage) => ({\n    isActiveModalLeavePage,\n  }),\n  ACTIVE_MODAL_CREATED_COURSE: (isActiveModalCreatedCourse) => ({\n    isActiveModalCreatedCourse,\n  }),\n  ACTIVE_MODAL_EDIT_COURSE: (isActiveModalEditCourse) => ({\n    isActiveModalEditCourse,\n  }),\n});\n\nexport const teamsListReducer = handleActions<StateTeamsList, any>(\n  {\n    [SET_SOCIAL_LINK]: (state, { payload: { socialLink } }) => ({\n      ...state,\n      socialLink,\n    }),\n    [SET_TEAM_PASSWORD]: (state, { payload: { teamPassword } }) => ({\n      ...state,\n      teamPassword,\n    }),\n    [SET_TEAM_MEMBER_EXPEL_ID]: (state, { payload: { teamMemberExpelId } }) => ({\n      ...state,\n      teamMemberExpelId,\n    }),\n    [ACTIVE_MODAL_EXPEL]: (state, { payload: { isActiveModalExpel } }) => ({\n      ...state,\n      isActiveModalExpel,\n    }),\n    [ACTIVE_MODAL_LEAVE]: (state, { payload: { isActiveModalLeave } }) => ({\n      ...state,\n      isActiveModalLeave,\n    }),\n    [ACTIVE_MODAL_JOIN]: (state, { payload: { isActiveModalJoin } }) => ({\n      ...state,\n      isActiveModalJoin,\n    }),\n    [ACTIVE_MODAL_CREATE_TEAM]: (state, { payload: { isActiveModalCreateTeam } }) => ({\n      ...state,\n      isActiveModalCreateTeam,\n    }),\n    [ACTIVE_MODAL_CREATED]: (state, { payload: { isActiveModalCreated } }) => ({\n      ...state,\n      isActiveModalCreated,\n    }),\n    [ACTIVE_MODAL_UPDATE_SOCIAL_LINK]: (state, { payload: { isActiveModalUpdateSocialLink } }) => ({\n      ...state,\n      isActiveModalUpdateSocialLink,\n    }),\n    [ACTIVE_MODAL_REMOVE_COURSE]: (state, { payload: { isActiveModalRemoveCourse } }) => ({\n      ...state,\n      isActiveModalRemoveCourse,\n    }),\n    [ACTIVE_MODAL_SORT_STUDENTS]: (state, { payload: { isActiveModalSortStudents } }) => ({\n      ...state,\n      isActiveModalSortStudents,\n    }),\n    [ACTIVE_MODAL_LEAVE_PAGE]: (state, { payload: { isActiveModalLeavePage } }) => ({\n      ...state,\n      isActiveModalLeavePage,\n    }),\n    [ACTIVE_MODAL_CREATED_COURSE]: (state, { payload: { isActiveModalCreatedCourse } }) => ({\n      ...state,\n      isActiveModalCreatedCourse,\n    }),\n    [ACTIVE_MODAL_EDIT_COURSE]: (state, { payload: { isActiveModalEditCourse } }) => ({\n      ...state,\n      isActiveModalEditCourse,\n    }),\n  },\n  teamsListState\n);\n"
  },
  {
    "path": "src/modules/TokenPage/index.tsx",
    "content": "import React, { FC, useEffect } from 'react';\nimport { AUTH_TOKEN } from 'appConstants';\nimport { useDispatch } from 'react-redux';\nimport { useParams, useHistory } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { setToken } from 'modules/LoginPage/loginPageReducer';\n\ntype ParamsType = {\n  id: string;\n};\n\nexport const TokenPage: FC = () => {\n  const dispatch = useDispatch();\n  const { id } = useParams<ParamsType>();\n  const history = useHistory();\n  const { t } = useTranslation();\n\n  useEffect(() => {\n    const loginToken = sessionStorage.getItem(AUTH_TOKEN);\n    if (!loginToken) {\n      sessionStorage.setItem(AUTH_TOKEN, id);\n      dispatch(setToken(id));\n    }\n    history.push('/');\n  }, [id, history, dispatch]);\n\n  return (\n    <div>\n      <p>{t('Redirecting...')}</p>\n    </div>\n  );\n};\n"
  },
  {
    "path": "src/modules/TutorialPage/components/NoteBlock/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { NoteWrapper, NoteList } from './styled';\nimport { useTranslation } from 'react-i18next';\n\ntype NoteBlockProps = {\n  title?: string;\n  subtitle?: string;\n  listItems?: string[];\n  isNote?: string;\n};\n\nexport const NoteBlock: FC<NoteBlockProps> = ({\n  title = 'Note',\n  subtitle,\n  listItems,\n  children,\n  isNote,\n}) => {\n  const { t } = useTranslation();\n  return (\n    <NoteWrapper isNote={isNote && 'Note'}>\n      <h4>{t(title)}</h4>\n      {subtitle && <p>{t(subtitle)}</p>}\n      {listItems && (\n        <NoteList>\n          {listItems.map((item: string) => (\n            <li key={item}>{t(item)}</li>\n          ))}\n        </NoteList>\n      )}\n      {children}\n    </NoteWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/TutorialPage/components/NoteBlock/styled.ts",
    "content": "import {\n  DARK_TEXT_COLOR,\n  MAIN1_COLOR,\n  DASHBOARD_HEADER_BG_COLOR,\n  WHITE_COLOR,\n} from 'appConstants/colors';\nimport styled from 'styled-components';\n\ntype NoteProps = {\n  isNote?: string;\n};\n\nexport const NoteWrapper = styled.div<NoteProps>`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  margin-bottom: ${({ isNote }) => isNote && '20px'};\n  padding: ${({ isNote }) => isNote && '30px'};\n  background-color: ${({ isNote }) => isNote && DASHBOARD_HEADER_BG_COLOR};\n  border-radius: 20px;\n\n  p {\n    margin-top: 0;\n  }\n\n  & > h4 {\n    color: ${({ isNote }) => (isNote ? MAIN1_COLOR : DARK_TEXT_COLOR)};\n    margin: 0 0 20px;\n  }\n\n  .SelectCourseExample {\n    width: 300px;\n    margin-left: 40px;\n\n    @media (max-width: 550px) {\n      width: 250px;\n      margin-left: 35px;\n    }\n    @media (max-width: 440px) {\n      width: 200px;\n      margin-left: 30px;\n    }\n  }\n\n  @media (max-width: 650px) {\n    padding: ${({ isNote }) => isNote && '27.5px'};\n  }\n  @media (max-width: 550px) {\n    padding: ${({ isNote }) => isNote && '25px'};\n  }\n  @media (max-width: 440px) {\n    padding: ${({ isNote }) => isNote && '20px'};\n    margin-bottom: ${({ isNote }) => isNote && '10px'};\n  }\n`;\n\nexport const NoteList = styled.ol`\n  display: flex;\n  flex-direction: column;\n  gap: 25px;\n  list-style: none;\n  counter-reset: counter;\n  margin: 0 0 20px;\n  padding-inline-start: 0;\n\n  li {\n    counter-increment: counter;\n    margin: 0 0 0 40px;\n    text-align: justify;\n    @media (max-width: 550px) {\n      margin-left: 35px;\n    }\n    @media (max-width: 440px) {\n      margin-left: 30px;\n    }\n  }\n\n  li::before {\n    content: counter(counter);\n    background-color: ${MAIN1_COLOR};\n    width: 30px;\n    height: 30px;\n    border-radius: 50%;\n    display: inline-block;\n    line-height: 30px;\n    color: ${WHITE_COLOR};\n    text-align: center;\n    margin: 0 10px -3px -40px;\n\n    @media (max-width: 550px) {\n      width: 25px;\n      height: 25px;\n      line-height: 25px;\n      margin-left: -35px;\n    }\n    @media (max-width: 440px) {\n      width: 20px;\n      height: 20px;\n      line-height: 22px;\n      margin-left: -30px;\n    }\n  }\n\n  @media (max-width: 550px) {\n    gap: 20px;\n  }\n  @media (max-width: 440px) {\n    gap: 15px;\n  }\n`;\n"
  },
  {
    "path": "src/modules/TutorialPage/components/StepBlock/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { StepBlockWrapper, StepBlockText } from './styled';\nimport { PageTitle } from 'typography';\n\ntype StepBlockProps = {\n  title: string;\n  subtitle: string;\n  imageSrc: string;\n  altText: string;\n};\n\nexport const StepBlock: FC<StepBlockProps> = ({ title, subtitle, imageSrc, altText }) => {\n  const { t } = useTranslation();\n  return (\n    <StepBlockWrapper>\n      <PageTitle>{t(title)}</PageTitle>\n      <StepBlockText>{t(subtitle)}</StepBlockText>\n      <img src={imageSrc} alt={altText} className=\"StepBlockImage\" />\n    </StepBlockWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/TutorialPage/components/StepBlock/styled.ts",
    "content": "import styled from 'styled-components';\nimport { TextRegular } from 'typography';\n\nexport const StepBlockWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  height: 100%;\n\n  & > * {\n    margin-bottom: 20px;\n  }\n`;\n\nexport const StepBlockText = styled.p`\n  ${TextRegular};\n  margin-top: 0;\n`;\n"
  },
  {
    "path": "src/modules/TutorialPage/components/index.ts",
    "content": "export { StepBlock } from './StepBlock';\nexport { NoteBlock } from './NoteBlock';\n"
  },
  {
    "path": "src/modules/TutorialPage/index.tsx",
    "content": "import React, { FC, useCallback } from 'react';\nimport { TutorialPageWrapper } from './styled';\nimport editProfileExampleEN from 'assets/images/editProfileExampleEN.png';\nimport editProfileExampleRU from 'assets/images/editProfileExampleRU.png';\nimport teamActionsExampleEN from 'assets/images/teamActionsExampleEN.png';\nimport teamActionsExampleRU from 'assets/images/teamActionsExampleRU.png';\nimport { NoteBlock, StepBlock } from './components';\nimport { tutorialNoteInfo } from './tutorialPageInfo';\nimport { useSelector } from 'react-redux';\nimport { selectCurrLanguage } from 'modules/LoginPage/selectors';\nimport { ContentPageWrapper } from 'typography';\nimport { useTranslation } from 'react-i18next';\n\nexport const TutorialPage: FC = () => {\n  const currentLang = useSelector(selectCurrLanguage);\n  const { t } = useTranslation();\n  const TUTORIAL_PAGE_NOTES_INFO = useCallback(\n    () => tutorialNoteInfo(currentLang, t),\n    [currentLang, t]\n  );\n\n  return (\n    <ContentPageWrapper>\n      <TutorialPageWrapper>\n        <StepBlock\n          title=\"Step 1\"\n          subtitle=\"The app will suggest\"\n          imageSrc={currentLang === 'en' ? editProfileExampleEN : editProfileExampleRU}\n          altText=\"Profile example\"\n        />\n        <NoteBlock\n          listItems={['The “score” field should be filled in with your score']}\n          isNote=\"Note\"\n        />\n        <StepBlock\n          title=\"Step 2\"\n          subtitle=\"On the teams page you will see two available buttons\"\n          imageSrc={currentLang === 'en' ? teamActionsExampleEN : teamActionsExampleRU}\n          altText=\"Team actions example\"\n        />\n        {TUTORIAL_PAGE_NOTES_INFO().map(({ title, subtitle, listItems, isNote, children }) => (\n          <NoteBlock\n            {...{ title, subtitle, listItems, isNote }}\n            key={listItems ? JSON.stringify(listItems) : title}\n          >\n            {children}\n          </NoteBlock>\n        ))}\n      </TutorialPageWrapper>\n    </ContentPageWrapper>\n  );\n};\n"
  },
  {
    "path": "src/modules/TutorialPage/styled.ts",
    "content": "import styled from 'styled-components';\nimport { GeneralAdaptiveFont } from 'typography';\n\nexport const TutorialPageWrapper = styled.div`\n  display: flex;\n  flex-direction: column;\n  width: 680px;\n  height: fit-content;\n  padding: 60px 0;\n  gap: 40px;\n\n  .StepBlockImage {\n    margin: 20px 0;\n    border-radius: 20px;\n    box-shadow: 0px 4px 50px rgba(6, 73, 140, 0.1);\n\n    @media (max-width: 440px) {\n      margin: 0;\n    }\n  }\n\n  div:nth-of-type(6) {\n    margin-top: -17px;\n  }\n\n  div:last-child {\n    margin-top: 20px;\n    & > p {\n      margin-bottom: 0;\n    }\n  }\n\n  p,\n  li {\n    ${GeneralAdaptiveFont};\n  }\n\n  h4 {\n    font-size: 20px;\n    line-height: 30px;\n  }\n\n  @media (max-width: 992px) {\n    width: 640px;\n\n    h4 {\n      font-size: 1.3rem;\n    }\n  }\n  @media (max-width: 768px) {\n    width: 600px;\n\n    h1 {\n      font-size: 1.3rem;\n    }\n    h4 {\n      font-size: 1.2rem;\n    }\n  }\n  @media (max-width: 650px) {\n    width: 500px;\n    padding: 55px 0;\n    gap: 30px;\n\n    div:last-child {\n      margin-top: 0;\n    }\n\n    h1 {\n      font-size: 1.25rem;\n    }\n    h4 {\n      font-size: 1.15rem;\n    }\n  }\n  @media (max-width: 550px) {\n    width: 400px;\n    padding: 50px 0;\n    gap: 25px;\n\n    h1 {\n      font-size: 1.1rem;\n    }\n    h4 {\n      font-size: 1rem;\n    }\n  }\n  @media (max-width: 440px) {\n    width: 280px;\n    padding: 40px 0;\n    gap: 20px;\n\n    h1 {\n      font-size: 1rem;\n    }\n    h4 {\n      font-size: 0.9rem;\n      line-height: 22px;\n    }\n  }\n`;\n"
  },
  {
    "path": "src/modules/TutorialPage/tutorialPageInfo.tsx",
    "content": "import myTeamExampleEN from 'assets/images/myTeamExampleEN.png';\nimport myTeamExampleRU from 'assets/images/myTeamExampleRU.png';\n\nexport const tutorialNoteInfo = (currentLang: string, t: any) => {\n  const TUTORIAL_PAGE_NOTES_INFO = [\n    {\n      title: 'Create team',\n      subtitle: 'The team creation process is taken place in three steps',\n      listItems: [\n        'Press the “Create team” button',\n        'Provide a link to a team chat',\n        'Specify password',\n      ],\n      children: <p>{t('The only person who creates the team is Team Lead')}</p>,\n    },\n    {\n      title: 'Join team',\n      subtitle: 'To join an existing team',\n      listItems: [`Press the “Join team” button`, `Specify the password`],\n    },\n    {\n      listItems: [\n        `If you have not found a team`,\n        `If the team has fewer members than is required for the task`,\n      ],\n      isNote: 'Note',\n    },\n    {\n      title: 'You will see the following after joining the team',\n      children: (\n        <img\n          src={currentLang === 'en' ? myTeamExampleEN : myTeamExampleRU}\n          alt=\"My team example\"\n          className=\"StepBlockImage\"\n        />\n      ),\n    },\n    {\n      title: 'Leave team',\n      subtitle: 'To leave the team',\n    },\n  ];\n  return TUTORIAL_PAGE_NOTES_INFO;\n};\n"
  },
  {
    "path": "src/modules/index.ts",
    "content": "export { LoginPage } from './LoginPage';\nexport { StudentsTable } from './StudentsTable';\nexport { TeamsList } from './TeamsList';\nexport { TokenPage } from './TokenPage';\nexport { NotFoundPage } from './NotFoundPage';\nexport { EditProfile } from './EditProfile';\nexport { TutorialPage } from './TutorialPage';\nexport { AdminPage } from './AdminPage';\n"
  },
  {
    "path": "src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\ndeclare module '*.woff2';\ndeclare module '*.svg' {\n  import React = require('react');\n  export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;\n  const src: string;\n  export default src;\n}\n\ndeclare module '*.jpg' {\n  const content: string;\n  export default content;\n}\n\ndeclare module '*.png' {\n  const content: string;\n  export default content;\n}\n"
  },
  {
    "path": "src/reportWebVitals.ts",
    "content": "import { ReportHandler } from 'web-vitals';\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry);\n      getFID(onPerfEntry);\n      getFCP(onPerfEntry);\n      getLCP(onPerfEntry);\n      getTTFB(onPerfEntry);\n    });\n  }\n};\n\nexport default reportWebVitals;\n"
  },
  {
    "path": "src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom';\n"
  },
  {
    "path": "src/store/index.tsx",
    "content": "import React, { FC } from 'react';\nimport { Provider } from 'react-redux';\nimport { studentsTableReducer } from 'modules/StudentsTable/studentsTableReducer';\nimport { teamsListReducer } from 'modules/TeamsList/teamsListReducer';\nimport { loginPageReducer } from 'modules/LoginPage/loginPageReducer';\nimport { createStore, combineReducers, applyMiddleware } from 'redux';\nimport { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';\nimport thunkMiddleware from 'redux-thunk';\nimport { State } from 'types';\n\nconst appReducer = combineReducers<State>({\n  studentsTableReducer,\n  teamsListReducer,\n  loginPageReducer,\n});\n\nconst store = createStore(appReducer, composeWithDevTools(applyMiddleware(thunkMiddleware)));\n\nexport const AppState: FC = ({ children }) => {\n  return (\n    <Provider store={store}>\n      <>{children}</>\n    </Provider>\n  );\n};\n"
  },
  {
    "path": "src/translation/en/en.json",
    "content": "{\n  \"First / Last Name\": \"First / Last Name\",\n  \"Score\": \"Score\",\n  \"Team Number\": \"Team Number\",\n  \"Location\": \"Location\",\n  \"Courses\": \"Courses\",\n  \"Course\": \"Course\",\n  \"Action\": \"Action\",\n  \"Use the format\": \"Use right format link - https://xxx/xxxx\",\n  \"This input exceed maxLength.\": \"This input exceed maxLength.\",\n  \"Development\" : \"Development:\",\n  \"Design\": \"Design:\",\n  \"Clear filter\": \"Clear filter\",\n  \"Apply\": \"Apply\",\n  \"Please, enter link\": \"Please, enter link\",\n  \"Enter group link\": \"Enter group link\",\n  \"Enter team password\": \"Enter team password\",\n  \"Enter your profile information\": \"Enter your profile information\",\n  \"Select course\": \"Select course\",\n  \"Submit\": \"Submit\", \n  \"Save\": \"Save\",\n  \"First Name\": \"First Name\",\n  \"Enter first name\": \"Enter first name\",\n  \"Last Name\": \"Last Name\",\n  \"This is required.\": \"This is required.\",\n  \"Minimal length is 1.\": \"Minimal length is 1.\",\n  \"Minimal length is 2.\": \"Minimal length is 2.\",\n  \"Minimal length is 3.\": \"Minimal length is 3.\",\n  \"Minimal length is 5.\": \"Minimal length is 5.\",\n  \"Enter last name\": \"Enter last name\",\n  \"Enter telegram\": \"Enter telegram\",\n  \"Enter discord\": \"Enter discord\",\n  \"This input is letters only.\": \"This input is letters only.\",\n  \"This input is number only.\": \"This input is number only.\",\n  \"This input is letters and digits only.\": \"This input is letters and digits only.\",\n  \"City\": \"City\",\n  \"Enter city\": \"Enter city\",\n  \"Country\": \"Country\",\n  \"Enter country\": \"Enter country\",\n  \"Enter score\": \"Enter score\",\n  \"Sign in\": \"Sign in\",\n  \"Sign in with Github\": \"Sign in with Github\",\n  \"Don’t have github account?\": \"Don’t have GitHub account?\",\n  \"Sign up\": \"Sign up\",\n  \"Not found!\": \"Page not found! :(\",\n  \"Dashboard\": \"Dashboard\",\n  \"Filter\": \"Filter\",\n  \"No team yet.\": \"No team yet.\",\n  \"No\": \"No\",\n  \"No courses.\": \"No courses.\",\n  \"Redirecting...\": \"Redirecting...\",\n  \"Teams\": \"Teams\",\n  \"Team\": \"Team\",\n  \"Sort students\": \"Sort students\",\n  \"Sort students?\": \"Sort students?\",\n  \"member\": \"member\",\n  \"members\": \"members\",\n  \"My team - Team\": \"My team - Team\",\n  \"Leave team\": \"Leave team\",\n  \"Join team\": \"Join team\",\n  \"The password is required to join the team.\": \"The password is required to join the team.\",\n  \"Become a member of the team!\": \"Become a member of the team!\",\n  \"To become a member\": \"To become a member of the team you can create your own team or join team. If not, you will be added to the team automatically.\",\n  \"Create team\": \"Create team\",\n  \"Expel\": \"Expel\",\n  \"Edit Profile\": \"Edit Profile\",\n  \"Something went wrong!\": \"Something went wrong!\",\n  \"Please, try again later.\": \"Please, try again later. If problem is not solved - contact us in telegram:\",\n  \"Ok\": \"Ok\",\n  \"Please, enter your team password.\": \"Please, enter your team password.\",\n  \"Wrong password!\": \"Wrong password! Please, also check if the team you want to join applies to the current course in your profile.\",\n  \"Are you sure want to leave team?\": \"Are you sure want to leave team?\",\n  \"Yes\": \"Yes\",\n  \"Expel User\": \"Expel User\",\n  \"Are you sure want to expel user?\": \"Are you sure want to expel user?\",\n  \"Leave course\": \"Leave course\",\n  \"Are you sure to leave this course?\": \"Are you sure to leave this course?\",\n  \"Please, enter your team telegram / discord / viber / ets. group link.\": \"Please, enter your team telegram / discord / viber / ets. group link.\",\n  \"New team created!\": \"New team created!\",\n  \"You are automatically added there.\": \"You are automatically added there.\",\n  \"If you want to invite friends - tell them your team password:\": \"If you want to invite friends - tell them your team password:\",\n  \"Got it!\": \"Got it!\",\n  \"Link to group\": \"Link to group\",\n  \"Please, enter new group link.\": \"Please, enter new group link.\",\n  \"Update link\": \"Update link\",\n  \"Sort by score\": \"Sort by score\",\n  \"Max score\": \"Max score\",\n  \"Min score\": \"Min score\",\n  \"Sort by team\": \"Sort by team\",\n  \"All\": \"All\",\n  \"Without team\": \"Without team\",\n  \"Enter location\": \"Enter location\",\n  \"Enter github name\": \"Enter GitHub name\",\n  \"Enter discord name\": \"Enter discord name\",\n  \"Enter course name\": \"Enter course name\",\n  \"Cancel\": \"Cancel\",\n  \"Invitation password\": \"Invitation password\",\n  \"You need to choose at least one course\": \"You need to choose at least one course\",\n  \"Step 1\": \"Step 1 -  Registration\",\n  \"The app will suggest\": \"The app will suggest you to fill in the registration form after authorization:\",\n  \"The “score” field should be filled in with your score\": \"The “score” field should be filled in with your score for the base course at RS School (Front-end/JavaScript). If you have not studied in the base course, fill in this field with 100.\",\n  \"Step 2\": \"Step 2 - Team creation or team joining\",\n  \"On the teams page you will see two available buttons\": \"On the teams page you will see two available buttons - “Join team” and “Create team”:\",\n  \"Note\": \"Note\",\n  \"The team creation process is taken place in three steps\": \"The team creation process is taken place in three steps:\",\n  \"Press the “Create team” button\": \"Press the “Create team” button;\",\n  \"Provide a link to a team chat\": \"Provide a link to a team chat (viber, discord, telegram);\",\n  \"Specify password\": \"Specify password (another teammates can join this team later using this password).\",\n  \"The only person who creates the team is Team Lead\": \"The only person who creates the team is Team Lead and then he or she shares the team password to another team’s participants.\",\n  \"To join an existing team\": \"To join an existing team you need to know the team password and go through the following steps:\",\n  \"Press the “Join team” button\": \"Press the “Join team” button;\",\n  \"Specify the password\": \"Specify the password which you have received from the team creator.\",\n  \"If you have not found a team\": \"If you have not found a team, you should just register in the app and we will find a team for you when registration closes.\",\n  \"If the team has fewer members than is required for the task\": \"If the team has fewer members than is required for the task, then it will be automatically staffed to the required number when registration closes.\",\n  \"You will see the following after joining the team\": \"You will see the following after joining the team:\",\n  \"To leave the team\": \"To leave the team, click the “Leave Team” button or ask someone from your teammates to exclude you from the team.\",\n  \"Data is unsaved\": \"Data is unsaved\",\n  \"Are you sure want to leave page without saving data\": \"Are you sure want to leave page without saving data?\",\n  \"Welcome to RSS Teams\": \"Welcome to RSS Teams!\",\n  \"Skip\": \"Skip\",\n  \"Next\": \"Next\",\n  \"You can create new team\": \"You can create new team - you need only the link to your future team chat.\",\n  \"Or join existing team\": \"Or join existing team! You should have the password from your team.\",\n  \"You can always leave the course\": \"You can always leave the course.\",\n  \"On Teams page you can see other teams\": \"On Teams page you can also see other teams.\",\n  \"With dropdown you can switch the course\": \"With dropdown you can switch the course in case if you have several courses.\",\n  \"On Dashboard page\": \"On Dashboard page you can check/find another students.\",\n  \"With filter usage\": \"With filter usage you can make the search for students easier.\",\n  \"On Edit profile page\": \"On Edit profile page you can add/remove course or edit your profile.\",\n  \"If you forget something\": \"If you forgot something, you can use Tutorial tab.\",\n  \"Support us\": \"Support us by pressing a star in\",\n  \"our repo\": \"our repo\",\n  \"Got it\": \"Got it!\",\n  \"Admin\": \"Admin\",\n  \"Admin page\": \"Admin page\",\n  \"Course name\": \"Course name\",\n  \"Team size\": \"Team size\",\n  \"Enter team size\": \"Enter team size\",\n  \"Add new course\": \"Add new course\",\n  \"Courses list\": \"Courses list\",\n  \"Show\": \"Show\",\n  \"Search course\": \"Search course...\",\n  \"Active(status)\": \"Active\",\n  \"Active\": \"Active\",\n  \"Terminate\": \"Terminate\",\n  \"Terminate(status)\": \"Terminated\",\n  \"Terminated\": \"Terminated\",\n  \"Edit course\": \"Edit course\",\n  \"Course was created\": \"Course was created!\",\n  \"If you want to change something in new course\": \"If you want to change something in new course you can edit it below\",\n  \"New course name\": \"New course name\",\n  \"New team size\": \"New team size\",\n  \"Enter new course name\": \"Enter new course name\",\n  \"Enter new team size\": \"Enter new team size\",\n  \"Please, enter new course information\": \"Please, enter new course information\",\n  \"Please, enter unique course name\": \"Please, enter unique course name\",\n  \"Please, enter correct course name\": \"Should include current year\",\n  \"Please, enter correct team size\": \"Please, enter correct team size (2-9)\",\n  \"Terminate course\": \"Terminate course\",\n  \"Activate course\": \"Activate course\",\n  \"Close\": \"Close\",\n  \"Unset\": \"Unset\"\n}\n"
  },
  {
    "path": "src/translation/resources.ts",
    "content": "import { CURRENT_LANG, DEFAULT_LANGUAGE } from 'appConstants';\nimport i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nimport translationEN from './en/en.json';\nimport translationRU from './ru/ru.json';\n\nconst resources = {\n  en: {\n    translation: translationEN,\n  },\n  ru: {\n    translation: translationRU,\n  },\n};\n\nconst language = localStorage.getItem(CURRENT_LANG) ?? DEFAULT_LANGUAGE;\n\ni18n.use(initReactI18next).init({\n  resources,\n  lng: language,\n  keySeparator: false,\n  interpolation: {\n    escapeValue: false,\n  },\n});\n\nexport default i18n;\n"
  },
  {
    "path": "src/translation/ru/ru.json",
    "content": "{\n  \"First / Last Name\": \"Имя и фамилия\",\n  \"Score\": \"Рейтинг\",\n  \"Team Number\": \"№ команды\",\n  \"Location\": \"Локация\",\n  \"Courses\": \"Курсы\",\n  \"Course\": \"Курс\",\n  \"Action\": \"Действие\",\n  \"Use the format\": \"Используйте верный формат ссылки - https://xxx/xxxx\",\n  \"This input exceed maxLength.\": \"Превышена максимальная длина ввода!\",\n  \"Development\" : \"Разработка:\",\n  \"Design\": \"Дизайн:\",\n  \"Clear filter\": \"Очистить фильтр\",\n  \"Apply\": \"Применить\",\n  \"Please, enter link\": \"Пожалуйста, введите ссылку\",\n  \"Enter group link\": \"Введите ссылку группы\",\n  \"Enter team password\": \"Введите пароль команды\",\n  \"Enter your profile information\": \"Заполните информацию Вашего профиля\",\n  \"Select course\": \"Выберите курс\",\n  \"Submit\": \"Отправить\", \n  \"Save\": \"Сохранить\",\n  \"First Name\": \"Имя\",\n  \"Enter first name\": \"Введите имя\",\n  \"Last Name\": \"Фамилия\",\n  \"This is required.\": \"Это поле не может быть пустым.\",\n  \"Minimal length is 1.\": \"Минимальная длина 1.\",\n  \"Minimal length is 2.\": \"Минимальная длина 2.\",\n  \"Minimal length is 3.\": \"Минимальная длина 3.\",\n  \"Minimal length is 5.\": \"Минимальная длина 5.\",\n  \"Enter last name\": \"Введите фамилию\",\n  \"Enter telegram\": \"Введите telegram\",\n  \"Enter discord\": \"Введите discord\",\n  \"This input is letters only.\": \"Вы можете ввести только буквы.\",\n  \"This input is number only.\": \"Вы можете ввести только цифры.\",\n  \"This input is letters and digits only.\": \"Вы можете ввести только цифры или буквы.\",\n  \"City\": \"Город\",\n  \"Enter city\": \"Введите город\",\n  \"Country\": \"Страна\",\n  \"Enter country\": \"Введите страну\",\n  \"Enter score\": \"Введите рейтинг\",\n  \"Sign in\": \"Войти\",\n  \"Sign in with Github\": \"Войти через Github\",\n  \"Don’t have github account?\": \"У Вас нет аккаунта Github?\",\n  \"Sign up\": \"Зарегистрироваться\",\n  \"Not found!\": \"Не найдено!\",\n  \"Dashboard\": \"Таблица\",\n  \"Filter\": \"Фильтр\",\n  \"No team yet.\": \"Нет команды.\",\n  \"No\": \"Нет\",\n  \"No courses.\": \"Нет курсов.\",\n  \"Redirecting...\": \"Перенаправление...\",\n  \"Teams\": \"Команды\",\n  \"Team\": \"Команда\",\n  \"Sort students\": \"Сортировка студентов\",\n  \"Sort students?\": \"Рассортировать студентов?\",\n  \"member\": \"участник\",\n  \"members\": \"участника\",\n  \"My team - Team\": \"Моя команда - Команда\",\n  \"Leave team\": \"Покинуть команду\",\n  \"Join team\": \"Вступить в команду\",\n  \"The password is required to join the team.\": \"Пароль обязателен для вступления в команду\",\n  \"Become a member of the team!\": \"Станьте участником команды!\",\n  \"To become a member\": \"Чтобы стать участником команды, Вам необходимо создать Вашу собствнную команду или вступить в уже существующую. Если нет, Вы будете автоматически добавлены в команду.\",\n  \"Create team\": \"Создать команду\",\n  \"Expel\": \"Исключить\",\n  \"Edit Profile\": \"Профиль\",\n  \"Something went wrong!\": \"Что-то пошло не так :(\",\n  \"Please, try again later.\": \"Пожалуйста, попробуйте позже. Если проблема не будет решена, свяжытесь с нами через telegram:\",\n  \"Ok\": \"Ok\",\n  \"Please, enter your team password.\": \"Пожалуйста, ввестите пароль команды.\",\n  \"Wrong password!\": \"Неверный пароль! Пожалуйста, также проверьте, относится ли Ваша команда к текущему курсу у Вас в профиле.\",\n  \"Are you sure want to leave team?\": \"Вы уверены, что хотите покинуть команду?\",\n  \"Yes\": \"Да\",\n  \"Expel User\": \"Исключение участника\",\n  \"Are you sure want to expel user?\": \"Вы уверены, что хотите исключить участника?\",\n  \"Leave course\": \"Покинуть курс\",\n  \"Are you sure to leave this course?\": \"Вы уверены, что хотите покинуть курс?\",\n  \"Please, enter your team telegram / discord / viber / ets. group link.\": \"Пожалуйста, введите ссылку на Ваш командный чат telegram / discord / viber / др.\",\n  \"New team created!\": \"Новая команда создана!\",\n  \"You are automatically added there.\": \"Вы автоматически добавлены туда.\",\n  \"If you want to invite friends - tell them your team password:\": \"Если Вы хотите пригласить друзей, - скажите им Ваш пароль от команды:\",\n  \"Got it!\": \"Есть!\",\n  \"Link to group\": \"Ссылка на группу\",\n  \"Please, enter new group link.\": \"Пожалуйста, введите новую ссылку группы.\",\n  \"Update link\": \"Обновить ссылку\",\n  \"Sort by score\": \"Сортировать по рейтингу\",\n  \"Max score\": \"Максимальный\",\n  \"Min score\": \"Минимальный\",\n  \"Sort by team\": \"Сортировать по командам\",\n  \"All\": \"Все\",\n  \"Without team\": \"Без команды\",\n  \"Enter location\": \"Введите локацию\",\n  \"Enter github name\": \"Введите имя GitHub\",\n  \"Enter discord name\": \"Введите имя discord\",\n  \"Enter course name\": \"Введите название курса\",\n  \"Cancel\": \"Закрыть\",\n  \"Invitation password\": \"Пароль команды\",\n  \"You need to choose at least one course\": \"Необходимо выбрать хотя бы один курс\",\n  \"Step 1\": \"Шаг № 1 Регистрация\",\n  \"The app will suggest\": \"После авторизации приложение предложит Вам заполнить регистрационную форму:\",\n  \"The “score” field should be filled in with your score\": \"Поле score заполняется в соответствии с Вашим скором на основном курсе в RS School. Если Вы не учились на основном курсе, то указываем 100, чтобы прошла валидация.\",\n  \"Step 2\": \"Шаг № 2 Создание команды или присоединение к команде\",\n  \"On the teams page you will see two available buttons\": \"На странице Команды Вы увидите две доступные кнопки - 'Присоединиться к команде' и 'Создать команду':\",\n  \"Note\": \"Примечание\",\n  \"The team creation process is taken place in three steps\": \"Процесс создания команды проходит в три шага:\",\n  \"Press the “Create team” button\": \"Нажать 'Создать команду';\",\n  \"Provide a link to a team chat\": \"Указать ссылку на командный чат (viber, discord, telegram);\",\n  \"Specify password\": \"Указать пароль (по паролю остальные члены команды смогут позже присоединиться).\",\n  \"The only person who creates the team is Team Lead\": \"Команду создает только один из участников (Team lead) и делится со всеми остальными участниками паролем.\",\n  \"To join an existing team\": \"Чтобы присоединиться к уже существующей команде вам нужно знать пароль и пройти следующие шаги:\",\n  \"Press the “Join team” button\": \"Нажать 'Присоединиться к команде';\",\n  \"Specify the password\": \"Указать пароль, которым с вами поделился создатель команды.\",\n  \"If you have not found a team\": \"Если Вы не нашли себе команду, то просто регистрируетесь в приложении и мы найдем команду для вас.\",\n  \"If the team has fewer members than is required for the task\": \"Если в команде меньше участников, чем указано в задании, команда будет укомплектована до нужного количества автоматически.\",\n  \"You will see the following after joining the team\": \"После присоединения к команде Вы увидите:\",\n  \"To leave the team\": \"Чтобы покинуть команду достаточно нажать кнопку 'Покинуть команду'. Или чтобы кто-то из сокомандников вас исключил.\",\n  \"Data is unsaved\": \"Данные не сохранены\",\n  \"Are you sure want to leave page without saving data\": \"Вы уверены, что хотите покинуть страницу без сохранения данных?\",\n  \"Welcome to RSS Teams\": \"Добро пожаловать в RSS Teams!\",\n  \"Skip\": \"Закрыть\",\n  \"Next\": \"Дальше!\",\n  \"You can create new team\": \"Вы можете создать новую команду - Вам нужна только ссылка чата Вашей группы.\",\n  \"Or join existing team\": \"Или Вы можете присоединиться к существующей команде! Вы должны получить пароль Вашей команды у членов Вашей команды.\",\n  \"You can always leave the course\": \"Вы можете покинуть курс в любое время.\",\n  \"On Teams page you can see other teams\": \"На странице 'Команды' Вы можете просмотреть команды других студентов.\",\n  \"With dropdown you can switch the course\": \"С помощью выпадающего списка Вы можете переключать текущий курс при условии, что у Вас несколько курсов.\",\n  \"On Dashboard page\": \"На странице 'Таблица' Вы можете найти других студентов.\",\n  \"With filter usage\": \"При использовании фильтров можно сделать поиск проще.\",\n  \"On Edit profile page\": \"На странице 'Профиль' Вы можете добавить/удалить курс или отредактировать Ваш профиль.\",\n  \"If you forget something\": \"Если Вы что-то забыли, воспользуйтесь страницей 'Tutorial'.\",\n  \"Support us\": \"Вы можете поддержать нас, поставив звезду\",\n  \"our repo\": \"нашему репозиторию\",\n  \"Got it\": \"Понятненько!\",\n  \"Admin\": \"Админ\",\n  \"Admin page\": \"Кабинет администратора\",\n  \"Course name\": \"Название курса\",\n  \"Team size\": \"Количество участников\",\n  \"Enter team size\": \"Введите количество участников\",\n  \"Add new course\": \"Добавить новый курс\",\n  \"Courses list\": \"Список курсов\",\n  \"Show\": \"Показать\",\n  \"Search course\": \"Найти курс...\",\n  \"Active(status)\": \"Активный\",\n  \"Active\": \"Активные\",\n  \"Terminate\": \"Закрыть\",\n  \"Terminate(status)\": \"Законченный\",\n  \"Terminated\": \"Законченные\",\n  \"Edit course\": \"Редактировать курс\",\n  \"Course was created\": \"Курс создан!\",\n  \"If you want to change something in new course\": \"Если Вы хотите что-то изменить в новом курсе, вы можете его отредактирвоать\",\n  \"New course name\": \"Новое название курса\",\n  \"New team size\": \"Новое количество учасников\",\n  \"Enter new course name\": \"Введите новое название курса\",\n  \"Enter new team size\": \"Введите новое количество участников\",\n  \"Please, enter new course information\": \"Пожалуйста, введите новую информацию о курсе\",\n  \"Please, enter unique course name\": \"Имя курса должно быть уникально\",\n  \"Please, enter correct course name\": \"Должен содержать текущий год\",\n  \"Please, enter correct team size\": \"Пожалуйста, введите корректное количество участников (2-9)\",\n  \"Terminate course\": \"Закрыть курс\",\n  \"Activate course\": \"Активировать курс\",\n  \"Close\": \"Закрыть\",\n  \"Save changes\": \"Сохранить изменения\",\n  \"Unset\": \"Не заданo\"\n}\n"
  },
  {
    "path": "src/types.ts",
    "content": "export type User = {\n  id: string;\n  firstName: string;\n  lastName: string;\n  github: string;\n  telegram: string | null;\n  discord: string;\n  score: number;\n  country: string;\n  city: string;\n  avatar: string;\n  isAdmin: boolean;\n  courses: Course[];\n  email: string | null;\n  courseIds: string[];\n  teamIds: string[];\n  teams: Team[];\n};\n\nexport interface Course {\n  id: string;\n  name: string;\n  isActive: boolean;\n  teamSize: number | null;\n  teamIds?: string[];\n  userIds?: string[];\n  teams?: Team[];\n  users?: User[];\n}\n\nexport type Team = {\n  id: string;\n  number: number;\n  password: string;\n  courseId: string;\n  socialLink: string;\n  memberIds: string[];\n  course: Course;\n  members: User[];\n};\n\nexport type TeamList = {\n  count: number;\n  results: Team[];\n};\n\nexport type TFilterForm = {\n  discord: string | null;\n  github: string | null;\n  location: string | null;\n  courseName: string | null;\n  sortingOrder: string;\n  teamFilter: string;\n};\n\nexport type UpdateUserInput = {\n  id: string;\n  firstName: string;\n  lastName: string;\n  email?: string;\n  telegram: string;\n  discord: string;\n  score?: number;\n  country: string;\n  city: string;\n  courseIds: string[];\n};\n\nexport type AddUserToTeamInput = {\n  userId: string;\n  courseId: string;\n  teamPassword: string;\n};\n\nexport type RemoveUserFromTeamInput = {\n  userId: string;\n  teamId: string;\n  page: number;\n  courseId: string;\n};\n\nexport type CreateTeamInput = {\n  socialLink: string;\n  courseId: string;\n  ownerId: string;\n  page: number;\n};\n\nexport type CreateCourseInput = {\n  name: string;\n  isActive: boolean;\n  teamSize: number;\n};\n\nexport type UpdateCourseInput = {\n  id: string;\n  name: string;\n  isActive: boolean;\n  teamSize: number;\n};\n\nexport type UpdateTeamInput = {\n  id: string;\n  socialLink: string;\n};\n\nexport type StateTeamsList = {\n  isActiveModalExpel: boolean;\n  isActiveModalLeave: boolean;\n  isActiveModalJoin: boolean;\n  isActiveModalCreateTeam: boolean;\n  isActiveModalCreated: boolean;\n  isActiveModalUpdateSocialLink: boolean;\n  isActiveModalRemoveCourse: boolean;\n  isActiveModalSortStudents: boolean;\n  isActiveModalLeavePage: boolean;\n  isActiveModalCreatedCourse: boolean;\n  isActiveModalEditCourse: boolean;\n  teamMemberExpelId: string;\n  teamPassword: string;\n  socialLink: string;\n};\n\nexport type UserFilterInput = {\n  discord: string | null;\n  github: string | null;\n  location: string | null;\n  courseName: string | null;\n  sortingOrder: string;\n  teamFilter: boolean;\n};\n\nexport type RemoveUserFromCourseInput = {\n  userId: string;\n  teamId?: string | null;\n  courseId: string;\n  page: number;\n};\n\nexport type StateStudentsTable = {\n  userData: User;\n  filterData: TFilterForm;\n};\n\nexport type StateLoginPage = {\n  loginToken: string | null;\n  currCourse: Course;\n  currLanguage: string;\n  isCommonError: boolean;\n  isBurgerMenuOpen: boolean;\n  isEditProfileDataChange: boolean;\n  pathToThePage: string;\n  isTourOpen: boolean;\n};\n\nexport type State = {\n  studentsTableReducer: StateStudentsTable;\n  teamsListReducer: StateTeamsList;\n  loginPageReducer: StateLoginPage;\n};\n\nexport type TNavLink = {\n  name: string;\n  isAlwaysVisible: boolean;\n};\n"
  },
  {
    "path": "src/typography/common.css",
    "content": "*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n:root {\n  --BG_COLOR: #f2f8fd;\n  --OVERLAY_COLOR: rgba(54, 61, 72, 0.3);\n  --SCROLL_THUMB_COLOR: #1e33570d;\n  --WHITE_COLOR: #ffffff;\n}\n\nbody {\n  margin: 0;\n  font: normal 16px/24px \"Poppins\", sans-serif;\n  background-color: var(--BG_COLOR);\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\ninput {\n  background-color: var(--BG_COLOR);\n}\n"
  },
  {
    "path": "src/typography/fonts.css",
    "content": "@font-face {\n  font-style: normal;\n  font-weight: 400;\n  font-family: \"Poppins\";\n  src: url(\"../assets/fonts/Poppins-Regular-400.otf\") format(\"otf\"),\n       url(\"../assets/fonts/Poppins-Regular-400.woff2\") format(\"woff2\"),\n       url(\"../assets/fonts/Poppins-Regular-400.woff\") format(\"woff\"),\n       url(\"../assets/fonts/Poppins-Regular-400.ttf\") format(\"truetype\");\n}\n\n@font-face {\n  font-style: normal;\n  font-weight: 500;\n  font-family: \"Poppins\";\n  src: url(\"../assets/fonts/Poppins-Medium-500.otf\") format(\"otf\"),\n       url(\"../assets/fonts/Poppins-Medium-500.woff\") format(\"woff\"),\n       url(\"../assets/fonts/Poppins-Medium-500.woff2\") format(\"woff2\")\n       url(\"../assets/fonts/Poppins-Medium-500.ttf\") format(\"truetype\");\n}\n\n@font-face {\n  font-style: normal;\n  font-weight: 600;\n  font-family: \"Poppins\";\n  src: url(\"../assets/fonts/Poppins-SemiBold-600.otf\") format(\"otf\"),\n       url(\"../assets/fonts/Poppins-SemiBold-600.woff\") format(\"woff\"),\n       url(\"../assets/fonts/Poppins-SemiBold-600.woff2\") format(\"woff2\"),\n       url(\"../assets/fonts/Poppins-SemiBold-600.ttf\") format(\"truetype\");\n}\n\n@font-face {\n  font-style: normal;\n  font-weight: 700;\n  font-family: \"Poppins\";\n  src: url(\"../assets/fonts/Poppins-Bold-700.otf\") format(\"otf\"),\n       url(\"../assets/fonts/Poppins-Bold-700.woff\") format(\"woff\"),\n       url(\"../assets/fonts/Poppins-Bold-700.woff2\") format(\"woff2\"),\n       url(\"../assets/fonts/Poppins-Bold-700.ttf\") format(\"truetype\");\n}\n"
  },
  {
    "path": "src/typography/index.ts",
    "content": "import styled, { css } from 'styled-components';\nimport { ReactComponent as RSLogoIcon } from 'assets/svg/rslogo.svg';\nimport {\n  WHITE_COLOR,\n  BG_COLOR,\n  MAIN1_COLOR,\n  DARK_TEXT_COLOR,\n  LIGHT_TEXT_COLOR,\n  TABLE_POPUP_BORDER_COLOR,\n} from 'appConstants/colors';\n\ninterface StyledTextProps {\n  color?: string;\n  fontSize?: string;\n  lineHeight?: string;\n  marginBottom?: string;\n}\n\ntype ButtonProps = {\n  bgc?: string;\n  color?: string;\n  mr?: string;\n};\n\ntype TRSLogoProps = {\n  login: string | null;\n};\n\ntype ModalInputProps = {\n  mt?: string;\n  blink?: boolean;\n  autoComplete?: string;\n};\n\nexport const RSLogo = styled(RSLogoIcon)<TRSLogoProps>`\n  width: 84px;\n  height: 30px;\n  margin-top: 5px;\n  margin-bottom: 22%;\n  path {\n    fill: ${({ login }) => (login ? WHITE_COLOR : DARK_TEXT_COLOR)};\n  }\n\n  @media (max-width: 992px) {\n    width: 80px;\n    height: 28px;\n  }\n  @media (max-width: 768px) {\n    width: 76px;\n    height: 24px;\n  }\n  @media (max-width: 550px) {\n    width: 72px;\n    height: 22px;\n  }\n  @media (max-width: 440px) {\n    width: 70px;\n    height: 20px;\n  }\n`;\n\nconst StyledText = css<StyledTextProps>`\n  color: ${(props) => props.color || DARK_TEXT_COLOR};\n  font-size: ${(props) => props.fontSize || '16px'};\n  line-height: ${(props) => props.lineHeight || '24px'};\n`;\n\nexport const TextRegular = css`\n  ${StyledText};\n  font-weight: 400;\n`;\n\nexport const TextMedium = css`\n  ${StyledText};\n  font-weight: 500;\n`;\n\nexport const TextSemiBold = css`\n  ${StyledText};\n  font-weight: 600;\n`;\n\nexport const TextBold = css`\n  ${StyledText};\n  font-weight: 700;\n`;\n\nexport const GeneralAdaptiveFont = css`\n  @media (max-width: 1200px) {\n    font-size: 0.95rem;\n    line-height: 23px;\n  }\n  @media (max-width: 992px) {\n    font-size: 0.9rem;\n    line-height: 22px;\n  }\n  @media (max-width: 768px) {\n    font-size: 0.825rem;\n    line-height: 21px;\n  }\n  @media (max-width: 550px) {\n    font-size: 0.8rem;\n    line-height: 20px;\n  }\n  @media (max-width: 440px) {\n    font-size: 0.68rem;\n    line-height: 18px;\n  }\n`;\n\nexport const HeaderAdaptiveFont = css`\n  font-size: 1rem;\n  line-height: 24px;\n\n  @media (max-width: 768px) {\n    font-size: 0.925rem;\n    line-height: 22px;\n  }\n  @media (max-width: 440px) {\n    font-size: 0.85rem;\n    line-height: 20px;\n  }\n`;\n\nexport const H1AdaptiveFont = css`\n  font-size: 30px;\n  line-height: 45px;\n\n  @media (max-width: 1200px) {\n    font-size: 28px;\n    line-height: 40px;\n  }\n  @media (max-width: 992px) {\n    font-size: 26px;\n    line-height: 38px;\n  }\n  @media (max-width: 768px) {\n    font-size: 24px;\n    line-height: 36px;\n  }\n  @media (max-width: 550px) {\n    font-size: 22px;\n    line-height: 32px;\n  }\n  @media (max-width: 440px) {\n    font-size: 20px;\n    line-height: 28px;\n  }\n`;\n\nexport const H2AdaptiveFont = css`\n  @media (max-width: 1200px) {\n    font-size: 26px;\n    line-height: 35px;\n  }\n  @media (max-width: 992px) {\n    font-size: 24px;\n    line-height: 30px;\n  }\n  @media (max-width: 768px) {\n    font-size: 22px;\n    line-height: 25px;\n  }\n  @media (max-width: 550px) {\n    font-size: 20px;\n    line-height: 25px;\n  }\n  @media (max-width: 440px) {\n    font-size: 17px;\n    line-height: 20px;\n  }\n`;\n\nexport const GeneralButtonPadding = css`\n  padding: 13px 50px;\n  @media (max-width: 1200px) {\n    padding: 11px 45px;\n  }\n  @media (max-width: 992px) {\n    padding: 14px 40px;\n  }\n  @media (max-width: 768px) {\n    padding: 12px 30px;\n  }\n  @media (max-width: 550px) {\n    padding: 10px 25px;\n  }\n  @media (max-width: 440px) {\n    padding: 10px 20px;\n  }\n`;\n\nexport const SVGArrowAdaptive = css`\n  @media (max-width: 992px) {\n    width: 13px;\n    height: 13px;\n  }\n  @media (max-width: 768px) {\n    width: 12px;\n    height: 12px;\n  }\n  @media (max-width: 550px) {\n    width: 11px;\n    height: 11px;\n  }\n  @media (max-width: 440px) {\n    width: 10px;\n    height: 10px;\n  }\n`;\n\nexport const SVGParamsAdaptive = css`\n  width: 16px;\n  height: 16px;\n  @media (max-width: 768px) {\n    width: 15px;\n    height: 15px;\n  }\n  @media (max-width: 550px) {\n    width: 14px;\n    height: 14px;\n  }\n  @media (max-width: 440px) {\n    width: 13px;\n    height: 13px;\n  }\n`;\n\nexport const AdditionalWrapper = styled.div`\n  width: 100%;\n  height: 60px;\n  @media screen and (max-width: 768px) {\n    height: 20px;\n  }\n`;\n\nexport const ScrollBar = css`\n  scrollbar-color: transparent ${TABLE_POPUP_BORDER_COLOR};\n  scrollbar-width: 8px;\n\n  &::-webkit-scrollbar {\n    width: 8px;\n    background-color: transparent;\n  }\n\n  &::-webkit-scrollbar-thumb {\n    background-color: ${TABLE_POPUP_BORDER_COLOR};\n  }\n`;\n\nexport const MainComponentHeight = css`\n  height: calc(100vh - 191px);\n\n  @media (max-width: 992px) {\n    height: calc(100vh - 181px);\n  }\n  @media (max-width: 880px) {\n    height: calc(100vh - 161px);\n  }\n  @media (max-width: 768px) {\n    height: calc(100vh - 146px);\n  }\n  @media (max-width: 550px) {\n    height: calc(100vh - 141px);\n  }\n  @media (max-width: 440px) {\n    height: calc(100vh - 131px);\n  }\n`;\n\nexport const ContentPageWrapper = styled.div`\n  display: flex;\n  width: 100%;\n  justify-content: center;\n  overflow-y: scroll;\n  ${ScrollBar};\n  ${MainComponentHeight};\n`;\n\nexport const PageTitle = styled.h1`\n  ${TextBold};\n  font-size: ${(props) => props.fontSize || '30px'};\n  line-height: ${(props) => props.lineHeight || '45px'};\n  margin-top: 0;\n  ${H1AdaptiveFont};\n`;\n\nexport const PageSubTitle = styled.h2`\n  ${TextSemiBold};\n  color: ${(props) => props.color || WHITE_COLOR};\n  font-size: ${(props) => props.fontSize || '24px'};\n  line-height: ${(props) => props.lineHeight || '36px'};\n  @media screen and (max-width: 768px) {\n    font-size: 16px;\n  }\n`;\n\nexport const Button = styled.button<ButtonProps>`\n  ${TextSemiBold};\n  margin-right: ${({ mr }) => mr || 0};\n  border-radius: 20px;\n  border: none;\n  outline: none;\n  cursor: pointer;\n  background-color: ${({ bgc }) => bgc || MAIN1_COLOR};\n  color: ${({ color }) => color || WHITE_COLOR};\n  ${GeneralAdaptiveFont};\n  ${GeneralButtonPadding}\n`;\n\nexport const TeamButton = styled(Button)`\n  padding: 11px 23px;\n  @media (max-width: 650px) {\n    padding: 8px 16px;\n  }\n`;\n\nexport const CourseButton = styled(TeamButton)`\n  background-color: ${WHITE_COLOR};\n  color: ${DARK_TEXT_COLOR};\n  border-radius: 10px;\n`;\n\nexport const InvertedButton = styled(Button)`\n  background-color: ${BG_COLOR};\n  color: ${MAIN1_COLOR};\n`;\n\nexport const Label = styled.label`\n  ${TextRegular};\n  ${GeneralAdaptiveFont};\n  max-width: 300px;\n  margin-bottom: ${(props) => props.marginBottom || '10px'};\n  color: ${(props) => props.color || LIGHT_TEXT_COLOR};\n`;\n\nexport const Input = styled.input`\n  ${TextMedium};\n  width: 300px;\n  padding: 8px 15px;\n  border-radius: 10px;\n  border: none;\n  background-color: ${BG_COLOR};\n  color: ${(props) => props.color || DARK_TEXT_COLOR};\n  outline: none;\n  ${GeneralAdaptiveFont};\n  @media (max-width: 440px) {\n    width: 100%;\n  }\n  &::placeholder {\n    color: ${LIGHT_TEXT_COLOR};\n  }\n`;\n\nexport const ModalInput = styled(Input)<ModalInputProps>`\n  @keyframes blinkInput {\n    from {\n      background-color: rgb(101, 80, 246, 0.5);\n    }\n    to {\n      background-color: ${BG_COLOR};\n    }\n  }\n\n  animation: ${({ blink }) => (blink ? 'blinkInput 1s' : 'none')};\n  margin-top: ${({ mt }) => mt || '20px'};\n`;\n\nexport const Select = styled.div`\n  display: grid;\n  position: relative;\n  grid-template-areas: 'select';\n  align-items: center;\n  width: 100%;\n  background-color: ${BG_COLOR};\n  border-radius: 10px;\n  cursor: pointer;\n  &:after {\n    position: absolute;\n    content: '*';\n    grid-area: select;\n    width: 12px;\n    height: 7px;\n    background-color: ${LIGHT_TEXT_COLOR};\n    clip-path: polygon(100% 0%, 50% 70%, 0% 0%, 0% 40%, 50% 100%, 100% 40%);\n    justify-self: end;\n    right: 15px;\n  }\n`;\n\nexport const SelectInner = styled.select`\n  ${TextMedium};\n  margin: 0;\n  width: 100%;\n  grid-area: select;\n  padding: 8px 15px;\n  border: none;\n  border-radius: 10px;\n  background-color: transparent;\n  color: ${(props) => props.color || LIGHT_TEXT_COLOR};\n  outline: none;\n  ${GeneralAdaptiveFont}\n  appearance: none;\n  z-index: 1;\n  cursor: pointer;\n  option {\n    color: ${DARK_TEXT_COLOR};\n  }\n`;\n\nexport const ButtonsBlock = styled.div`\n  display: flex;\n  justify-content: space-around;\n  margin-top: 30px;\n  margin-bottom: 10px;\n`;\n"
  },
  {
    "path": "src/typography/normalize.css",
    "content": "/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n   ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n  line-height: 1.15; /* 1 */\n\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n   ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n  margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n  display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n  margin: 0.67em 0;\n  font-size: 2em;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n  box-sizing: content-box; /* 1 */\n  height: 0; /* 1 */\n  overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n  font-size: 1em; /* 2 */\n  font-family: monospace, monospace; /* 1 */\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n  text-decoration: underline; /* 2 */\n  text-decoration: underline dotted; /* 2 */\n  border-bottom: none; /* 1 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n  font-size: 1em; /* 2 */\n  font-family: monospace, monospace; /* 1 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n  border-style: none;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0; /* 2 */\n  font-size: 100%; /* 1 */\n  line-height: 1.15; /* 1 */\n  font-family: inherit; /* 1 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput {\n  /* 1 */\n  overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect {\n  /* 1 */\n  text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n  -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n  outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n  padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n *    `fieldset` elements in all browsers.\n */\n\nlegend {\n  display: table; /* 1 */\n  box-sizing: border-box; /* 1 */\n  max-width: 100%; /* 1 */\n  padding: 0; /* 3 */\n  color: inherit; /* 2 */\n  white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n  vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n  outline-offset: -2px; /* 2 */\n\n  -webkit-appearance: textfield; /* 1 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n  font: inherit; /* 2 */\n\n  -webkit-appearance: button; /* 1 */\n}\n\n/* Interactive\n   ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n  display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n  display: list-item;\n}\n\n/* Misc\n   ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n  display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n  display: none;\n}\n"
  },
  {
    "path": "src/utils/isFieldValid.ts",
    "content": "export const isFieldValid = (\n  value: string,\n  validateRules: any,\n  needValidate: boolean,\n  setInputValid: (valid: boolean) => void,\n  setErrorMessage: (message: string) => void,\n  isValueUniq?: (courseName: string) => boolean\n) => {\n  if (!needValidate) return true;\n\n  const trimmedValueLength = value.trim().length;\n  let valid = true;\n\n  if (validateRules.maxLength) {\n    valid = trimmedValueLength < validateRules.maxLength.value + 1 && valid;\n    if (!(trimmedValueLength < validateRules.maxLength.value + 1)) {\n      setErrorMessage(validateRules.maxLength.message);\n    }\n  }\n\n  if (validateRules.minLength) {\n    valid = trimmedValueLength >= validateRules.minLength.value && valid;\n    if (!(trimmedValueLength >= validateRules.minLength.value)) {\n      setErrorMessage(validateRules.minLength.message);\n    }\n  }\n\n  if (validateRules.pattern) {\n    const regExp = new RegExp(validateRules.pattern.value);\n    valid = regExp.test(value) && valid;\n    if (!regExp.test(value)) {\n      setErrorMessage(validateRules.pattern.message);\n    }\n  }\n\n  if (validateRules.uniq && isValueUniq) {\n    const isFieldValueUniq = isValueUniq(value.trim());\n    valid = isFieldValueUniq && valid;\n    if (!isFieldValueUniq) {\n      setErrorMessage(validateRules.uniq.message);\n    }\n  }\n\n  setInputValid(valid);\n};\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react-jsx\",\n    \"baseUrl\": \"./src\"\n  },\n  \"include\": [\n    \"src\"\n  ]\n}\n"
  }
]