├── .babelrc
├── .dockerignore
├── .env.development
├── .env.example
├── .env.production
├── .eslintignore
├── .eslintrc.json
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── enhancement.md
│ └── feature.md
└── workflows
│ ├── build.yml
│ └── deployment.yml
├── .gitignore
├── .prettierrc.js
├── .storybook
├── main.ts
└── preview.tsx
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── next-env.d.ts
├── next.config.js
├── package.json
├── public
├── favicon.ico
├── gifs
│ ├── frog-complete.gif
│ ├── frogging.gif
│ └── grey-frog.gif
├── icons
│ ├── 404-page
│ │ ├── 404-frog.svg
│ │ ├── clouds-desktop.svg
│ │ ├── clouds-mobile.svg
│ │ ├── leaves-left.svg
│ │ ├── leaves-right-mobile.svg
│ │ └── leaves-right.svg
│ ├── check-mark.svg
│ ├── fly-logo.svg
│ ├── frog.svg
│ ├── halloween-logo.svg
│ ├── logo.svg
│ ├── schedule-line.svg
│ ├── schedule-page
│ │ └── grid-pattern.svg
│ ├── stars-empty.svg
│ └── stars-full.svg
└── images
│ ├── about-page
│ ├── basic.png
│ ├── dayF-mobile.png
│ ├── dayF.png
│ ├── events-mobile.png
│ ├── events.png
│ ├── military-cerf.png
│ ├── vitrazh-mobile.png
│ ├── vitrazh.png
│ └── wallFICE.png
│ ├── frog-avatar.png
│ ├── lecturer-avatar.png
│ ├── login-page
│ ├── login-background.png
│ └── new-logo.png
│ ├── logo.png
│ ├── main-page
│ ├── avatars
│ │ ├── artem.png
│ │ ├── danya.png
│ │ ├── dima.png
│ │ ├── illia.png
│ │ ├── katya.png
│ │ ├── oleg.png
│ │ ├── pasha.png
│ │ ├── sasha.png
│ │ ├── stas.png
│ │ ├── svyat.png
│ │ └── vovka.png
│ └── main-background.png
│ ├── preview.jpg
│ └── register-page
│ └── background.png
├── src
├── components
│ ├── common
│ │ ├── icons
│ │ │ ├── BannerImage.tsx
│ │ │ ├── Captain.tsx
│ │ │ ├── CustomCheck.tsx
│ │ │ ├── CustomEnvelopeOpen.tsx
│ │ │ ├── CustomTelegram.tsx
│ │ │ ├── Discord.tsx
│ │ │ ├── DoubleCheck.tsx
│ │ │ ├── Facebook.tsx
│ │ │ ├── GitHub.tsx
│ │ │ ├── Instagram.tsx
│ │ │ ├── Mail.tsx
│ │ │ ├── Moderator.tsx
│ │ │ ├── StarsEmpty.tsx
│ │ │ ├── StarsFull.tsx
│ │ │ ├── Telegram.tsx
│ │ │ ├── TelegramForAccount.tsx
│ │ │ ├── TikTok.tsx
│ │ │ ├── Twitter.tsx
│ │ │ └── YouTube.tsx
│ │ ├── layout
│ │ │ ├── admin-panel-layout
│ │ │ │ ├── AdminPanelLayout.styles.ts
│ │ │ │ └── AdminPanelLayout.tsx
│ │ │ ├── admin-panel
│ │ │ │ ├── AdminPanel.styles.ts
│ │ │ │ ├── AdminPanel.tsx
│ │ │ │ └── constants
│ │ │ │ │ └── index.tsx
│ │ │ ├── footer
│ │ │ │ ├── Footer.styles.ts
│ │ │ │ ├── Footer.tsx
│ │ │ │ ├── constants
│ │ │ │ │ └── index.tsx
│ │ │ │ └── index.ts
│ │ │ ├── header
│ │ │ │ ├── Header.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── authentication-buttons
│ │ │ │ │ │ ├── AuthenticationButtons.styles.ts
│ │ │ │ │ │ ├── AuthenticationButtons.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── desktop-header
│ │ │ │ │ │ ├── DesktopHeader.styles.ts
│ │ │ │ │ │ ├── DesktopHeader.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── header-desktop-card
│ │ │ │ │ │ ├── HeaderDesktopCard.styles.ts
│ │ │ │ │ │ ├── HeaderDesktopCard.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── header-mobile-card
│ │ │ │ │ │ ├── HeaderMobileCard.styles.ts
│ │ │ │ │ │ ├── HeaderMobileCard.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── mobile-header
│ │ │ │ │ │ ├── MobileHeader.styles.ts
│ │ │ │ │ │ ├── MobileHeader.tsx
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ └── drawer
│ │ │ │ │ │ │ ├── Drawer.styles.ts
│ │ │ │ │ │ │ ├── Drawer.tsx
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── constants
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.ts
│ │ │ │ ├── types
│ │ │ │ │ └── index.ts
│ │ │ │ └── utils
│ │ │ │ │ └── transformData.ts
│ │ │ └── page-layout
│ │ │ │ ├── PageLayout.module.scss
│ │ │ │ ├── PageLayout.tsx
│ │ │ │ └── index.ts
│ │ └── ui
│ │ │ ├── alert-button
│ │ │ ├── AlertButton.stories.ts
│ │ │ ├── AlertButton.styles.ts
│ │ │ ├── AlertButton.tsx
│ │ │ ├── index.ts
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ │ └── get-colors.ts
│ │ │ ├── alert
│ │ │ ├── Alert.stories.ts
│ │ │ ├── Alert.styles.ts
│ │ │ ├── Alert.tsx
│ │ │ ├── index.ts
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ │ └── get-color.ts
│ │ │ ├── breadcrumbs
│ │ │ ├── Breadcrumbs.stories.ts
│ │ │ ├── Breadcrumbs.styles.ts
│ │ │ ├── Breadcrumbs.tsx
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── button-mui
│ │ │ ├── Button.stories.ts
│ │ │ ├── Button.styles.ts
│ │ │ ├── Button.tsx
│ │ │ ├── index.ts
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ │ └── get-colors.ts
│ │ │ ├── button
│ │ │ ├── Button.module.scss
│ │ │ ├── Button.tsx
│ │ │ ├── index.ts
│ │ │ └── styles
│ │ │ │ ├── button-style.scss
│ │ │ │ ├── primary.scss
│ │ │ │ └── secondary.scss
│ │ │ ├── cards
│ │ │ ├── card-roles
│ │ │ │ ├── CardRoles.module.scss
│ │ │ │ ├── CardRoles.tsx
│ │ │ │ └── index.ts
│ │ │ ├── floating-card
│ │ │ │ ├── FloatingCard.styles.ts
│ │ │ │ ├── FloatingCard.tsx
│ │ │ │ └── index.ts
│ │ │ ├── personal-teacher-card
│ │ │ │ ├── PersonalTeacherCard.styles.ts
│ │ │ │ ├── PersonalTeacherCard.tsx
│ │ │ │ └── index.ts
│ │ │ ├── poll-card
│ │ │ │ ├── PollCard.styles.ts
│ │ │ │ ├── PollCard.tsx
│ │ │ │ └── index.ts
│ │ │ ├── poll-teacher-card
│ │ │ │ ├── PollTeacherCard.module.scss
│ │ │ │ ├── PollTeacherCard.tsx
│ │ │ │ ├── SkipTeacherPopup.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── pollTeachaerCard.styles.ts
│ │ │ ├── subject-card
│ │ │ │ ├── SubjectCard.styles.ts
│ │ │ │ ├── SubjectCard.tsx
│ │ │ │ └── index.ts
│ │ │ ├── teacher-card
│ │ │ │ ├── TeacherCard.styles.ts
│ │ │ │ ├── TeacherCard.tsx
│ │ │ │ └── index.ts
│ │ │ ├── teacher-header-card
│ │ │ │ ├── TeacherHeaderCard.styles.ts
│ │ │ │ ├── TeacherHeaderCard.tsx
│ │ │ │ └── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── circle-diagram
│ │ │ ├── CircleDiagram.stories.ts
│ │ │ ├── CircleDiagram.styles.ts
│ │ │ ├── CircleDiagram.tsx
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── column-chart
│ │ │ ├── ColumnChart.stories.ts
│ │ │ ├── ColumnChart.styles.ts
│ │ │ ├── ColumnChart.tsx
│ │ │ ├── index.ts
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ │ ├── get-data.ts
│ │ │ │ └── get-options.ts
│ │ │ ├── comment
│ │ │ ├── Comment.stories.ts
│ │ │ ├── Comment.styles.ts
│ │ │ ├── Comment.tsx
│ │ │ └── index.ts
│ │ │ ├── custom-link
│ │ │ ├── CustomLink.stories.ts
│ │ │ ├── CustomLink.styles.ts
│ │ │ ├── CustomLink.tsx
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── divider
│ │ │ ├── Divider.stories.ts
│ │ │ ├── Divider.styles.ts
│ │ │ ├── Divider.tsx
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── form
│ │ │ ├── checkbox
│ │ │ │ ├── Checkbox.stories.ts
│ │ │ │ ├── Checkbox.styles.ts
│ │ │ │ ├── Checkbox.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── CheckedIcon.tsx
│ │ │ │ │ └── Icon.tsx
│ │ │ │ ├── constants
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ │ └── index.ts
│ │ │ ├── common
│ │ │ │ └── types.ts
│ │ │ ├── dropdown
│ │ │ │ ├── Dropdown.stories.tsx
│ │ │ │ ├── Dropdown.styles.ts
│ │ │ │ ├── Dropdown.tsx
│ │ │ │ ├── components
│ │ │ │ │ └── option
│ │ │ │ │ │ ├── Option.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── constants
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── input-mui
│ │ │ │ ├── Input.stories.tsx
│ │ │ │ ├── Input.styles.ts
│ │ │ │ ├── Input.tsx
│ │ │ │ ├── constants
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── types
│ │ │ │ │ └── index.ts
│ │ │ │ └── util
│ │ │ │ │ └── index.ts
│ │ │ ├── input
│ │ │ │ ├── Input.module.scss
│ │ │ │ ├── Input.tsx
│ │ │ │ └── index.ts
│ │ │ ├── numbered-text-area
│ │ │ │ ├── NumberedTextArea.stories.tsx
│ │ │ │ ├── NumberedTextArea.styles.ts
│ │ │ │ ├── NumberedTextArea.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── LineNumbers.styles.ts
│ │ │ │ │ ├── LineNumbers.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── types
│ │ │ │ │ └── index.ts
│ │ │ │ └── utils
│ │ │ │ │ └── index.tsx
│ │ │ ├── radio
│ │ │ │ ├── RadioGroup.stories.tsx
│ │ │ │ ├── RadioGroup.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── radio-button
│ │ │ │ │ ├── Radio.styles.ts
│ │ │ │ │ ├── Radio.tsx
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── radio.stories.tsx
│ │ │ ├── slider
│ │ │ │ ├── Slider.stories.tsx
│ │ │ │ ├── Slider.styles.ts
│ │ │ │ ├── Slider.tsx
│ │ │ │ ├── const
│ │ │ │ │ └── marks.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ │ └── index.ts
│ │ │ ├── switch
│ │ │ │ ├── Switch.stories.ts
│ │ │ │ ├── Switch.styles.ts
│ │ │ │ ├── Switch.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ │ └── index.ts
│ │ │ ├── text-area-mui
│ │ │ │ ├── TextArea.stories.tsx
│ │ │ │ ├── TextArea.styles.ts
│ │ │ │ ├── TextArea.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ │ └── index.ts
│ │ │ └── with-formik
│ │ │ │ ├── checkbox
│ │ │ │ ├── FormikCheckbox.stories.tsx
│ │ │ │ ├── FormikCheckbox.tsx
│ │ │ │ └── index.ts
│ │ │ │ ├── dropdown
│ │ │ │ ├── FormikDropdown.stories.tsx
│ │ │ │ ├── FormikDropdown.tsx
│ │ │ │ └── index.ts
│ │ │ │ ├── input
│ │ │ │ ├── FormikInput.stories.tsx
│ │ │ │ ├── FormikInput.tsx
│ │ │ │ └── index.ts
│ │ │ │ ├── numbered-text-area
│ │ │ │ ├── FormikNumberedTextArea.tsx
│ │ │ │ └── index.ts
│ │ │ │ ├── radio
│ │ │ │ ├── FormikRadio.tsx
│ │ │ │ ├── FormikRadioGroup.tsx
│ │ │ │ └── RadioGroup.stories.tsx
│ │ │ │ └── slider
│ │ │ │ ├── FormikSlider.tsx
│ │ │ │ └── index.ts
│ │ │ ├── icon-button-mui
│ │ │ ├── IconButton.styles.ts
│ │ │ ├── IconButton.tsx
│ │ │ ├── index.ts
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ ├── utils
│ │ │ │ └── get-color.ts
│ │ │ └── variants
│ │ │ │ ├── ArrowButton
│ │ │ │ ├── ArrowButton.stories.ts
│ │ │ │ ├── ArrowButton.styles.ts
│ │ │ │ └── ArrowButton.tsx
│ │ │ │ ├── CloseButton
│ │ │ │ ├── CloseButton.stories.ts
│ │ │ │ └── CloseButton.tsx
│ │ │ │ ├── SortButton
│ │ │ │ ├── SortButton.stories.ts
│ │ │ │ └── SortButton.tsx
│ │ │ │ ├── StarButton
│ │ │ │ ├── StarButton.stories.ts
│ │ │ │ └── StarButton.tsx
│ │ │ │ ├── TrashBucketButton
│ │ │ │ ├── TrashBucketButton.stories.ts
│ │ │ │ └── TrashBucketButton.tsx
│ │ │ │ └── index.ts
│ │ │ ├── icon-button
│ │ │ ├── IconButton.module.scss
│ │ │ ├── IconButton.tsx
│ │ │ └── index.ts
│ │ │ ├── line-graph
│ │ │ ├── LineGraph.stories.ts
│ │ │ ├── LineGraph.styles.ts
│ │ │ ├── LineGraph.tsx
│ │ │ ├── index.ts
│ │ │ └── utils
│ │ │ │ ├── check-value.ts
│ │ │ │ └── get-color.ts
│ │ │ ├── pop-ups
│ │ │ ├── Popup
│ │ │ │ ├── Popup.stories.tsx
│ │ │ │ ├── Popup.styles.ts
│ │ │ │ ├── Popup.tsx
│ │ │ │ └── index.ts
│ │ │ ├── PopupActions
│ │ │ │ ├── PopupActions.styles.ts
│ │ │ │ ├── PopupActions.tsx
│ │ │ │ └── index.ts
│ │ │ ├── PopupContent
│ │ │ │ ├── PopupContent.styles.ts
│ │ │ │ ├── PopupContent.tsx
│ │ │ │ └── index.ts
│ │ │ └── PopupTitle
│ │ │ │ ├── PopupTitle.styles.ts
│ │ │ │ ├── PopupTitle.tsx
│ │ │ │ └── index.ts
│ │ │ ├── progress
│ │ │ ├── Progress.stories.ts
│ │ │ ├── Progress.styles.ts
│ │ │ ├── Progress.tsx
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── radar
│ │ │ ├── Radar.styles.ts
│ │ │ ├── Radar.tsx
│ │ │ ├── index.ts
│ │ │ └── utils
│ │ │ │ ├── drawData.ts
│ │ │ │ ├── findImage.tsx
│ │ │ │ ├── getOptions.ts
│ │ │ │ └── radar-background
│ │ │ │ ├── 11-mobile.tsx
│ │ │ │ ├── 12-mobile.tsx
│ │ │ │ ├── 13-mobile.tsx
│ │ │ │ ├── 15-mobile.tsx
│ │ │ │ ├── lab-12-desktop.tsx
│ │ │ │ ├── lect-11-desktop.tsx
│ │ │ │ ├── lect-lab-13-desktop.tsx
│ │ │ │ ├── lect-pract-13-desktop.tsx
│ │ │ │ ├── lect-pract-lab-15-desktop.tsx
│ │ │ │ └── pract-12-desktop.tsx
│ │ │ ├── rating
│ │ │ ├── Rating.stories.ts
│ │ │ ├── Rating.styles.ts
│ │ │ ├── Rating.tsx
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── tab
│ │ │ ├── index.ts
│ │ │ ├── tab-context
│ │ │ │ ├── TabContext.tsx
│ │ │ │ └── index.ts
│ │ │ ├── tab-list
│ │ │ │ ├── TabList.tsx
│ │ │ │ └── index.ts
│ │ │ ├── tab-panel
│ │ │ │ ├── TabPanel.styles.ts
│ │ │ │ ├── TabPanel.tsx
│ │ │ │ └── index.ts
│ │ │ └── tab
│ │ │ │ ├── Tab.stories.tsx
│ │ │ │ ├── Tab.styles.ts
│ │ │ │ ├── Tab.tsx
│ │ │ │ ├── components
│ │ │ │ └── CustomLabel.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ ├── tag
│ │ │ ├── Tag.stories.ts
│ │ │ ├── Tag.styles.ts
│ │ │ ├── Tag.tsx
│ │ │ ├── index.ts
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ │ └── get-color.ts
│ │ │ ├── toast
│ │ │ ├── Toast.stories.tsx
│ │ │ ├── Toast.styles.ts
│ │ │ ├── Toast.tsx
│ │ │ └── index.ts
│ │ │ └── tooltip
│ │ │ ├── Tooltip.stories.tsx
│ │ │ ├── Tooltip.styles.tsx
│ │ │ ├── Tooltip.tsx
│ │ │ └── index.ts
│ └── pages
│ │ ├── 404-page
│ │ ├── NotFoundPage.styles.ts
│ │ ├── NotFoundPage.tsx
│ │ └── index.ts
│ │ ├── about-page
│ │ ├── AboutPage.styles.ts
│ │ ├── AboutPage.tsx
│ │ ├── components
│ │ │ ├── MobileStudActivityCard.styles.ts
│ │ │ ├── MobileStudActivityCard.tsx
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ └── types
│ │ │ └── index.ts
│ │ ├── account-page
│ │ ├── AccountPage.styles.ts
│ │ ├── AccountPage.tsx
│ │ ├── components
│ │ │ ├── general-tab
│ │ │ │ ├── GeneralTab.styles.ts
│ │ │ │ ├── GeneralTab.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── change-avatar-window
│ │ │ │ │ │ ├── ChangeAvatarWindow.styles.ts
│ │ │ │ │ │ ├── ChangeAvatarWindow.tsx
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ └── avatar-dropzone
│ │ │ │ │ │ │ │ ├── AvatarDropzone.styles.ts
│ │ │ │ │ │ │ │ ├── AvatarDropzone.tsx
│ │ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ │ └── utils
│ │ │ │ │ │ │ │ └── handleFileSelect.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── contacts-block
│ │ │ │ │ │ ├── ContactsBlock.styles.ts
│ │ │ │ │ │ ├── ContactsBlock.tsx
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ ├── ContactForm.tsx
│ │ │ │ │ │ │ └── ContactItem.tsx
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── types
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── validation
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── personal-info
│ │ │ │ │ │ ├── PersonalInfo.styles.ts
│ │ │ │ │ │ ├── PersonalInfo.tsx
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── types
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── validation
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── utils
│ │ │ │ │ └── isValidFile.ts
│ │ │ ├── group-tab
│ │ │ │ ├── GroupTab.styles.ts
│ │ │ │ ├── GroupTab.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── no-group-block
│ │ │ │ │ │ ├── NoGroupBlock.styles.ts
│ │ │ │ │ │ ├── NoGroupBlock.tsx
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── utils
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── validation
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── table
│ │ │ │ │ │ ├── constants
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── grid.styles.ts
│ │ │ │ │ │ ├── requests-table
│ │ │ │ │ │ │ ├── RequestTable.styles.ts
│ │ │ │ │ │ │ ├── RequestsTable.tsx
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── student-table
│ │ │ │ │ │ │ ├── StudentsTable.styles.ts
│ │ │ │ │ │ │ ├── StudentsTable.tsx
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ ├── EditingColumn.tsx
│ │ │ │ │ │ │ │ ├── MobileDropdown.style.ts
│ │ │ │ │ │ │ │ └── MobileDropdown.tsx
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── types
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── utils
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── text-area-popup
│ │ │ │ │ │ ├── TextAreaPopup.styles.ts
│ │ │ │ │ │ ├── TextAreaPopup.tsx
│ │ │ │ │ │ ├── constants
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── validation
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── index.ts
│ │ │ ├── security-tab
│ │ │ │ ├── SecurityTab.styles.ts
│ │ │ │ ├── SecurityTab.tsx
│ │ │ │ ├── components
│ │ │ │ │ └── change-password-form
│ │ │ │ │ │ ├── ChangePasswordForm.styles.ts
│ │ │ │ │ │ ├── ChangePasswordForm.tsx
│ │ │ │ │ │ ├── constants
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── types
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── validation
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── index.ts
│ │ │ └── selective-tab
│ │ │ │ ├── SelectiveTab.styles.ts
│ │ │ │ ├── SelectiveTab.tsx
│ │ │ │ ├── components
│ │ │ │ ├── opened-selective
│ │ │ │ │ ├── OpenedSelective.styles.ts
│ │ │ │ │ ├── OpenedSelective.tsx
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── utils
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── selective-block
│ │ │ │ │ ├── SelectiveBlock.styles.ts
│ │ │ │ │ ├── SelectiveBlock.tsx
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── utils
│ │ │ │ │ └── index.ts
│ │ │ │ └── index.ts
│ │ ├── index.ts
│ │ └── types
│ │ │ └── index.ts
│ │ ├── admin
│ │ └── admin-default
│ │ │ ├── AdminMainPage.styles.ts
│ │ │ ├── AdminMainPage.tsx
│ │ │ └── index.ts
│ │ ├── contract-admin-page
│ │ ├── ContractAdminPage.styles.ts
│ │ ├── ContractAdminPage.tsx
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── utils
│ │ │ └── index.ts
│ │ └── validation
│ │ │ └── index.ts
│ │ ├── contract-page
│ │ ├── ContractPage.module.scss
│ │ ├── ContractPage.styles.ts
│ │ ├── ContractPage.tsx
│ │ ├── components
│ │ │ ├── Actions.tsx
│ │ │ ├── PassFormAgain.tsx
│ │ │ ├── personal-form
│ │ │ │ ├── PersonalForm.styles.ts
│ │ │ │ └── PersonalForm.tsx
│ │ │ └── steps
│ │ │ │ ├── FirstStep.tsx
│ │ │ │ ├── FourthStep.tsx
│ │ │ │ ├── SecondStep.tsx
│ │ │ │ └── ThirdStep.tsx
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── utils
│ │ │ ├── localStorage.ts
│ │ │ └── prepareData.ts
│ │ └── validation
│ │ │ ├── constants.ts
│ │ │ ├── customer.ts
│ │ │ ├── entrant.ts
│ │ │ ├── meta.ts
│ │ │ └── representative.ts
│ │ ├── email-confirmation-page
│ │ ├── EmailConfirmationPage.module.ts
│ │ ├── EmailConfirmationPage.tsx
│ │ └── index.ts
│ │ ├── entrant-admin-page
│ │ ├── EntrantAdminPage.tsx
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── utils
│ │ │ ├── localStorage.ts
│ │ │ └── prepareData.ts
│ │ └── validation
│ │ │ └── index.ts
│ │ ├── entrant-dashboard-page
│ │ ├── EntrantDashboardPage.styles.ts
│ │ ├── EntrantDashboardPage.tsx
│ │ ├── components
│ │ │ ├── ContractDetailsSection.tsx
│ │ │ ├── ContractPersonalDetailsSection.tsx
│ │ │ ├── PersonalDataSection.tsx
│ │ │ ├── PrioritiesSection.tsx
│ │ │ ├── entrant-approve-form
│ │ │ │ ├── ContractApproveForm.tsx
│ │ │ │ ├── constants.ts
│ │ │ │ └── validation.ts
│ │ │ └── entrant-search-form
│ │ │ │ ├── EntrantSearchForm.tsx
│ │ │ │ ├── constants.ts
│ │ │ │ └── validation.ts
│ │ ├── index.ts
│ │ └── utils
│ │ │ └── localStorage.ts
│ │ ├── login-page
│ │ ├── LoginPage.styles.ts
│ │ ├── LoginPage.tsx
│ │ ├── components
│ │ │ ├── login-form-block
│ │ │ │ ├── LoginFormBlock.module.scss
│ │ │ │ ├── LoginFormBlock.styles.ts
│ │ │ │ ├── LoginFormBlock.tsx
│ │ │ │ ├── components
│ │ │ │ │ └── login-form
│ │ │ │ │ │ ├── LoginForm.styles.ts
│ │ │ │ │ │ ├── LoginForm.tsx
│ │ │ │ │ │ ├── constants
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── types
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── validation
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── index.ts
│ │ │ └── logo-register-block
│ │ │ │ ├── LogoRegisterBlock.styles.ts
│ │ │ │ ├── LogoRegisterBlock.tsx
│ │ │ │ └── index.ts
│ │ └── index.ts
│ │ ├── main-page
│ │ ├── MainPage.module.scss
│ │ ├── MainPage.styles.ts
│ │ ├── MainPage.tsx
│ │ ├── completely-normal-folder
│ │ │ ├── GreetingBlock.module.scss
│ │ │ ├── GreetingBlock.styles.ts
│ │ │ └── GreetingBlock.tsx
│ │ ├── components
│ │ │ ├── resource-card
│ │ │ │ ├── ResourceCard.styles.ts
│ │ │ │ ├── ResourceCard.tsx
│ │ │ │ └── index.ts
│ │ │ └── token-popup
│ │ │ │ ├── TokenPopup.tsx
│ │ │ │ └── index.ts
│ │ └── index.ts
│ │ ├── password-recovery
│ │ ├── create-password-page
│ │ │ ├── CreatePasswordPage.module.scss
│ │ │ ├── CreatePasswordPage.styles.ts
│ │ │ ├── CreatePasswordPage.tsx
│ │ │ ├── components
│ │ │ │ └── create-password-form
│ │ │ │ │ ├── CreatePasswordForm.tsx
│ │ │ │ │ ├── constants
│ │ │ │ │ └── index.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types
│ │ │ │ │ └── index.ts
│ │ │ │ │ └── validation
│ │ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ ├── email-confirmation-page
│ │ │ ├── PasswordResetEmailConfirmationPage.tsx
│ │ │ ├── index.ts
│ │ │ └── utils
│ │ │ │ └── chooseMessageError.ts
│ │ ├── forgot-password-page
│ │ │ ├── ForgotPasswordPage.module.scss
│ │ │ ├── ForgotPasswordPage.styles.ts
│ │ │ ├── ForgotPasswordPage.tsx
│ │ │ ├── components
│ │ │ │ └── forgot-password-form
│ │ │ │ │ ├── ForgotPasswordForm.tsx
│ │ │ │ │ ├── constants
│ │ │ │ │ └── index.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types
│ │ │ │ │ └── index.ts
│ │ │ │ │ └── validation
│ │ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ ├── link-expired
│ │ │ ├── PasswordResetLinkExpiredPage.styles.ts
│ │ │ ├── PasswordResetLinkExpiredPage.tsx
│ │ │ └── index.ts
│ │ └── link-valid
│ │ │ ├── PasswordResetValidLinkPage.styles.ts
│ │ │ ├── PasswordResetValidLinkPage.tsx
│ │ │ └── index.ts
│ │ ├── personal-teacher-page
│ │ ├── PersonalTeacherPage.module.scss
│ │ ├── PersonalTeacherPage.tsx
│ │ ├── contacts
│ │ │ ├── Contact.module.scss
│ │ │ ├── Contact.tsx
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── personal-teacher-tabs
│ │ │ ├── PersonalTeacherTabs.styles.ts
│ │ │ ├── PersonalTeacherTabs.tsx
│ │ │ ├── components
│ │ │ │ ├── comment-tab
│ │ │ │ │ ├── CommentTab.styles.ts
│ │ │ │ │ ├── CommentTab.tsx
│ │ │ │ │ ├── constants
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── general-tab
│ │ │ │ │ ├── GeneralTab.styles.ts
│ │ │ │ │ ├── GeneralTab.tsx
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── FillerBox.styles.ts
│ │ │ │ │ │ ├── FillerBox.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── poll-buttons
│ │ │ │ │ ├── PollButtons.styles.ts
│ │ │ │ │ ├── PollButtons.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ └── subject-tab
│ │ │ │ │ ├── SubjectTab.styles.ts
│ │ │ │ │ ├── SubjectTab.tsx
│ │ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ └── utils
│ │ │ └── index.ts
│ │ ├── personal-teacher-subject-page
│ │ ├── PersonalTeacherSubjectPage.module.scss
│ │ ├── PersonalTeacherSubjectPage.tsx
│ │ ├── contacts
│ │ │ ├── Contact.module.scss
│ │ │ ├── Contact.tsx
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ └── personal-subject-teacher-tabs
│ │ │ ├── PersonalSubjectTeacherTabs.styles.ts
│ │ │ ├── PersonalSubjectTeacherTabs.tsx
│ │ │ └── index.ts
│ │ ├── poll-fucked-page
│ │ ├── PollPageFailed.styles.ts
│ │ ├── PollPageFailed.tsx
│ │ └── index.ts
│ │ ├── poll-page
│ │ ├── PollPage.styles.ts
│ │ ├── PollPage.tsx
│ │ ├── components
│ │ │ ├── answers-sheet
│ │ │ │ ├── AnswerSheet.style.ts
│ │ │ │ ├── AnswersSaved
│ │ │ │ │ ├── AnswerSaved.style.ts
│ │ │ │ │ ├── AnswersSaved.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── AnswersSheet.module.scss
│ │ │ │ ├── AnswersSheet.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── validation
│ │ │ │ │ └── index.ts
│ │ │ ├── poll-form
│ │ │ │ ├── PollForm.styles.ts
│ │ │ │ ├── PollForm.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── types
│ │ │ │ │ └── index.ts
│ │ │ ├── questions-list
│ │ │ │ ├── QuestionsList.styles.ts
│ │ │ │ ├── QuestionsList.tsx
│ │ │ │ └── index.ts
│ │ │ └── single-question
│ │ │ │ ├── SingleQuestion.style.ts
│ │ │ │ └── SingleQuestion.tsx
│ │ └── index.ts
│ │ ├── priority-approve-page
│ │ ├── PriorityApprovePage.styles.ts
│ │ ├── PriorityApprovePage.tsx
│ │ ├── components
│ │ │ ├── EntrantPriorityForm.tsx
│ │ │ └── EntrantPriorityPage.tsx
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── utils
│ │ │ ├── checkError.ts
│ │ │ ├── getPriorityName.ts
│ │ │ └── getSpecialityName.ts
│ │ └── validation
│ │ │ └── index.ts
│ │ ├── priority-page
│ │ ├── PriorityPage.styles.ts
│ │ ├── PriorityPage.tsx
│ │ ├── SuccessScreen.tsx
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── utils
│ │ │ ├── localStorage.ts
│ │ │ └── prepareData.ts
│ │ └── validation
│ │ │ └── index.ts
│ │ ├── privacy-page
│ │ ├── PrivacyPage.styles.ts
│ │ ├── PrivacyPage.tsx
│ │ └── index.ts
│ │ ├── register
│ │ ├── email-confirmation-page
│ │ │ ├── RegistrationEmailConfirmationPage.tsx
│ │ │ └── index.ts
│ │ ├── register-page
│ │ │ ├── RegisterImage.module.scss
│ │ │ ├── RegisterPage.styles.ts
│ │ │ ├── RegisterPage.tsx
│ │ │ ├── components
│ │ │ │ ├── left-block
│ │ │ │ │ ├── LeftBlock.styles.ts
│ │ │ │ │ ├── LeftBlock.tsx
│ │ │ │ │ ├── Link.module.scss
│ │ │ │ │ └── index.ts
│ │ │ │ ├── register-form
│ │ │ │ │ ├── FormStyles.module.scss
│ │ │ │ │ ├── RegisterForm.styles.ts
│ │ │ │ │ ├── RegisterForm.tsx
│ │ │ │ │ ├── constants
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── utils
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── validation
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── right-block
│ │ │ │ │ ├── RightBlock.module.scss
│ │ │ │ │ ├── RightBlock.styles.ts
│ │ │ │ │ ├── RightBlock.tsx
│ │ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ └── verify-email-token-page
│ │ │ ├── VerifyEmailTokenPage.styles.ts
│ │ │ ├── VerifyEmailTokenPage.tsx
│ │ │ └── index.ts
│ │ ├── schedule-page
│ │ ├── SchedulePage.styles.ts
│ │ ├── SchedulePage.tsx
│ │ ├── calendar-section
│ │ │ ├── CalendarSection.styles.ts
│ │ │ ├── CalendarSection.tsx
│ │ │ └── components
│ │ │ │ ├── checkboxes-section
│ │ │ │ ├── CheckBoxSection.styles.ts
│ │ │ │ └── CheckBoxSection.tsx
│ │ │ │ ├── date-picker
│ │ │ │ ├── DatePicker.styles.ts
│ │ │ │ └── DatePicker.tsx
│ │ │ │ ├── groups-dropdown
│ │ │ │ └── GroupsDropDown.tsx
│ │ │ │ ├── mobile
│ │ │ │ ├── CalendarSectionMobile.styles.ts
│ │ │ │ ├── CalendarSectionMobile.tsx
│ │ │ │ ├── buttonIcons
│ │ │ │ │ ├── ButtonIcons.tsx
│ │ │ │ │ └── buttonIcons.styles.ts
│ │ │ │ ├── checkboxes-dropdown
│ │ │ │ │ ├── CheckboxesDropDown.styles.ts
│ │ │ │ │ ├── CheckboxesDropDown.tsx
│ │ │ │ │ ├── constants
│ │ │ │ │ │ └── CheckboxConstants.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ └── CheckboxOption.ts
│ │ │ │ └── weekArrows
│ │ │ │ │ └── WeekArrows.tsx
│ │ │ │ └── tabs-section
│ │ │ │ ├── TabSection.styles.ts
│ │ │ │ └── TabSection.tsx
│ │ ├── constants.ts
│ │ ├── index.ts
│ │ ├── schedule-event-edit-section
│ │ │ ├── ScheduleEventEdit.tsx
│ │ │ ├── index.tsx
│ │ │ ├── schedule-form
│ │ │ │ ├── ScheduleEventForm.styles.ts
│ │ │ │ ├── ScheduleEventForm.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── add-delete-teachers
│ │ │ │ │ │ ├── AddDeleteTeachers.styles.ts
│ │ │ │ │ │ ├── AddDeleteTeachers.tsx
│ │ │ │ │ │ └── utils
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── calendar-input
│ │ │ │ │ │ ├── CalendarInput.styles.ts
│ │ │ │ │ │ ├── CalendarInput.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── discipline-related-fields
│ │ │ │ │ │ └── DisciplineRelatedFields.tsx
│ │ │ │ │ ├── schedule-dropdown
│ │ │ │ │ │ ├── ScheduleDropdown.styles.ts
│ │ │ │ │ │ ├── ScheduleDropdown.tsx
│ │ │ │ │ │ └── TimeScheduleDropdown.tsx
│ │ │ │ │ ├── schedule-input
│ │ │ │ │ │ ├── ScheduleInput.styles.ts
│ │ │ │ │ │ ├── ScheduleInput.tsx
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── text-area
│ │ │ │ │ │ ├── TextArea.styles.ts
│ │ │ │ │ │ ├── TextArea.tsx
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── types
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── constants
│ │ │ │ │ └── index.ts
│ │ │ │ ├── icons
│ │ │ │ │ ├── Add.tsx
│ │ │ │ │ ├── Date.tsx
│ │ │ │ │ ├── Delete.tsx
│ │ │ │ │ ├── DeleteAll.tsx
│ │ │ │ │ ├── End.tsx
│ │ │ │ │ ├── Link.tsx
│ │ │ │ │ ├── Repeat.tsx
│ │ │ │ │ └── Start.tsx
│ │ │ │ ├── index.ts
│ │ │ │ ├── utils
│ │ │ │ │ ├── getDateWithTimeSet.ts
│ │ │ │ │ └── getOptionsFromDate.ts
│ │ │ │ └── validation
│ │ │ │ │ └── index.ts
│ │ │ ├── schedule-info-card
│ │ │ │ ├── ScheduleInfoCard.styles.tsx
│ │ │ │ ├── ScheduleInfoCard.tsx
│ │ │ │ ├── components
│ │ │ │ │ └── TextWithLinks.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ │ ├── prepareData.ts
│ │ │ │ ├── skeletonProps.ts
│ │ │ │ └── transformDetailedEvent.ts
│ │ ├── schedule-section
│ │ │ ├── ScheduleSection.styles.ts
│ │ │ ├── ScheduleSection.tsx
│ │ │ ├── ScheduleSectionMobile.tsx
│ │ │ └── components
│ │ │ │ ├── schedule-header
│ │ │ │ ├── ScheduleHeader.styles.ts
│ │ │ │ ├── ScheduleHeader.tsx
│ │ │ │ └── index.ts
│ │ │ │ └── schedule
│ │ │ │ ├── Schedule.styles.ts
│ │ │ │ ├── Schedule.tsx
│ │ │ │ ├── components
│ │ │ │ ├── schedule-column
│ │ │ │ │ ├── ScheduleColumn.styles.ts
│ │ │ │ │ ├── ScheduleColumn.tsx
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── schedule-card
│ │ │ │ │ │ │ ├── ScheduleCard.styles.ts
│ │ │ │ │ │ │ ├── ScheduleCard.tsx
│ │ │ │ │ │ │ ├── cards
│ │ │ │ │ │ │ ├── Cards.styles.ts
│ │ │ │ │ │ │ ├── ScheduleEvent.tsx
│ │ │ │ │ │ │ └── ScheduleEvents.tsx
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ └── schedule-events-section
│ │ │ │ │ │ │ │ ├── ScheduleEventsSection.styles.ts
│ │ │ │ │ │ │ │ └── ScheduleEventsSection.tsx
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── types
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ │ └── utils
│ │ │ │ │ │ │ ├── calculateHeight.ts
│ │ │ │ │ │ │ ├── calculateScheduleLineTop.ts
│ │ │ │ │ │ │ └── calculateTop.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── schedule-line
│ │ │ │ │ ├── ScheduleLine.styles.ts
│ │ │ │ │ ├── ScheduleLine.tsx
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── schedule-time
│ │ │ │ │ ├── ScheduleTime.styles.ts
│ │ │ │ │ ├── ScheduleTime.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ └── index.ts
│ │ └── utils
│ │ │ ├── areDatesInSameWeek.ts
│ │ │ ├── areValuesUnique.ts
│ │ │ ├── getCurrentWeek.ts
│ │ │ ├── getStringTime.ts
│ │ │ └── undefineNegativeValues.ts
│ │ └── search-pages
│ │ ├── poll-teachers-page
│ │ ├── PollTeacherPage.styles.ts
│ │ ├── PollTeacherPage.tsx
│ │ ├── components
│ │ │ ├── PollTeacherSearchList.module.scss
│ │ │ ├── PollTeacherSearchList.styles.ts
│ │ │ └── PollTeacherSearchList.tsx
│ │ └── index.ts
│ │ ├── search-form
│ │ ├── SearchForm.module.scss
│ │ ├── SearchForm.styles.ts
│ │ ├── SearchForm.tsx
│ │ ├── constants.ts
│ │ ├── index.ts
│ │ └── types
│ │ │ └── index.ts
│ │ ├── subject-search
│ │ ├── SubjectSearchPage.styles.ts
│ │ ├── SubjectSearchPage.tsx
│ │ ├── components
│ │ │ ├── SubjectSearchList.styles.ts
│ │ │ ├── SubjectSearchList.tsx
│ │ │ └── constants
│ │ │ │ └── breakpoints.tsx
│ │ ├── constants
│ │ │ └── index.ts
│ │ └── index.ts
│ │ ├── subject-teacher-search
│ │ ├── SearchTeacherPage.styles.ts
│ │ ├── SearchTeacherPage.tsx
│ │ ├── components
│ │ │ ├── SubjectTeacherSearchList.styles.ts
│ │ │ └── SubjectTeacherSearchList.tsx
│ │ └── index.ts
│ │ └── teacher-search
│ │ ├── TeacherSearchPage.styles.ts
│ │ ├── TeacherSearchPage.tsx
│ │ ├── components
│ │ ├── TeacherSearchList.styles.ts
│ │ └── TeacherSearchList.tsx
│ │ ├── constants
│ │ └── index.ts
│ │ └── index.ts
├── config
│ └── index.ts
├── hooks
│ ├── use-authentication
│ │ ├── authentication-context
│ │ │ ├── AuthenticationContext.tsx
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── types
│ │ │ └── index.ts
│ │ └── useAuthentication.tsx
│ ├── use-outside-click
│ │ ├── UseOutsideClick.tsx
│ │ └── index.ts
│ ├── use-tab-close
│ │ ├── index.ts
│ │ └── useTabClose.tsx
│ ├── use-tab-state
│ │ ├── UseTabState.ts
│ │ └── index.ts
│ ├── use-toast-error
│ │ └── useToastError.tsx
│ └── use-toast
│ │ ├── index.ts
│ │ ├── toast-context
│ │ ├── ToastContext.tsx
│ │ └── index.ts
│ │ ├── types
│ │ └── index.ts
│ │ └── useToast.tsx
├── lib
│ ├── api
│ │ ├── auth
│ │ │ ├── AuthAPI.ts
│ │ │ └── types
│ │ │ │ ├── AuthBody.ts
│ │ │ │ ├── ChangePasswordBody.ts
│ │ │ │ ├── CheckRegisterTelegramResponse.ts
│ │ │ │ ├── ForgotPasswordBody.ts
│ │ │ │ ├── RefreshAccesTokenResponse.ts
│ │ │ │ ├── RegisterBody.ts
│ │ │ │ ├── ResetPasswordBody.ts
│ │ │ │ ├── ResetPasswordResponse.ts
│ │ │ │ └── VerifyEmailBody.ts
│ │ ├── contract
│ │ │ ├── ContractAPI.ts
│ │ │ └── types
│ │ │ │ ├── AdminContractBody.ts
│ │ │ │ ├── ContractBody.ts
│ │ │ │ ├── DeleteEntrantBody.ts
│ │ │ │ ├── DeleteEntrantDataBody.ts
│ │ │ │ ├── EntrantFullResponse.ts
│ │ │ │ └── PriorityDataBody.ts
│ │ ├── dates
│ │ │ ├── DatesAPI.ts
│ │ │ └── types
│ │ │ │ ├── GetCurrentSemester.ts
│ │ │ │ └── GetDates.ts
│ │ ├── group
│ │ │ ├── GroupAPI.ts
│ │ │ └── types
│ │ │ │ ├── AddStudentsByMailBody.ts
│ │ │ │ ├── AddStudentsByMailResponse.ts
│ │ │ │ ├── GetAllResponse.ts
│ │ │ │ ├── GetGroupDisciplines.ts
│ │ │ │ ├── GetGroupStudentsResponse.ts
│ │ │ │ ├── GetGroupTeachers.ts
│ │ │ │ ├── GetPendingStudentsResponse.ts
│ │ │ │ ├── UpdateStudentRoleBody.ts
│ │ │ │ └── VerifyStudentBody.ts
│ │ ├── instance.ts
│ │ ├── poll
│ │ │ ├── PollAPI.ts
│ │ │ └── types
│ │ │ │ ├── CreateTeacherGradeBody.ts
│ │ │ │ ├── GetTeacherQuestionsResponse.ts
│ │ │ │ └── PollTeachersResponse.ts
│ │ ├── schedule
│ │ │ ├── ScheduleAPI.ts
│ │ │ ├── types
│ │ │ │ ├── DetailedEventBody.ts
│ │ │ │ ├── GetEventBody.ts
│ │ │ │ ├── PatchEventBody.ts
│ │ │ │ ├── PostEventBody.ts
│ │ │ │ ├── getDisciplinesAndTeachers.ts
│ │ │ │ └── shared.ts
│ │ │ └── utils
│ │ │ │ └── transformEvents.ts
│ │ ├── student-resources
│ │ │ ├── StudentResourcesAPI.ts
│ │ │ └── types
│ │ │ │ └── GetStudentResourcesResponse.ts
│ │ ├── subject
│ │ │ ├── SubjectAPI.ts
│ │ │ └── types
│ │ │ │ ├── GetListOfSubjectsResponse.ts
│ │ │ │ └── GetTeachersBySubjectResponse.ts
│ │ ├── teacher
│ │ │ ├── TeacherAPI.ts
│ │ │ └── types
│ │ │ │ ├── GetTeacherCommentsResponse.ts
│ │ │ │ ├── GetTeacherDisciplinesResponse.ts
│ │ │ │ ├── GetTeacherMarksResponse.ts
│ │ │ │ ├── GetTeacherSubjectsResponse.ts
│ │ │ │ └── GetTeachersResponse.ts
│ │ ├── user
│ │ │ ├── UserAPI.ts
│ │ │ └── types
│ │ │ │ ├── AddContactBody.ts
│ │ │ │ ├── ChangeAvatarResponse.ts
│ │ │ │ ├── ChangeInfoBody.ts
│ │ │ │ ├── ChangeRoleBody.ts
│ │ │ │ ├── GetContactsResponse.ts
│ │ │ │ ├── GetSelectiveDisciplinesBySemesterResponse.ts
│ │ │ │ ├── GetSelectiveDisciplinesResponse.ts
│ │ │ │ ├── GetSelectiveResponse.ts
│ │ │ │ ├── PostSelectiveDisciplinesBody.ts
│ │ │ │ ├── PostSuperheroBody.ts
│ │ │ │ ├── RequestNewGroupBody.ts
│ │ │ │ ├── VerifyStudentBody.ts
│ │ │ │ └── VerifySuperheroBody.ts
│ │ └── utils.ts
│ ├── services
│ │ ├── auth
│ │ │ ├── AuthService.ts
│ │ │ └── index.ts
│ │ ├── permisson
│ │ │ ├── PermissionService.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ ├── teacher
│ │ │ ├── TeacherService.ts
│ │ │ ├── index.ts
│ │ │ └── types
│ │ │ │ └── index.ts
│ │ └── telegram
│ │ │ ├── TelegramService.ts
│ │ │ └── index.ts
│ └── utils
│ │ ├── MergeSxStylesUtil.ts
│ │ ├── StorageUtil.ts
│ │ └── getErrorMessage.ts
├── pages
│ ├── 404.tsx
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── about.tsx
│ ├── account.tsx
│ ├── admin
│ │ ├── departments
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [departmentId].tsx
│ │ │ └── index.tsx
│ │ ├── disciplines
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [disciplineId].tsx
│ │ │ └── index.tsx
│ │ ├── groups
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [groupId].tsx
│ │ │ └── index.tsx
│ │ ├── index.tsx
│ │ ├── rights
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [rightId].tsx
│ │ │ └── index.tsx
│ │ ├── roles
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [roleId].tsx
│ │ │ └── index.tsx
│ │ ├── students
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [studentId].tsx
│ │ │ └── index.tsx
│ │ ├── subjects
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [subjectId].tsx
│ │ │ └── index.tsx
│ │ ├── teachers
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ │ └── [teacherId].tsx
│ │ │ └── index.tsx
│ │ └── users
│ │ │ ├── create.tsx
│ │ │ ├── edit
│ │ │ └── [userId].tsx
│ │ │ └── index.tsx
│ ├── contract-admin.tsx
│ ├── contract
│ │ └── index.tsx
│ ├── discipline.tsx
│ ├── entrant-admin.tsx
│ ├── entrant-dashboard.tsx
│ ├── index.tsx
│ ├── login.tsx
│ ├── password-recovery
│ │ ├── [token].tsx
│ │ ├── email-verification.tsx
│ │ ├── index.tsx
│ │ ├── invalid.tsx
│ │ └── valid.tsx
│ ├── poll
│ │ ├── [disciplineTeacherId].tsx
│ │ └── index.tsx
│ ├── priority-approve.tsx
│ ├── privacy.tsx
│ ├── register
│ │ ├── email-verification
│ │ │ ├── [token].tsx
│ │ │ └── index.tsx
│ │ └── index.tsx
│ ├── schedule
│ │ └── index.tsx
│ ├── subjects
│ │ ├── [subjectId]
│ │ │ └── teachers.tsx
│ │ └── index.tsx
│ └── teachers
│ │ ├── [teacherId].tsx
│ │ └── index.tsx
├── store
│ ├── poll-page
│ │ └── usePollStore.ts
│ └── schedule
│ │ ├── useSchedule.ts
│ │ └── utils
│ │ ├── findFirstOf5.ts
│ │ ├── getCurrentWeek.ts
│ │ ├── getFirstDayOfAWeek.ts
│ │ ├── getWeekByDate.ts
│ │ └── setUrlParams.ts
├── styles
│ ├── global-styles.scss
│ ├── partials
│ │ ├── _breakpoints.scss
│ │ ├── _theme.scss
│ │ ├── _typography-mixins.scss
│ │ └── _utils.scss
│ ├── reset.scss
│ ├── theme
│ │ ├── constants
│ │ │ ├── breakpoints
│ │ │ │ ├── breakpoints.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── interfaces.ts
│ │ │ ├── pallete
│ │ │ │ ├── index.ts
│ │ │ │ ├── interfaces.ts
│ │ │ │ └── palette.ts
│ │ │ └── typography
│ │ │ │ ├── index.ts
│ │ │ │ ├── interfaces.ts
│ │ │ │ └── typography.ts
│ │ ├── index.ts
│ │ └── theme.ts
│ └── typography.scss
└── types
│ ├── api.ts
│ ├── contact.ts
│ ├── contract.ts
│ ├── dates.ts
│ ├── discipline.ts
│ ├── group.ts
│ ├── poll.ts
│ ├── schedule.ts
│ ├── storage.ts
│ ├── student.ts
│ ├── subject.ts
│ ├── teacher.ts
│ ├── telegram.ts
│ ├── tokens.ts
│ ├── user.ts
│ └── utils
│ └── PartialBy.ts
└── tsconfig.json
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | [
4 | "babel-plugin-import",
5 | {
6 | "libraryName": "@mui/material",
7 | "libraryDirectory": "",
8 | "camel2DashComponentName": false
9 | },
10 | "core"
11 | ],
12 | [
13 | "babel-plugin-import",
14 | {
15 | "libraryName": "@mui/icons-material",
16 | "libraryDirectory": "",
17 | "camel2DashComponentName": false
18 | },
19 | "icons"
20 | ]
21 | ],
22 | "presets": [
23 | "next/babel"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /.next
3 | /node_modules
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 |
13 | # OS
14 | .DS_Store
15 |
16 | # Tests
17 | /coverage
18 | /.nyc_output
19 |
20 | # IDEs and editors
21 | /.idea
22 | .project
23 | .classpath
24 | .c9/
25 | *.launch
26 | .settings/
27 | *.sublime-workspace
28 |
29 | # IDE - VSCode
30 | .vscode/*
31 | !.vscode/settings.json
32 | !.vscode/tasks.json
33 | !.vscode/launch.json
34 | !.vscode/extensions.json
--------------------------------------------------------------------------------
/.env.development:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_API_BASE_URL=https://apidev.fictadvisor.com/v2
2 | API_BASE_URL=https://apidev.fictadvisor.com/v2
3 |
4 | BOT_ID=5916509477
5 | BOT_NAME=fictadvisordevbot
6 |
7 | NEXT_PUBLIC_BOT_ID=5916509477
8 | NEXT_PUBLIC_BOT_NAME=fictadvisordevbot
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_API_BASE_URL=
2 | API_BASE_URL=
3 |
4 | BOT_ID=
5 | BOT_NAME=
6 |
7 | NEXT_PUBLIC_BOT_ID=
8 | NEXT_PUBLIC_BOT_NAME=
--------------------------------------------------------------------------------
/.env.production:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_API_BASE_URL=https://apidev.fictadvisor.com/v2
2 | API_BASE_URL=https://apidev.fictadvisor.com/v2
3 |
4 | NEXT_PUBLIC_BOT_ID=1699479241
5 | NEXT_PUBLIC_BOT_NAME=fictadvisor_bot
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .husky
3 | .github
4 | .next
5 |
6 | # generated css files
7 | *.css
8 | *.css.map
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG] "
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Preconditions:**
11 |
12 | **Steps to reproduce**
13 | 1. Go to '...'
14 | 2. Click on '....'
15 | 3. Scroll down to '....'
16 | 4. Pay attention
17 |
18 | **Actual result:**
19 |
20 | **Expected result:**
21 |
22 | **Environment:**
23 | -deploy:
24 | -url:
25 | -OS:
26 | -browser: Google Chrome 116.0.5845.141/...
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancement.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Enhancement
3 | about: Improvement or refactoring
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the enhancement request here.
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature
3 | about: New feature on the front-end site
4 | title: ''
5 | labels: feature
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | bracketSpacing: true,
3 | singleQuote: true,
4 | trailingComma: 'all',
5 | arrowParens: 'avoid',
6 | semi: true,
7 | }
--------------------------------------------------------------------------------
/.storybook/main.ts:
--------------------------------------------------------------------------------
1 | import type { StorybookConfig } from '@storybook/nextjs';
2 |
3 | const config: StorybookConfig = {
4 | stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
5 | addons: [
6 | '@storybook/addon-links',
7 | '@storybook/addon-essentials',
8 | '@storybook/addon-onboarding',
9 | '@storybook/addon-interactions',
10 | ],
11 | staticDirs:[{from:'../public/icons', to: '/icons' }],
12 | framework: {
13 | name: '@storybook/nextjs',
14 | options: {},
15 | },
16 | docs: {
17 | autodocs: 'tag',
18 | },
19 | };
20 | export default config;
21 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
4 |
5 | 1. Fork the project
6 | 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
7 | 3. Commit your changes (`git commit -m 'Added an amazing feature'`)
8 | 4. Push the branch (`git push -u origin feature/amazing-feature`)
9 | 5. Open a pull request
10 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | output: 'standalone',
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: 'https',
7 | hostname: '**',
8 | },
9 | ],
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/favicon.ico
--------------------------------------------------------------------------------
/public/gifs/frog-complete.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/gifs/frog-complete.gif
--------------------------------------------------------------------------------
/public/gifs/frogging.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/gifs/frogging.gif
--------------------------------------------------------------------------------
/public/gifs/grey-frog.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/gifs/grey-frog.gif
--------------------------------------------------------------------------------
/public/icons/check-mark.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/public/icons/schedule-line.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/schedule-page/grid-pattern.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/about-page/basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/basic.png
--------------------------------------------------------------------------------
/public/images/about-page/dayF-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/dayF-mobile.png
--------------------------------------------------------------------------------
/public/images/about-page/dayF.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/dayF.png
--------------------------------------------------------------------------------
/public/images/about-page/events-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/events-mobile.png
--------------------------------------------------------------------------------
/public/images/about-page/events.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/events.png
--------------------------------------------------------------------------------
/public/images/about-page/military-cerf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/military-cerf.png
--------------------------------------------------------------------------------
/public/images/about-page/vitrazh-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/vitrazh-mobile.png
--------------------------------------------------------------------------------
/public/images/about-page/vitrazh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/vitrazh.png
--------------------------------------------------------------------------------
/public/images/about-page/wallFICE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/about-page/wallFICE.png
--------------------------------------------------------------------------------
/public/images/frog-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/frog-avatar.png
--------------------------------------------------------------------------------
/public/images/lecturer-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/lecturer-avatar.png
--------------------------------------------------------------------------------
/public/images/login-page/login-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/login-page/login-background.png
--------------------------------------------------------------------------------
/public/images/login-page/new-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/login-page/new-logo.png
--------------------------------------------------------------------------------
/public/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/logo.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/artem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/artem.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/danya.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/danya.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/dima.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/dima.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/illia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/illia.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/katya.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/katya.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/oleg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/oleg.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/pasha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/pasha.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/sasha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/sasha.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/stas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/stas.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/svyat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/svyat.png
--------------------------------------------------------------------------------
/public/images/main-page/avatars/vovka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/avatars/vovka.png
--------------------------------------------------------------------------------
/public/images/main-page/main-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/main-page/main-background.png
--------------------------------------------------------------------------------
/public/images/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/preview.jpg
--------------------------------------------------------------------------------
/public/images/register-page/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fictadvisor/fictadvisor-web/ae08498e44b1513b4c1aa15aa33109b5d7bd26b2/public/images/register-page/background.png
--------------------------------------------------------------------------------
/src/components/common/icons/CustomCheck.tsx:
--------------------------------------------------------------------------------
1 | export const CustomCheck = () => (
2 |
17 | );
18 |
--------------------------------------------------------------------------------
/src/components/common/layout/admin-panel-layout/AdminPanelLayout.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const layoutWrapper: SxProps = {
4 | width: '100%',
5 | };
6 |
7 | export const mainContent: SxProps = {
8 | marginLeft: '240px',
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/common/layout/admin-panel-layout/AdminPanelLayout.tsx:
--------------------------------------------------------------------------------
1 | import React, { ReactNode } from 'react';
2 | import { Box } from '@mui/material';
3 |
4 | import AdminPanel from '@/components/common/layout/admin-panel/AdminPanel';
5 |
6 | import * as styles from './AdminPanelLayout.styles';
7 |
8 | interface AdminPanelLayoutProps {
9 | children?: ReactNode;
10 | }
11 |
12 | const AdminPanelLayout: React.FC = ({
13 | children,
14 | }: AdminPanelLayoutProps) => {
15 | return (
16 |
17 |
18 | {children}
19 |
20 | );
21 | };
22 |
23 | export default AdminPanelLayout;
24 |
--------------------------------------------------------------------------------
/src/components/common/layout/footer/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Footer';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/components/authentication-buttons/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AuthenticationButtons';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/components/desktop-header/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './DesktopHeader';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/components/header-desktop-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './HeaderDesktopCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/components/header-mobile-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './HeaderMobileCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/components/mobile-header/components/drawer/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Drawer';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/components/mobile-header/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './MobileHeader';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Header';
2 |
--------------------------------------------------------------------------------
/src/components/common/layout/header/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface TransformedUser {
2 | name: string;
3 | groupName: string | null;
4 | position: string | null;
5 | avatar?: string;
6 | }
7 |
8 | export type HeaderCardProps = TransformedUser;
9 |
--------------------------------------------------------------------------------
/src/components/common/layout/page-layout/PageLayout.module.scss:
--------------------------------------------------------------------------------
1 | @import "src/styles/partials/theme";
2 |
3 | .page {
4 | width: 100%;
5 | display: flex;
6 | flex-direction: column;
7 | align-items: center;
8 | justify-content: center;
9 | min-height: 100vh;
10 | background-color: $background-dark-0;
11 | }
12 |
13 | .header {
14 | width: 100%;
15 | position: fixed;
16 | top: 0;
17 | z-index: 10;
18 | }
19 |
20 | .nav {
21 | height: 64px;
22 | }
23 |
24 | .footer {
25 | width: 100%;
26 | margin-top: auto;
27 | z-index: 2;
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/src/components/common/layout/page-layout/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PageLayout';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/alert-button/AlertButton.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import AlertButton from '@/components/common/ui/alert-button/AlertButton';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/AlertButton',
7 | component: AlertButton,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | text: 'Alert Button Test',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/alert-button/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AlertButton';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/alert-button/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum AlertButtonVariant {
2 | ERROR_FILL = 'error_fill',
3 | ERROR_OUTLINE = 'error_outline',
4 | SUCCESS = 'success',
5 | }
6 |
7 | export enum AlertButtonState {
8 | DEFAULT = 'default',
9 | HOVER = 'hover',
10 | ACTIVE = 'active',
11 | FOCUS = 'focus',
12 | DISABLED = 'disabled',
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/common/ui/alert/Alert.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Alert from '@/components/common/ui/alert/Alert';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Alert',
7 | component: Alert,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | title: 'Alert Test',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/alert/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Alert';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/alert/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum AlertType {
2 | INFO = 'info',
3 | WARNING = 'warning',
4 | ERROR = 'error',
5 | SUCCESS = 'success',
6 | }
7 |
8 | export enum AlertVariant {
9 | FILLED = 'filled',
10 | DARKER = 'darker',
11 | OUTLINED = 'outlined',
12 | BORDER_LEFT = 'border-left',
13 | BORDER_TOP = 'border-top',
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/common/ui/breadcrumbs/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Breadcrumbs';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/breadcrumbs/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface Breadcrumb {
2 | label: string;
3 | href: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/button-mui/Button.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Button from '@/components/common/ui/button-mui/Button';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Button',
7 | component: Button,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | text: 'Button Test',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/button-mui/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Button';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/button/Button.module.scss:
--------------------------------------------------------------------------------
1 | @import "styles/primary";
2 | @import "styles/secondary";
3 | @import "styles/button-style";
4 |
--------------------------------------------------------------------------------
/src/components/common/ui/button/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Button';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/card-roles/CardRoles.module.scss:
--------------------------------------------------------------------------------
1 | @import 'src/styles/partials/utils';
2 |
3 | .card-roles {
4 | @include flex-center;
5 | flex-wrap: nowrap;
6 | overflow: hidden;
7 | gap: 4px;
8 | justify-content: flex-start;
9 | }
--------------------------------------------------------------------------------
/src/components/common/ui/cards/card-roles/index.ts:
--------------------------------------------------------------------------------
1 | export { CardRoles } from './CardRoles';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/floating-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FloatingCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/personal-teacher-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PersonalTeacherCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/poll-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PollCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/poll-teacher-card/index.ts:
--------------------------------------------------------------------------------
1 | export { PollTeacherCard } from './PollTeacherCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/poll-teacher-card/pollTeachaerCard.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const buttonIcon: SxProps = {
4 | position: 'absolute',
5 | right: '8px',
6 | top: '6px',
7 | zIndex: 1,
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/subject-card/index.ts:
--------------------------------------------------------------------------------
1 | export { SubjectCard } from './SubjectCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/teacher-card/index.ts:
--------------------------------------------------------------------------------
1 | export { TeacherCard } from './TeacherCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/teacher-header-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TeacherHeaderCard';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/cards/types/index.ts:
--------------------------------------------------------------------------------
1 | export type DivProps = React.DetailedHTMLProps<
2 | React.HTMLAttributes,
3 | HTMLDivElement
4 | >;
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/circle-diagram/CircleDiagram.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import CircleDiagram from '@/components/common/ui/circle-diagram/CircleDiagram';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/CircleDiagram',
7 | component: CircleDiagram,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | value: 80,
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/circle-diagram/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CircleDiagram';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/circle-diagram/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum CircleDiagramVariant {
2 | DETERMINATE = 'determinate',
3 | INDETERMINATE = 'indeterminate',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/column-chart/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ColumnChart';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/column-chart/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface TeacherEvaluations {
2 | name: string;
3 | amount: number;
4 | type: string;
5 | mark: Record;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/common/ui/comment/Comment.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const wrapper: SxProps = {
4 | wordWrap: 'break-word',
5 | height: '100%',
6 | padding: '11px 16px 12px 16px',
7 | backgroundColor: 'backgroundDark.200',
8 | borderRadius: '4px',
9 | };
10 |
11 | export const text: SxProps = {
12 | marginBottom: '2px',
13 | textAlign: 'justify',
14 | typography: 'body1',
15 | whiteSpace: 'pre-wrap',
16 | };
17 |
18 | export const date: SxProps = {
19 | height: '17px',
20 | width: '100%',
21 | typography: 'body1',
22 | textAlign: 'right',
23 | color: 'grey.400',
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/common/ui/comment/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Comment';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/custom-link/CustomLink.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import CustomLink from '@/components/common/ui/custom-link/CustomLink';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/CustomLink',
7 | component: CustomLink,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | href: '#',
20 | text: 'Lorem Ipsum is simply',
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/common/ui/custom-link/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CustomLink';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/custom-link/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum CustomLinkType {
2 | WHITE = 'white',
3 | BLUE = 'blue',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/divider/Divider.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Divider from '@/components/common/ui/divider/Divider';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Divider',
7 | component: Divider,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | text: 'Divider',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/divider/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Divider';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/divider/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum DividerTextAlign {
2 | RIGHT = 'right',
3 | LEFT = 'left',
4 | CENTER = 'center',
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/checkbox/Checkbox.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Checkbox from '@/components/common/ui/form/checkbox/Checkbox';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Form/Checkbox',
7 | component: Checkbox,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | label: 'Checkbox test',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/checkbox/Checkbox.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const wrapper: SxProps = {
4 | margin: 0,
5 | alignItems: 'center',
6 | };
7 |
8 | export const checkBox: SxProps = {
9 | padding: '2px',
10 | };
11 |
12 | export const label = (disabled: boolean, label?: string): SxProps => ({
13 | color: disabled ? 'grey.400' : 'grey.800',
14 | marginLeft: label && '8px',
15 | minWidth: '75px',
16 | });
17 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/checkbox/components/Icon.tsx:
--------------------------------------------------------------------------------
1 | import { styled } from '@mui/material/styles';
2 |
3 | import { ControlsColorMap } from '../constants';
4 | import { CheckboxColor } from '../types';
5 |
6 | interface IconProps {
7 | color: CheckboxColor;
8 | disabled?: boolean;
9 | }
10 |
11 | export const Icon = styled('span')(({ theme, color, disabled }) => ({
12 | borderRadius: '2px',
13 | width: '18px',
14 | height: '18px',
15 | transition: 'all 0.8s ease-in-out',
16 | boxShadow: `0px 0px 0px 2px ${
17 | disabled ? theme.palette.grey[300] : ControlsColorMap[color]
18 | }`,
19 | }));
20 |
21 | export default Icon;
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/checkbox/constants/index.ts:
--------------------------------------------------------------------------------
1 | import theme from '@/styles/theme';
2 |
3 | import { CheckboxColor } from '../types';
4 |
5 | export const ControlsColorMap: Record = {
6 | [CheckboxColor.PRIMARY]: theme.palette.grey[800],
7 | [CheckboxColor.ERROR]: theme.palette.error[500],
8 | [CheckboxColor.LECTURE]: theme.palette.indigo[700],
9 | [CheckboxColor.PRACTICE]: theme.palette.orange[600],
10 | [CheckboxColor.LAB]: theme.palette.mint[600],
11 | [CheckboxColor.EVENT]: theme.palette.violet[700],
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Checkbox';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/checkbox/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum CheckboxColor {
2 | PRIMARY = 'primary',
3 | ERROR = 'error',
4 | LECTURE = 'lecture',
5 | PRACTICE = 'practice',
6 | LAB = 'lab',
7 | EVENT = 'event',
8 | }
9 |
10 | export enum CheckboxTextType {
11 | BODY1 = 'body1',
12 | BODY2MEDIUM = 'body2Medium',
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/common/types.ts:
--------------------------------------------------------------------------------
1 | export enum FieldState {
2 | DEFAULT = 'default',
3 | DISABLED = 'disabled',
4 | ERROR = 'error',
5 | SUCCESS = 'success',
6 | }
7 |
8 | export enum FieldSize {
9 | SMALL = 'small',
10 | MEDIUM = 'medium',
11 | LARGE = 'large',
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/dropdown/components/option/Option.tsx:
--------------------------------------------------------------------------------
1 | import { FC, HTMLProps } from 'react';
2 |
3 | import { DropDownOption } from '../../types';
4 |
5 | interface OptionProps extends HTMLProps {
6 | option: DropDownOption;
7 | }
8 |
9 | import Tag from '@/components/common/ui/tag';
10 |
11 | const Option: FC = ({ option, ...props }) => {
12 | if ('text' in option) {
13 | return (
14 |
15 |
16 |
17 | );
18 | } else {
19 | return {option.label};
20 | }
21 | };
22 |
23 | export default Option;
24 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/dropdown/components/option/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Option';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/dropdown/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { PopperProps } from '@mui/base';
2 |
3 | export const popperProps: Partial = {
4 | placement: 'bottom-start',
5 | modifiers: [
6 | { name: 'flip', enabled: false },
7 | {
8 | name: 'preventOverflow',
9 | options: {
10 | mainAxis: false,
11 | },
12 | },
13 | {
14 | name: 'sameWidth',
15 | enabled: true,
16 | fn: ({ state }) => {
17 | state.styles.popper.width = `${state.rects.reference.width}px`;
18 | },
19 | phase: 'beforeWrite',
20 | requires: ['computeStyles'],
21 | },
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/dropdown/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Dropdown';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Checkbox } from './checkbox';
2 | export { default as Dropdown } from './dropdown';
3 | export { default as Input, InputSize, InputType } from './input';
4 | export { default as RadioGroup } from './radio/radio-button';
5 | export { default as Slider } from './slider';
6 | export { default as Switch } from './switch';
7 | export { default as TextArea } from './text-area-mui';
8 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/input-mui/Input.stories.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Meta, Story } from '@storybook/react';
3 |
4 | import Input from '@/components/common/ui/form/input-mui';
5 |
6 | const meta: Meta = {
7 | title: 'Ui Kit/Components/Form/Input',
8 | component: Input,
9 | parameters: {
10 | layout: 'centered',
11 | },
12 | tags: ['autodocs'],
13 | };
14 |
15 | export default meta;
16 |
17 | const InputTemplate: Story = args => {
18 | const [value, setValue] = useState('');
19 | return ;
20 | };
21 |
22 | export const Base = InputTemplate.bind({});
23 | Base.args = {};
24 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/input-mui/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const MAX_LENGTH = 2000;
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/input-mui/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Input';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/input/index.ts:
--------------------------------------------------------------------------------
1 | export { default, InputSize, InputType } from './Input';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/numbered-text-area/components/LineNumbers.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const lineNumbers: SxProps = {
4 | marginTop: '9px',
5 | textAlign: 'center',
6 | width: '30px',
7 | display: 'flex',
8 | flexDirection: 'column',
9 | typography: 'body1',
10 | lineHeight: '24px',
11 | overflow: 'hidden',
12 | color: 'inherit',
13 | height: {
14 | mobile: '168px',
15 | mobileMedium: '240px',
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/numbered-text-area/components/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LineNumbers';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/numbered-text-area/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './NumberedTextArea';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/numbered-text-area/types/index.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export interface NumberedTextAreaProps {
4 | value: string;
5 | placeholder?: string;
6 | disabled?: boolean;
7 | showRemark?: boolean;
8 | sx?: SxProps;
9 | touched?: boolean;
10 | error?: string;
11 | onChange?: (value: string) => void;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/numbered-text-area/utils/index.tsx:
--------------------------------------------------------------------------------
1 | export const transformValue = (value: string): string => {
2 | if (value.includes(',') || value.includes(';')) {
3 | value = value.replace(/,/g, '\n').replace(/;/g, '\n');
4 | }
5 | value = value.replace(/\s+/g, '\n').replace(/\n\n/g, '\n');
6 |
7 | return value;
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/radio/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './RadioGroup';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/radio/radio-button/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Radio';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/slider/const/marks.ts:
--------------------------------------------------------------------------------
1 | export const marks = Array.from({ length: 10 }, (_, index) => ({
2 | value: index + 1,
3 | label: (index + 1).toString(),
4 | }));
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/slider/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Slider';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/slider/types/index.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material';
2 |
3 | export enum SliderSize {
4 | MEDIUM = 'medium',
5 | SMALL = 'small',
6 | }
7 |
8 | export interface SliderProps {
9 | defaultValue?: number;
10 | size?: SliderSize;
11 | sx?: SxProps;
12 | onChange?: (event: Event, value: number | number[]) => void;
13 | value?: number;
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/switch/Switch.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Switch from '@/components/common/ui/form/switch';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Form/Switch',
7 | component: Switch,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 | type Story = StoryObj;
16 |
17 | export const Base: Story = {
18 | args: {
19 | label: 'Switch',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/switch/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Switch';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/switch/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum SwitchLabelPlacement {
2 | START = 'start',
3 | END = 'end',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/text-area-mui/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TextArea';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/text-area-mui/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum TextAreaSize {
2 | MEDIUM = 'medium',
3 | SMALL = 'small',
4 | }
5 |
6 | export enum TextAreaState {
7 | DEFAULT = 'default',
8 | ERROR = 'error',
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/with-formik/checkbox/FormikCheckbox.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import FormikCheckbox from '@/components/common/ui/form/checkbox/Checkbox';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Form/Formik/Checkbox',
7 | component: FormikCheckbox,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | label: 'FormikCheckbox test',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/with-formik/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FormikCheckbox';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/with-formik/dropdown/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FormikDropdown';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/with-formik/input/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FormikInput';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/with-formik/numbered-text-area/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FormikNumberedTextArea';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/form/with-formik/slider/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FormikSlider';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './IconButton';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/variants/ArrowButton/ArrowButton.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import ArrowButton from './ArrowButton';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/IconButton',
7 | component: ArrowButton,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Arrow: Story = {};
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/variants/CloseButton/CloseButton.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import CloseButton from './CloseButton';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/IconButton',
7 | component: CloseButton,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Close: Story = {};
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/variants/SortButton/SortButton.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import SortButton from './SortButton';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/IconButton',
7 | component: SortButton,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Sort: Story = {};
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/variants/StarButton/StarButton.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import StarButton from './StarButton';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/IconButton',
7 | component: StarButton,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Star: Story = {};
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/variants/TrashBucketButton/TrashBucketButton.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import TrashBucketButton from './TrashBucketButton';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/IconButton',
7 | component: TrashBucketButton,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const TrashBucket: Story = {};
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button-mui/variants/index.ts:
--------------------------------------------------------------------------------
1 | export { default as ArrowButton } from './ArrowButton/ArrowButton';
2 | export { default as CloseButton } from './CloseButton/CloseButton';
3 | export { default as SortButton } from './SortButton/SortButton';
4 | export { default as StarButton } from './StarButton/StarButton';
5 | export { default as TrashBucketButton } from './TrashBucketButton/TrashBucketButton';
6 |
--------------------------------------------------------------------------------
/src/components/common/ui/icon-button/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | IconButton,
3 | IconButtonColor,
4 | IconButtonShape,
5 | IconButtonSize,
6 | } from './IconButton';
7 |
--------------------------------------------------------------------------------
/src/components/common/ui/line-graph/LineGraph.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import LineGraph from '@/components/common/ui/line-graph/LineGraph';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/LineGraph',
7 | component: LineGraph,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | value: 77,
20 | label: 'Lorem Ipsum is simply',
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/common/ui/line-graph/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LineGraph';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/line-graph/utils/check-value.ts:
--------------------------------------------------------------------------------
1 | const checkValue = (value: number) => {
2 | if (value < 0) return 0;
3 | if (value > 100) return 100;
4 | return value;
5 | };
6 |
7 | export default checkValue;
8 |
--------------------------------------------------------------------------------
/src/components/common/ui/line-graph/utils/get-color.ts:
--------------------------------------------------------------------------------
1 | const ColorMap: Record = {
2 | good: 'green.700',
3 | average: 'amber.600',
4 | bad: 'warning.200',
5 | };
6 |
7 | const getColor = (value: number) => {
8 | if (value > 70) {
9 | return ColorMap.good;
10 | }
11 | if (value < 40) {
12 | return ColorMap.bad;
13 | }
14 | if (value <= 70) {
15 | return ColorMap.average;
16 | }
17 | };
18 |
19 | export default getColor;
20 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/Popup/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Popup';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupActions/PopupActions.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const popupActions: SxProps = {
4 | padding: 0,
5 | };
6 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupActions/PopupActions.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC } from 'react';
2 | import DialogActions from '@mui/material/DialogActions';
3 | import { SxProps, Theme } from '@mui/material/styles';
4 |
5 | import mergeSx from '@/lib/utils/MergeSxStylesUtil';
6 |
7 | import * as styles from './PopupActions.styles';
8 | interface PopupActionsProps {
9 | children?: React.ReactNode;
10 | sx?: SxProps;
11 | }
12 |
13 | const PopupActions: FC = ({ children, sx = {} }) => {
14 | return (
15 |
16 | {children}
17 |
18 | );
19 | };
20 |
21 | export default PopupActions;
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupActions/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PopupActions';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupContent/PopupContent.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | import typography from '@/styles/theme/constants/typography';
4 |
5 | export const popupContent: SxProps = {
6 | typography: typography.body1,
7 | padding: 0,
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupContent/PopupContent.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC } from 'react';
2 | import DialogContent from '@mui/material/DialogContent';
3 | import { SxProps, Theme } from '@mui/material/styles';
4 |
5 | import mergeSx from '@/lib/utils/MergeSxStylesUtil';
6 |
7 | import * as styles from './PopupContent.styles';
8 |
9 | interface PopupContentProps {
10 | children?: React.ReactNode;
11 | sx?: SxProps;
12 | }
13 |
14 | const PopupContent: FC = ({ children, sx = {} }) => {
15 | return (
16 |
17 | {children}
18 |
19 | );
20 | };
21 | export default PopupContent;
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupContent/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PopupContent';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupTitle/PopupTitle.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | import typography from '@/styles/theme/constants/typography';
4 |
5 | export const iconButton: SxProps = {
6 | position: 'absolute',
7 | right: 8,
8 | top: 8,
9 | color: 'grey.800',
10 | };
11 |
12 | export const dialogTitle: SxProps = {
13 | m: 0,
14 | padding: 0,
15 | '.MuiTypography-root': {
16 | typography: typography.h6Bold,
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/common/ui/pop-ups/PopupTitle/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PopupTitle';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/progress/Progress.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Progress from '@/components/common/ui/progress/Progress';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Progress',
7 | component: Progress,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {};
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/progress/Progress.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const progressFront: SxProps = {
4 | '.MuiCircularProgress-svg': {
5 | strokeLinecap: 'round',
6 | },
7 | color: 'primary.300',
8 | };
9 |
10 | export const progressBack: SxProps = {
11 | color: 'backgroundDark.200',
12 | position: 'absolute',
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/common/ui/progress/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Progress';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/progress/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum ProgressColor {
2 | PRIMARY = 'primary',
3 | SECONDARY = 'secondary',
4 | ERROR = 'error',
5 | INFO = 'info',
6 | SUCCESS = 'success',
7 | WARNING = 'warning',
8 | INHERIT = 'inherit',
9 | }
10 |
11 | export enum ProgressSize {
12 | SMALL = 58,
13 | SEMI_MEDIUM = 144,
14 | MEDIUM = 180,
15 | LARGE = 216,
16 | EXTRA_LARGE = 252,
17 | }
18 |
19 | export enum ProgressVariant {
20 | DETERMINATE = 'determinate',
21 | INDETERMINATE = 'indeterminate',
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/common/ui/radar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Radar';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/rating/Rating.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Rating from '@/components/common/ui/rating/Rating';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Rating',
7 | component: Rating,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | rating: 80,
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/rating/Rating.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | import { RatingVariant } from './types';
4 |
5 | export const rating = (variant: RatingVariant): SxProps => ({
6 | width: 'fit-content',
7 | display: 'flex',
8 | alignItems: 'center',
9 | justifyContent: 'center',
10 | ...(variant === RatingVariant.SHORT && { gap: '4px' }),
11 | ...(variant === RatingVariant.LONG && { gap: '8px' }),
12 | typography: 'body1Bold',
13 | });
14 |
15 | export const ratingStars: SxProps = {
16 | paddingBottom: '4px',
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/common/ui/rating/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Rating';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/rating/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum RatingVariant {
2 | LONG = 'long',
3 | SHORT = 'short',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/index.ts:
--------------------------------------------------------------------------------
1 | import Tab from './tab';
2 | import TabContext from './tab-context';
3 | import TabList from './tab-list';
4 | import TabPanel from './tab-panel';
5 |
6 | export { Tab, TabContext, TabList, TabPanel };
7 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-context/TabContext.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { TabContext as MuiTabContext, TabContextProps } from '@mui/lab';
3 |
4 | const TabContext: FC = props => {
5 | return ;
6 | };
7 |
8 | export default TabContext;
9 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-context/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TabContext';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-list/TabList.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { TabList as MuiTabList, TabListProps } from '@mui/lab';
3 |
4 | const TabList: FC = props => {
5 | return (
6 |
15 | );
16 | };
17 |
18 | export default TabList;
19 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-list/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TabList';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-panel/TabPanel.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const tabPanel: SxProps = {
4 | padding: '0',
5 | };
6 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-panel/TabPanel.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { TabPanel as MuiTabPanel, TabPanelProps } from '@mui/lab';
3 |
4 | import * as styles from './TabPanel.styles';
5 |
6 | const TabPanel: FC = props => {
7 | return ;
8 | };
9 | export default TabPanel;
10 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab-panel/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TabPanel';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab/Tab.stories.tsx:
--------------------------------------------------------------------------------
1 | import { AcademicCapIcon } from '@heroicons/react/24/outline';
2 | import type { Meta, StoryObj } from '@storybook/react';
3 |
4 | import Tab from '@/components/common/ui/tab/tab/Tab';
5 |
6 | const meta = {
7 | title: 'Ui Kit/Components/Tab',
8 | component: Tab,
9 | parameters: {
10 | layout: 'centered',
11 | },
12 | tags: ['autodocs'],
13 | } satisfies Meta;
14 |
15 | export default meta;
16 |
17 | type Story = StoryObj;
18 | export const Base: Story = {
19 | args: {
20 | label: 'Безпека',
21 | icon: ,
22 | },
23 | };
24 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab/components/CustomLabel.tsx:
--------------------------------------------------------------------------------
1 | import { FC, ReactNode } from 'react';
2 | import Box from '@mui/material/Box';
3 |
4 | import * as styles from '../Tab.styles';
5 |
6 | interface CustomLabelProps {
7 | label: string | ReactNode;
8 | count: number | null;
9 | disabled: boolean;
10 | }
11 |
12 | export const CustomLabel: FC = ({
13 | label,
14 | count,
15 | disabled,
16 | }) => {
17 | return (
18 |
19 | {label}
20 | {count !== null && {count}}
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Tab';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/tab/tab/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum TabTextPosition {
2 | CENTER = 'center',
3 | LEFT = 'left',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/common/ui/tag/Tag.stories.ts:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Tag from '@/components/common/ui/tag/Tag';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Tag',
7 | component: Tag,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 | export const Base: Story = {
18 | args: {
19 | text: 'Tag',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/common/ui/tag/Tag.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { Box } from '@mui/material';
3 |
4 | import mergeSx from '@/lib/utils/MergeSxStylesUtil';
5 |
6 | import * as styles from './Tag.styles';
7 | import { TagColor, TagProps, TagSize, TagVariant } from './types';
8 |
9 | const Tag: FC = ({
10 | text,
11 | variant = TagVariant.FILL,
12 | color = TagColor.PRIMARY,
13 | size = TagSize.MEDIUM,
14 | icon,
15 | sx = {},
16 | }) => {
17 | return (
18 |
19 | {icon && {icon}}
20 | {text}
21 |
22 | );
23 | };
24 |
25 | export default Tag;
26 |
--------------------------------------------------------------------------------
/src/components/common/ui/tag/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Tag';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/toast/Toast.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const toast = (open: boolean): SxProps => ({
4 | margin: {
5 | mobile: '15px',
6 | tablet: '50px',
7 | },
8 | ...(!open && {
9 | display: 'none',
10 | }),
11 | });
12 |
--------------------------------------------------------------------------------
/src/components/common/ui/toast/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Toast';
2 |
--------------------------------------------------------------------------------
/src/components/common/ui/tooltip/Tooltip.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import Tooltip from '@/components/common/ui/tooltip/Tooltip';
4 |
5 | const meta = {
6 | title: 'Ui Kit/Components/Tooltip',
7 | component: Tooltip,
8 | parameters: {
9 | layout: 'centered',
10 | },
11 | tags: ['autodocs'],
12 | } satisfies Meta;
13 |
14 | export default meta;
15 |
16 | type Story = StoryObj;
17 |
18 | export const Base: Story = {
19 | args: { title: 'Tooltip', children: TooltipChildren
},
20 | };
21 |
--------------------------------------------------------------------------------
/src/components/common/ui/tooltip/Tooltip.styles.tsx:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 |
3 | export const tooltip: SxProps = {
4 | backgroundColor: 'primary.A100',
5 | color: 'backgroundDark.50',
6 | padding: '4px 12px',
7 | textAlign: 'center',
8 | borderRadius: '4px',
9 | };
10 |
11 | export const arrow: SxProps = {
12 | color: 'primary.A100',
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/common/ui/tooltip/Tooltip.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC, ReactElement } from 'react';
2 | import { Tooltip as MuiTooltip, TooltipProps } from '@mui/material';
3 |
4 | import * as styles from './Tooltip.styles';
5 |
6 | interface StyledTooltipProps extends TooltipProps {
7 | children: ReactElement;
8 | }
9 |
10 | const Tooltip: FC = ({ children, ...rest }) => {
11 | return (
12 |
19 | {children}
20 |
21 | );
22 | };
23 |
24 | export default Tooltip;
25 |
--------------------------------------------------------------------------------
/src/components/common/ui/tooltip/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Tooltip';
2 |
--------------------------------------------------------------------------------
/src/components/pages/404-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './NotFoundPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/about-page/components/MobileStudActivityCard.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const wrapper: SxProps = {
4 | display: 'flex',
5 | flexDirection: 'column',
6 | alignItems: 'center',
7 | width: '320px',
8 | position: 'relative',
9 | };
10 | export const content = (imgSrc?: string): SxProps => ({
11 | display: 'flex',
12 | flexDirection: 'column',
13 | gap: '8px',
14 | borderRadius: '12px',
15 | background: '#151515',
16 | alignItems: 'flex-start',
17 | mt: imgSrc ? '45px' : '0',
18 | padding: imgSrc ? '70px 20px 20px 20px' : '16px',
19 | });
20 |
--------------------------------------------------------------------------------
/src/components/pages/about-page/components/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './MobileStudActivityCard';
2 |
--------------------------------------------------------------------------------
/src/components/pages/about-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AboutPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/about-page/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum EclipseSize {
2 | LARGE = 'LARGE',
3 | MEDIUM = 'MEDIUM',
4 | SMALL = 'SMALL',
5 | }
6 |
7 | export enum EclipseType {
8 | RED = 'RED',
9 | BLUE = 'BLUE',
10 | VIOLET = 'VIOLET',
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/change-avatar-window/components/avatar-dropzone/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AvatarDropzone';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/change-avatar-window/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ChangeAvatarWindow';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/contacts-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ContactsBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/contacts-block/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface Contact {
2 | id: string;
3 | link: string;
4 | name: string;
5 | displayName: string;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/contacts-block/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | import { ContactType } from '@/types/contact';
4 |
5 | export const validationSchema = yup.object().shape({
6 | displayName: yup.string().required(`Обов'язкове поле`),
7 | link: yup
8 | .string()
9 | .required(`Обов'язкове поле`)
10 | .url('Неправильний формат посилання'),
11 | name: yup.string().required(`Обов'язкове поле`),
12 | });
13 |
14 | export const initialValues = {
15 | name: ContactType.TELEGRAM,
16 | link: '',
17 | displayName: '',
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/personal-info/PersonalInfo.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const input: SxProps = {
4 | marginBottom: { mobile: '22px', desktopSemiMedium: '24px' },
5 | marginTop: '1.5%',
6 | };
7 |
8 | export const confirmButton: SxProps = {
9 | width: { mobile: 'fit-content', desktopSemiMedium: '50%' },
10 | margin: { mobile: '0 0 36px 0', desktopSemiMedium: '5px 0 36px 0' },
11 | display: { mobile: 'block', desktop: '' },
12 | };
13 |
14 | export const buttonPadding: SxProps = {
15 | padding: '6px 12px',
16 | };
17 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/personal-info/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PersonalInfo';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/personal-info/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface PersonalInfoForm {
2 | firstName: string;
3 | lastName: string;
4 | middleName?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/components/personal-info/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 | const commonValidation = yup
3 | .string()
4 | .min(2, 'Не коротше 2 символів')
5 | .max(40, 'Не довше 40 символів')
6 | .matches(
7 | /^[ҐЄІЇЬА-ЩЮЯґєіїьа-щюя\-`ʼ' ]+$/,
8 | 'Має містити українські літери, апостроф або дефіс',
9 | );
10 |
11 | export const validationSchema = yup.object().shape({
12 | firstName: commonValidation.required(`Обов'язкове поле`),
13 | lastName: commonValidation.required(`Обов'язкове поле`),
14 | middleName: commonValidation,
15 | });
16 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './GeneralTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/general-tab/utils/isValidFile.ts:
--------------------------------------------------------------------------------
1 | export const isValidFile = (file: File) => {
2 | if (file) {
3 | const allowedExtensions = ['.png', '.jpg', '.jpeg', '.webp'];
4 | const fileExtension = file.name
5 | .slice(file.name.lastIndexOf('.') + 1)
6 | .toLowerCase();
7 | return allowedExtensions.includes(`.${fileExtension}`);
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/GroupTab.styles.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material/styles';
2 | import { SxProps } from '@mui/system';
3 |
4 | export const progress: SxProps = {
5 | display: 'flex',
6 | justifyContent: 'center',
7 | alignItems: 'center',
8 | };
9 |
10 | export const group: SxProps = {
11 | pb: '20px',
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/no-group-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './NoGroupBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/no-group-block/utils/index.ts:
--------------------------------------------------------------------------------
1 | import { DropDownOption } from '@/components/common/ui/form/dropdown/types';
2 | import { Group } from '@/types/group';
3 |
4 | export const transformGroups = (groups: Group[]): DropDownOption[] =>
5 | groups.map(({ code, id }) => ({
6 | label: code,
7 | id,
8 | }));
9 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/no-group-block/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const validationSchema = yup.object().shape({
4 | groupId: yup.string().required(`Обов'язкове поле`),
5 | });
6 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/table/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { UserGroupRole } from '@/types/user';
2 |
3 | const roleNamesMapper: Record = {
4 | [UserGroupRole.CAPTAIN]: 'Староста',
5 | [UserGroupRole.MODERATOR]: 'Заст. старости',
6 | [UserGroupRole.STUDENT]: 'Студент',
7 | };
8 |
9 | export default roleNamesMapper;
10 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/table/requests-table/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './RequestsTable';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/table/student-table/StudentsTable.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const button: SxProps = {
5 | width: { mobile: 'min-content' },
6 | whiteSpace: 'nowrap',
7 | };
8 |
9 | export const dividerWrapper: SxProps = {
10 | display: 'flex',
11 | justifyContent: 'space-between',
12 | gap: '18px',
13 | alignItems: 'center',
14 | pb: '20px',
15 | typography: 'body1',
16 | };
17 |
18 | export const tag: SxProps = {
19 | padding: '1px 3px',
20 | };
21 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/table/student-table/components/MobileDropdown.style.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const dropdown: SxProps = {
5 | width: '165px',
6 | backgroundColor: 'backgroundDark.100',
7 | boxShadow: '3px 1px 3px hsla(0,0%,4%,.09), 2px 4px 16px hsla(0,0%,5%,.13);',
8 | borderRadius: '5px',
9 | '& svg': {
10 | height: '18px',
11 | width: '18px',
12 | },
13 | '& .MuiButtonBase-root': {
14 | justifyContent: 'flex-start',
15 | typography: 'body1',
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/table/student-table/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './StudentsTable';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/text-area-popup/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const initialValues = {
2 | textArea: '',
3 | };
4 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/text-area-popup/index.ts:
--------------------------------------------------------------------------------
1 | export { TextAreaPopup } from './TextAreaPopup';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/components/text-area-popup/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const validationSchema = yup.object().shape({
4 | textArea: yup.string().required('Немає кого додати!'),
5 | });
6 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/group-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './GroupTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/security-tab/components/change-password-form/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { ChangePasswordFormFields } from '../types';
2 |
3 | export const initialValues: ChangePasswordFormFields = {
4 | oldPassword: '',
5 | newPassword: '',
6 | confirmationPassword: '',
7 | };
8 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/security-tab/components/change-password-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ChangePasswordForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/security-tab/components/change-password-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface ChangePasswordFormFields {
2 | oldPassword: string;
3 | newPassword: string;
4 | confirmationPassword: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/security-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SecurityTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/selective-tab/components/opened-selective/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './OpenedSelective';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/selective-tab/components/selective-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SelectiveBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/selective-tab/components/selective-block/utils/index.ts:
--------------------------------------------------------------------------------
1 | export const fillArray = (
2 | arr: string[],
3 | newLength: number,
4 | fillString: string,
5 | ) => {
6 | const newArr = [...arr];
7 | while (newArr.length < newLength) {
8 | newArr.push(fillString);
9 | }
10 | return newArr;
11 | };
12 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/components/selective-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SelectiveTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AccountPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/account-page/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum AccountPageTab {
2 | GENERAL = 'GENERAL',
3 | SECURITY = 'SECURITY',
4 | GROUP = 'GROUP',
5 | SELECTIVE = 'SELECTIVE',
6 | }
7 |
8 | export enum AccountPagesMapper {
9 | GROUP = 'Група',
10 | SECURITY = 'Безпека',
11 | GENERAL = 'Загальне',
12 | SELECTIVE = 'Мої вибіркові',
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/pages/admin/admin-default/AdminMainPage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const wrapper: SxProps = {
5 | width: '100%',
6 | display: 'flex',
7 | flexDirection: 'column',
8 | justifyContent: 'center',
9 | alignItems: 'center',
10 | alignContent: 'center',
11 | marginTop: '126px',
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/pages/admin/admin-default/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AdminMainPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/contract-admin-page/utils/index.ts:
--------------------------------------------------------------------------------
1 | const errors = {
2 | InvalidBodyException: 'Дані вказані невірно',
3 | 'Not Found': 'Дані не знайдено',
4 | AlreadyExistException: 'Контракт вже існує',
5 | UnauthorizedException: 'Користувач не авторизований',
6 | NoPermissionException: 'У тебе немає дозволу на виконання цієї дії',
7 | };
8 |
9 | export const checkError = (requestError: string) => {
10 | for (const [exception, error] of Object.entries(errors)) {
11 | if (requestError === exception) {
12 | return error;
13 | }
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/pages/contract-page/ContractPage.module.scss:
--------------------------------------------------------------------------------
1 | @import 'src/styles/partials/utils';
2 | @import 'src/styles/partials/theme';
3 |
4 | .poll-page__content {
5 | display: flex;
6 | flex-direction: row;
7 | justify-content: center;
8 | align-items: center;
9 | width: 100%;
10 | flex-grow: 1;
11 | background-color: $background-dark-0;
12 | }
13 |
14 | .poll-page__content-wrapper {
15 | width: 100%;
16 | }
17 |
18 | @media screen and (max-width: 1024px) {
19 | .poll-page__content-wrapper {
20 | .breadcrumbs-wrapper {
21 | display: none;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/pages/contract-page/components/personal-form/PersonalForm.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const formWrapper: SxProps = {
5 | display: 'flex',
6 | justifyContent: 'center',
7 | flexDirection: 'column',
8 | };
9 | export const buttonPanel: SxProps = {
10 | width: '100%',
11 | display: 'flex',
12 | justifyContent: 'center',
13 | alignItems: 'center',
14 | gap: '40px',
15 | };
16 | export const button: SxProps = {
17 | maxWidth: '240px',
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/pages/contract-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ContractPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/email-confirmation-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from 'src/components/pages/email-confirmation-page/EmailConfirmationPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-admin-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './EntrantAdminPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-admin-page/utils/localStorage.ts:
--------------------------------------------------------------------------------
1 | import type { DeleteEntrantBody } from '@/lib/api/contract/types/DeleteEntrantBody';
2 |
3 | export const saveLocalStorage = (data: DeleteEntrantBody | null) => {
4 | localStorage.setItem('deleteEntrantData', JSON.stringify(data));
5 | };
6 |
7 | export const getLocalStorage = (): DeleteEntrantBody | null => {
8 | const data = localStorage.getItem('deleteEntrantData');
9 |
10 | if (data) return JSON.parse(data);
11 |
12 | return null;
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-dashboard-page/components/entrant-approve-form/constants.ts:
--------------------------------------------------------------------------------
1 | import { ContractAdminBody } from '@/lib/api/contract/types/AdminContractBody';
2 |
3 | export const initialValues: ContractAdminBody = {
4 | number: '',
5 | date: '',
6 | };
7 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-dashboard-page/components/entrant-approve-form/validation.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const validationSchema = yup.object().shape({
4 | number: yup.string().required(`Обов'язкове поле`),
5 | date: yup.string().required(`Обов'язкове поле`),
6 | });
7 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-dashboard-page/components/entrant-search-form/constants.ts:
--------------------------------------------------------------------------------
1 | import { EntrantBody } from '@/types/contract';
2 |
3 | export const initialValues: EntrantBody = {
4 | firstName: '',
5 | middleName: '',
6 | lastName: '',
7 | specialty: '',
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-dashboard-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './EntrantDashboardPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/entrant-dashboard-page/utils/localStorage.ts:
--------------------------------------------------------------------------------
1 | import { EntrantBody, Fullname } from '@/types/contract';
2 |
3 | export const saveLocalStorage = (data: Fullname | null) => {
4 | localStorage.setItem('entrantAdminPageData', JSON.stringify(data));
5 | };
6 |
7 | export const getLocalStorage = (): EntrantBody | null => {
8 | const data = localStorage.getItem('entrantAdminPageData');
9 |
10 | let parsedData;
11 | if (data) {
12 | parsedData = JSON.parse(data);
13 | return parsedData as EntrantBody;
14 | }
15 |
16 | return null;
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/login-form-block/components/login-form/LoginForm.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | import theme from '@/styles/theme';
4 |
5 | export const passwordLink: SxProps = {
6 | marginBottom: '30px',
7 | alignSelf: 'flex-start',
8 |
9 | [theme.breakpoints.down('mobileMedium')]: {
10 | marginBottom: '26px',
11 | },
12 | };
13 |
14 | export const loginButton: SxProps = {
15 | borderRadius: '8px',
16 |
17 | [theme.breakpoints.down('mobileMedium')]: {
18 | padding: '12px 24px',
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/login-form-block/components/login-form/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { LoginFormFields } from '@/components/pages/login-page/components/login-form-block/components/login-form/types';
2 |
3 | export const initialValues: LoginFormFields = {
4 | username: '',
5 | password: '',
6 | };
7 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/login-form-block/components/login-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LoginForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/login-form-block/components/login-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface LoginFormFields {
2 | username: string;
3 | password: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/login-form-block/components/login-form/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const validationSchema = yup.object().shape({
4 | username: yup.string().required(''),
5 | password: yup.string().required(''),
6 | });
7 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/login-form-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LoginFormBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/components/logo-register-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LogoRegisterBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/login-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LoginPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/main-page/completely-normal-folder/GreetingBlock.module.scss:
--------------------------------------------------------------------------------
1 | @media screen and (max-width: 768px){
2 | .kitten-image {
3 | width: 102px;
4 | height: 102px;
5 | }
6 | }
--------------------------------------------------------------------------------
/src/components/pages/main-page/components/resource-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ResourceCard';
2 |
--------------------------------------------------------------------------------
/src/components/pages/main-page/components/token-popup/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TokenPopup';
2 |
--------------------------------------------------------------------------------
/src/components/pages/main-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './MainPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/create-password-page/components/create-password-form/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { CreatePasswordFormFields } from '../types';
2 |
3 | export const initialValues: CreatePasswordFormFields = {
4 | password: '',
5 | confirmPassword: '',
6 | };
7 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/create-password-page/components/create-password-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CreatePasswordForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/create-password-page/components/create-password-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface CreatePasswordFormFields {
2 | password: string;
3 | confirmPassword: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/create-password-page/components/create-password-form/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const validationSchema = yup.object().shape({
4 | password: yup
5 | .string()
6 | .required(`Обов'язкове поле`)
7 | .matches(
8 | /^(?=.*[A-Za-z])(?=.*\d)[\w\W]+$/,
9 | 'Мінімум одна латинська літера та одна цифра',
10 | ),
11 | confirmPassword: yup
12 | .string()
13 | .nullable()
14 | .oneOf([yup.ref('password'), null], 'Паролі не збігаються')
15 | .required('Це поле не може бути пустим'),
16 | });
17 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/create-password-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CreatePasswordPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/email-confirmation-page/PasswordResetEmailConfirmationPage.tsx:
--------------------------------------------------------------------------------
1 | import EmailConfirmationPage from '@/components/pages/email-confirmation-page';
2 |
3 | const PasswordResetEmailConfirmationPage = () => (
4 |
5 | );
6 |
7 | export default PasswordResetEmailConfirmationPage;
8 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/email-confirmation-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PasswordResetEmailConfirmationPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/email-confirmation-page/utils/chooseMessageError.ts:
--------------------------------------------------------------------------------
1 | const chooseMessageError = (errorName: string, tries: number): string => {
2 | let errorMessage = 'Як ти це зробив?';
3 | if (errorName === 'TooManyActionsException') {
4 | tries++;
5 | if (tries >= 5) errorMessage = 'Да ти заєбав';
6 | else errorMessage = ' Час для надсилання нового листа ще не сплив';
7 | } else if (errorName === 'NotRegisteredException') {
8 | errorMessage = 'Упс, реєструйся заново';
9 | }
10 | return errorMessage;
11 | };
12 |
13 | export default chooseMessageError;
14 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/forgot-password-page/components/forgot-password-form/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { ForgotPasswordFormFields } from '../types';
2 |
3 | export const initialValues: ForgotPasswordFormFields = {
4 | email: '',
5 | };
6 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/forgot-password-page/components/forgot-password-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ForgotPasswordForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/forgot-password-page/components/forgot-password-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface ForgotPasswordFormFields {
2 | email: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/forgot-password-page/components/forgot-password-form/validation/index.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const validationSchema = yup.object().shape({
4 | email: yup
5 | .string()
6 | .email('Це не схоже на поштову адресу')
7 | .required('Це не схоже на поштову адресу'),
8 | });
9 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/forgot-password-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ForgotPasswordPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/link-expired/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PasswordResetLinkExpiredPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/password-recovery/link-valid/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PasswordResetValidLinkPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/contacts/Contact.module.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../styles/partials/utils";
2 | @import "../../../../styles/partials/theme";
3 | @import "../../../../styles/partials/typography-mixins";
4 |
5 | .contact{
6 | display: flex;
7 | flex-direction: row;
8 | width: fit-content;
9 | gap: 8px;
10 | align-items: center;
11 | }
12 |
13 | .icon{
14 | width: 24px;
15 | height: 24px;
16 | }
17 | .link{
18 | @include body-primary;
19 | }
20 |
21 | @media screen and (max-width: 1200px){
22 | .icon{
23 | width: 18px;
24 | height: 18px;
25 | }
26 | .link{
27 | @include overline-text;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/contacts/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Contact';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PersonalTeacherPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/PersonalTeacherTabs.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const tabList: SxProps = {
4 | paddingTop: '24px',
5 | '.MuiTabs-flexContainer': {
6 | gap: '8px',
7 | overflow: 'scroll',
8 | scrollbarWidth: 'none',
9 | '&::-webkit-scrollbar': {
10 | width: '0',
11 | height: '0',
12 | },
13 | '.MuiTab-root': {
14 | zIndex: '1',
15 | },
16 | },
17 | width: '100%',
18 | };
19 |
20 | export const tabPanelList: SxProps = {
21 | padding: {
22 | mobile: '20px 0 38px',
23 | desktop: '24px 0 50px',
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/comment-tab/CommentTab.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const wrapper: SxProps = {
4 | display: 'flex',
5 | gap: '16px',
6 | };
7 |
8 | export const commentsWrapper: SxProps = {
9 | maxWidth: '750px',
10 | width: '100%',
11 | display: 'flex',
12 | flexDirection: 'column',
13 | gap: '14px',
14 | };
15 |
16 | export const dropdown = {
17 | marginBottom: '12px',
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/comment-tab/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { DropDownOption } from '@/components/common/ui/form/dropdown/types';
2 |
3 | export const sortInfo: DropDownOption[] = [
4 | {
5 | label: 'Спочатку нові',
6 | id: 'newest',
7 | },
8 | {
9 | label: 'Спочатку від дідів',
10 | id: 'oldest',
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/comment-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CommentTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/general-tab/components/FillerBox.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const filler = (width: string): SxProps => ({
4 | width: width,
5 | height: '0',
6 | });
7 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/general-tab/components/FillerBox.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { Box } from '@mui/material';
3 |
4 | import * as styles from './FillerBox.styles';
5 | interface FillerBoxProps {
6 | width: string;
7 | }
8 |
9 | const FillerBox: FC = ({ width }) => {
10 | return (
11 | <>
12 | {Array.from({ length: 4 }).map((_, index) => (
13 |
14 | ))}
15 | >
16 | );
17 | };
18 |
19 | export default FillerBox;
20 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/general-tab/components/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FillerBox';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/general-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './GeneralTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/poll-buttons/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PollButtons';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/subject-tab/SubjectTab.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const wrapper: SxProps = {
4 | columns: {
5 | mobile: '1',
6 | mobileSemiMedium: '2',
7 | tablet: '3',
8 | desktop: '4',
9 | },
10 | };
11 |
12 | export const listItem: SxProps = {
13 | marginBottom: '16px',
14 | breakInside: 'avoid',
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/components/subject-tab/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SubjectTab';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/personal-teacher-tabs/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PersonalTeacherTabs';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-page/utils/index.ts:
--------------------------------------------------------------------------------
1 | import { NextParsedUrlQuery } from 'next/dist/server/request-meta';
2 | import { NextRouter } from 'next/router';
3 |
4 | import { TeacherPageInfo } from '@/lib/services/teacher/types';
5 | import { Teacher } from '@/types/teacher';
6 |
7 | export enum TeachersPageTabs {
8 | GENERAL = 'general',
9 | SUBJECTS = 'subjects',
10 | COMMENTS = 'reviews',
11 | }
12 |
13 | export interface PersonalTeacherPageProps {
14 | isLoading: boolean;
15 | isError: boolean;
16 | teacher: Teacher;
17 | data: TeacherPageInfo | undefined;
18 | query: NextParsedUrlQuery;
19 | teacherId: string;
20 | router: NextRouter;
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-subject-page/contacts/Contact.module.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../styles/partials/utils";
2 | @import "../../../../styles/partials/theme";
3 | @import "../../../../styles/partials/typography-mixins";
4 |
5 | .contact{
6 | display: flex;
7 | flex-direction: row;
8 | width: fit-content;
9 | gap: 8px;
10 | align-items: center;
11 | }
12 |
13 | .icon{
14 | width: 24px;
15 | height: 24px;
16 | }
17 | .link{
18 | @include body-primary;
19 | }
20 |
21 | @media screen and (max-width: 1200px){
22 | .icon{
23 | width: 18px;
24 | height: 18px;
25 | }
26 | .link{
27 | @include overline-text;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-subject-page/contacts/index.ts:
--------------------------------------------------------------------------------
1 | export { ContactType, default } from './Contact';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-subject-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PersonalTeacherSubjectPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-subject-page/personal-subject-teacher-tabs/PersonalSubjectTeacherTabs.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const tabList: SxProps = {
4 | paddingTop: '24px',
5 | '.MuiTabs-flexContainer': {
6 | gap: '8px',
7 | overflow: 'scroll',
8 | scrollbarWidth: 'none',
9 | '&::-webkit-scrollbar': {
10 | width: '0',
11 | height: '0',
12 | },
13 | '.MuiTab-root': {
14 | zIndex: '1',
15 | },
16 | },
17 | width: '100%',
18 | };
19 |
20 | export const tabPanelList: SxProps = {
21 | padding: {
22 | mobile: '20px 0 38px',
23 | desktop: '24px 0 50px',
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/src/components/pages/personal-teacher-subject-page/personal-subject-teacher-tabs/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PersonalSubjectTeacherTabs';
2 |
--------------------------------------------------------------------------------
/src/components/pages/poll-fucked-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PollPageFailed';
2 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/answers-sheet/AnswersSaved/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './AnswersSaved';
2 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/answers-sheet/AnswersSheet.module.scss:
--------------------------------------------------------------------------------
1 | @import 'src/styles/partials/theme';
2 |
3 | .form {
4 | display: flex;
5 | flex-direction: column;
6 | gap: 40px;
7 | }
8 |
9 | @media screen and (max-width: 1024px) {
10 | .form {
11 | display: flex;
12 | flex-direction: column;
13 | gap: 32px;
14 | width: 100%;
15 | height: 100%;
16 | padding: 24px 32px;
17 | }
18 | }
19 |
20 | @media screen and (max-width: 425px) {
21 | .form {
22 | padding: 24px 21px;
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/answers-sheet/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AnswersSheet';
2 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/poll-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PollForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/poll-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum SendingStatus {
2 | ANY = 'any',
3 | LOADING = 'loading',
4 | SUCCESS = 'success',
5 | ERROR = 'error',
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/questions-list/QuestionsList.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | import theme from '@/styles/theme';
4 |
5 | export const wrapper: SxProps = {
6 | [theme.breakpoints.down('desktop')]: {
7 | width: '100%',
8 | animationName: 'appear',
9 | animationDuration: '0.3s',
10 | },
11 |
12 | '@keyframe appear': {
13 | from: {
14 | opacity: 0,
15 | },
16 |
17 | to: {
18 | opacity: 1,
19 | },
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/components/questions-list/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './QuestionsList';
2 |
--------------------------------------------------------------------------------
/src/components/pages/poll-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PollPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/priority-approve-page/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const initialValues = {
2 | firstName: '',
3 | middleName: '',
4 | lastName: '',
5 | };
6 |
7 | export const expectedValues = {
8 | firstName: '',
9 | middleName: '',
10 | lastName: '',
11 | priorities: {
12 | 1: '',
13 | 2: '',
14 | 3: '',
15 | },
16 | specialty: '',
17 | state: '',
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/pages/priority-approve-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PriorityApprovePage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/priority-approve-page/utils/checkError.ts:
--------------------------------------------------------------------------------
1 | const errors = {
2 | InvalidBodyException: 'Дані вказані невірно',
3 | DataNotFoundException: 'Дані не знайдено',
4 | AlreadyExistException: 'Контракт вже існує',
5 | UnauthorizedException: 'Користувач не авторизований',
6 | NoPermissionException: 'У тебе немає дозволу на виконання цієї дії',
7 | };
8 |
9 | export const checkError = (requestError: string) => {
10 | for (const [exception, error] of Object.entries(errors)) {
11 | if (requestError === exception) {
12 | return error;
13 | }
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/pages/priority-approve-page/utils/getPriorityName.ts:
--------------------------------------------------------------------------------
1 | const priorityName = {
2 | CSSE: "Інженерія програмного забезпечення комп'ютерних систем ",
3 | ISSE: 'Інженерія програмного забезпечення інформаційних систем',
4 | IIS: 'Інтегровані інформаційні системи',
5 | ISRS: 'Інформаційне забезпечення робототехнічних систем',
6 | IMST: 'Інформаційні управляючі системи та технології',
7 | };
8 |
9 | export const getPriorityName = (priority: string) => {
10 | const entries = Object.entries(priorityName);
11 | for (const [shortcut, name] of entries) {
12 | if (shortcut === priority) return name;
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/pages/priority-approve-page/utils/getSpecialityName.ts:
--------------------------------------------------------------------------------
1 | const specialities = {
2 | 121: 'Інженерія програмного забезпечення',
3 | 123: "Комп'ютерна інженерія",
4 | 126: 'Інформаційні системи та технології',
5 | };
6 |
7 | export const getSpecialityName = (number: string) => {
8 | const entries = Object.entries(specialities);
9 | for (const [num, name] of entries) {
10 | if (num === number) return name;
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/pages/priority-page/PriorityPage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const item: SxProps = {
4 | marginTop: '8px',
5 | display: 'flex',
6 | flexDirection: 'column',
7 | gap: '8px',
8 | marginBottom: '16px',
9 | width: { tablet: '480px', mobile: '100%' },
10 | };
11 |
12 | export const divider: SxProps = {
13 | borderColor: 'grey.400',
14 | color: 'grey.500',
15 | marginBottom: '8px',
16 | };
17 |
--------------------------------------------------------------------------------
/src/components/pages/priority-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PriorityPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/privacy-page/PrivacyPage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const privacyContent: SxProps = {
4 | padding: {
5 | mobile: '8%',
6 | tablet: '3% 20% 4% 13%',
7 | },
8 | };
9 |
10 | export const privacyListInfo: SxProps = {
11 | margin: '1% 0 0',
12 | };
13 |
14 | export const privacyList: SxProps = {
15 | marginTop: '2%',
16 | display: 'flex',
17 | flexDirection: 'column',
18 | gap: '36px',
19 | };
20 |
--------------------------------------------------------------------------------
/src/components/pages/privacy-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PrivacyPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/register/email-confirmation-page/RegistrationEmailConfirmationPage.tsx:
--------------------------------------------------------------------------------
1 | import EmailConfirmationPage from '@/components/pages/email-confirmation-page';
2 |
3 | const RegistrationEmailConfirmationPage = () => (
4 |
5 | );
6 |
7 | export default RegistrationEmailConfirmationPage;
8 |
--------------------------------------------------------------------------------
/src/components/pages/register/email-confirmation-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './RegistrationEmailConfirmationPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/RegisterImage.module.scss:
--------------------------------------------------------------------------------
1 | .background-image {
2 | height: fit-content;
3 | position: absolute;
4 | top: 0;
5 | min-height: 100vh;
6 | min-width: 100%;
7 | z-index: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/left-block/Link.module.scss:
--------------------------------------------------------------------------------
1 | @import "src/styles/partials/utils";
2 | @import "src/styles/partials/breakpoints";
3 |
4 | .mobile-register-logo-container {
5 | @include flex-center;
6 | position: relative;
7 | margin: 8vh 4vh;
8 | display: none;
9 | width: calc(100% - 40px);
10 | min-width: 200px;
11 | aspect-ratio: 7.1/1;
12 | justify-content: center;
13 | }
14 |
15 | @media screen and (max-width: $breakpoint-desktop-semi-medium) {
16 | .mobile-register-logo-container {
17 | display: flex;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/left-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LeftBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/register-form/FormStyles.module.scss:
--------------------------------------------------------------------------------
1 | .form {
2 | margin-top: 16px;
3 | width: 100%;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: flex-start;
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/register-form/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { RegisterFormFields } from '@/components/pages/register/register-page/components/register-form/types';
2 |
3 | export const initialValues: RegisterFormFields = {
4 | username: '',
5 | firstName: '',
6 | lastName: '',
7 | middleName: '',
8 | email: '',
9 | group: '',
10 | isCaptain: false,
11 | password: '',
12 | passwordConfirmation: '',
13 | agreement: false,
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/register-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './RegisterForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/register-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface RegisterFormFields {
2 | username: string;
3 | firstName: string;
4 | lastName: string;
5 | middleName: string;
6 | email: string;
7 | group: string;
8 | isCaptain: boolean;
9 | password: string;
10 | passwordConfirmation: string;
11 | agreement: boolean;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/right-block/RightBlock.module.scss:
--------------------------------------------------------------------------------
1 | .login-logo{
2 | margin: 0;
3 | padding: 8px;
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/components/right-block/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './RightBlock';
2 |
--------------------------------------------------------------------------------
/src/components/pages/register/register-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './RegisterPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/register/verify-email-token-page/VerifyEmailTokenPage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const box: SxProps = {
4 | flexGrow: 1,
5 | display: 'flex',
6 | alignItems: 'center',
7 | justifyContent: 'center',
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/pages/register/verify-email-token-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './VerifyEmailTokenPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/SchedulePage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const schedulePage: SxProps = {
5 | display: 'flex',
6 | flexDirection: { mobile: 'column', tablet: 'row' },
7 | alignItems: { mobile: 'stretch', tablet: 'center' },
8 | pl: { mobile: '10%', tablet: 'unset' },
9 | pr: { mobile: '10%', tablet: 'unset' },
10 | justifyContent: 'space-between',
11 |
12 | width: '100%',
13 | mt: '16px',
14 | mb: '74px',
15 | ml: '16px',
16 | mr: '16px',
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/calendar-section/CalendarSection.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const mainWrapper: SxProps = {
5 | width: '325px',
6 | height: 'min(80vh)',
7 | display: 'flex',
8 | flexFlow: 'column nowrap',
9 | alignItems: 'center',
10 | gap: '16px',
11 | };
12 | export const sticky: SxProps = {
13 | position: 'sticky',
14 | top: '80px',
15 | alignItems: 'center',
16 | mb: '16px',
17 | };
18 |
19 | export const wrapper: SxProps = {
20 | gap: '8px',
21 | alignItems: 'center',
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/calendar-section/components/checkboxes-section/CheckBoxSection.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const checkboxes: SxProps = {
5 | flexDirection: 'column',
6 | alignSelf: 'flex-start',
7 | pl: '16px',
8 | gap: '12px',
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/calendar-section/components/mobile/CalendarSectionMobile.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const mainWrapper: SxProps = {
5 | display: 'flex',
6 | flexFlow: 'column nowrap',
7 | alignItems: 'center',
8 | gap: '16px',
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/calendar-section/components/mobile/buttonIcons/buttonIcons.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const buttonIcons: SxProps = {
5 | position: 'fixed',
6 | right: '10%',
7 | bottom: '32px',
8 | display: 'flex',
9 | flexDirection: 'column',
10 | height: '93px',
11 | justifyContent: 'space-between',
12 | gap: '10px',
13 | zIndex: 11,
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/calendar-section/components/mobile/checkboxes-dropdown/types/CheckboxOption.ts:
--------------------------------------------------------------------------------
1 | export interface CheckboxOption {
2 | label: string;
3 | value: string;
4 | checked?: boolean;
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/calendar-section/components/tabs-section/TabSection.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const tabList: SxProps = {};
5 |
6 | export const tabBox: SxProps = {
7 | display: 'flex',
8 | flexFlow: 'column nowrap',
9 | alignItems: 'center',
10 | gap: '16px',
11 | '& .MuiTabs-root': {
12 | minHeight: 'fit-content',
13 | },
14 | width: '100%',
15 | '& .MuiTabs-flexContainer': { justifyContent: 'center' },
16 | '& .MuiButtonBase-root.MuiTab-root': {
17 | width: 'fit-content',
18 | },
19 | '& .MuiTabPanel-root': {
20 | p: 0,
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/constants.ts:
--------------------------------------------------------------------------------
1 | export const LOCAL_STORAGE_SCHEDULE_KEY = 'scheduleChosenGroupId';
2 | export const MAX_WEEK_NUMBER = 20;
3 | export const TZ = 'Europe/Kiev';
4 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SchedulePage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleEventEdit';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/components/calendar-input/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CalendarInput';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/components/schedule-input/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleInput';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/components/text-area/TextArea.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const textArea: SxProps = {
4 | backgroundColor: 'backgroundDark.200',
5 | borderRadius: '8px',
6 | p: '12px',
7 | '& div': {
8 | color: 'grey.500',
9 | },
10 | '&:hover': {
11 | div: {
12 | color: 'grey.700',
13 | },
14 | },
15 | width: '100%',
16 | };
17 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/components/text-area/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TextArea';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/components/text-area/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum TextAreaSize {
2 | NORMAL = 'normal',
3 | SMALL = 'small',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/icons/Delete.tsx:
--------------------------------------------------------------------------------
1 | export const Delete = () => {
2 | return (
3 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/icons/End.tsx:
--------------------------------------------------------------------------------
1 | export const End = () => {
2 | return (
3 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleEventForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/utils/getDateWithTimeSet.ts:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs';
2 |
3 | export function getDateWithTimeSet(date: dayjs.Dayjs, time: string) {
4 | return (
5 | date.format('YYYY-MM-DDTHH:mm:ssZ[Z]').toString().substring(0, 11) +
6 | time.substring(11)
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/schedule-info-card/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleInfoCard';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum InfoCardTabs {
2 | DISCIPLINE = 'discipline',
3 | EVENT = 'event',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-event-edit-section/utils/skeletonProps.ts:
--------------------------------------------------------------------------------
1 | import { SkeletonProps } from '@mui/material/Skeleton';
2 |
3 | export const skeletonProps: SkeletonProps = {
4 | sx: { bgcolor: 'grey.200' },
5 | variant: 'rounded',
6 | animation: 'wave',
7 | };
8 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/ScheduleSection.tsx:
--------------------------------------------------------------------------------
1 | import { Box } from '@mui/material';
2 |
3 | import Schedule from './components/schedule';
4 | import ScheduleHeader from './components/schedule-header';
5 | import * as styles from './ScheduleSection.styles';
6 |
7 | export const ScheduleSection = ({}) => {
8 | return (
9 |
10 |
11 |
12 |
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule-header/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleHeader';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/ScheduleColumn.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const column: SxProps = {
4 | position: 'relative',
5 | display: 'flex',
6 | flexDirection: 'column',
7 | gap: '10px',
8 | width: { mobile: '100%', tablet: '148px' },
9 | height: { mobile: '100%', tablet: '1344px' },
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/components/schedule-card/ScheduleCard.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const wrapper = (
4 | top: number,
5 | height: string | number,
6 | zIndex = 0,
7 | ): SxProps => ({
8 | width: {
9 | tablet: '132px',
10 | mobile: '100%',
11 | },
12 | height: {
13 | tablet: `calc(${height}px + 4px)`,
14 | mobile: '80px',
15 | },
16 | zIndex,
17 | borderRadius: '6px',
18 | position: { mobile: 'relative', tablet: 'absolute' },
19 | transform: { tablet: `translateY(calc(${top}px - 5px))` },
20 | transition: 'linear .1s all',
21 | });
22 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/components/schedule-card/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleCard';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/components/schedule-card/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum DisciplineType {
2 | LECTURE = 'LECTURE',
3 | PRACTICE = 'PRACTICE',
4 | LABORATORY = 'LABORATORY',
5 | CONSULTATION = 'CONSULTATION',
6 | WORKOUT = 'WORKOUT',
7 | EXAM = 'EXAM',
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/components/schedule-card/utils/calculateHeight.ts:
--------------------------------------------------------------------------------
1 | const calculateHeight = (startTime: string, endTime: string): number => {
2 | const start = new Date(startTime);
3 | const end = new Date(endTime);
4 |
5 | const difference = end.getTime() - start.getTime();
6 | const minutes = difference / 60000;
7 | return minutes * 1.4;
8 | };
9 |
10 | export default calculateHeight;
11 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/components/schedule-card/utils/calculateScheduleLineTop.ts:
--------------------------------------------------------------------------------
1 | export const calculateScheduleLineTop = (
2 | startTime: string,
3 | endTime: string,
4 | currentTime: string,
5 | ): number => {
6 | if (startTime && endTime && currentTime) {
7 | const start = new Date(startTime);
8 | const end = new Date(endTime);
9 | const current = new Date(currentTime);
10 | const eventDuration = end.getTime() - start.getTime();
11 | const elapsedTime = current.getTime() - start.getTime();
12 | return (elapsedTime / eventDuration) * 100;
13 | }
14 | return 0;
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/components/schedule-card/utils/calculateTop.ts:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs';
2 |
3 | export const calculateTop = (startTime: string): number => {
4 | if (startTime) {
5 | const date = dayjs(startTime).tz();
6 | const minutes = date.hour() * 60 + date.minute() - 7 * 60;
7 | return (minutes / 60) * 84 + 4;
8 | }
9 | return 0;
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-column/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleColumn';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-line/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleLine';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-line/types/index.ts:
--------------------------------------------------------------------------------
1 | export enum ScheduleLineVariant {
2 | LONG = 'long',
3 | SHORT = 'short',
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-time/ScheduleTime.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const time: SxProps = {
4 | display: 'flex',
5 | flexDirection: 'column',
6 | width: '39px',
7 | gap: '64.4px',
8 | marginTop: '74px',
9 | marginRight: '7px',
10 | };
11 |
12 | export const text: SxProps = {
13 | typography: 'body1',
14 | color: 'grey.400',
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/components/schedule-time/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ScheduleTime';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/schedule-section/components/schedule/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Schedule';
2 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/utils/areDatesInSameWeek.ts:
--------------------------------------------------------------------------------
1 | export const areDatesInSameWeek = (
2 | eventsTime: string,
3 | currentTime: string,
4 | ): boolean => {
5 | const copyEventsTime = new Date(eventsTime);
6 | const copyCurrentTime = new Date(currentTime);
7 | copyEventsTime.setHours(0, 0, 0, 0);
8 | copyEventsTime.setDate(copyEventsTime.getDate() - copyEventsTime.getDay());
9 | copyCurrentTime.setHours(0, 0, 0, 0);
10 | copyCurrentTime.setDate(copyCurrentTime.getDate() - copyCurrentTime.getDay());
11 | return copyEventsTime.getTime() === copyCurrentTime.getTime();
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/utils/areValuesUnique.ts:
--------------------------------------------------------------------------------
1 | export const areValuesUnique = (arr: T[]) => {
2 | for (let i = 0; i < arr.length; ++i) {
3 | for (let j = i; j < arr.length; ++j) {
4 | if (arr[i] === arr[j] && i !== j && arr[i] && arr[j]) return false;
5 | }
6 | }
7 | return true;
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/utils/getCurrentWeek.ts:
--------------------------------------------------------------------------------
1 | import { GetCurrentSemester } from '@/lib/api/dates/types/GetCurrentSemester';
2 | export const getCurrentWeek = (semester: GetCurrentSemester) => {
3 | const startDateMs = new Date(semester.startDate).getTime();
4 | const nowDateMs = new Date().getTime();
5 |
6 | const weekFloating = (nowDateMs - startDateMs) / (1000 * 60 * 60 * 24 * 7);
7 |
8 | const currentWeek = Math.ceil(weekFloating);
9 |
10 | return currentWeek;
11 | };
12 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/utils/getStringTime.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @param time - time in ISOString format
3 | */
4 | import dayjs from 'dayjs';
5 |
6 | export const getStringTime = (time: string) => {
7 | const date = dayjs(time).tz();
8 | return date.format('HH:mm');
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/pages/schedule-page/utils/undefineNegativeValues.ts:
--------------------------------------------------------------------------------
1 | export const makeNegativeValuesUndefined = (
2 | _dataFromForm: T,
3 | ) => {
4 | const dataFromForm = JSON.parse(JSON.stringify(_dataFromForm));
5 |
6 | for (const _key in dataFromForm) {
7 | const key = _key as keyof T;
8 | if (!dataFromForm[key]) {
9 | dataFromForm[key] = undefined;
10 | }
11 | }
12 |
13 | return dataFromForm;
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/poll-teachers-page/PollTeacherPage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const layout: SxProps = {
4 | width: '100%',
5 | display: 'flex',
6 | flexDirection: 'column',
7 | padding: '0px 80px 32px 80px',
8 | };
9 |
10 | export const pageLoader: SxProps = {
11 | padding: '30px 0',
12 | width: '100%',
13 | display: 'flex',
14 | justifyContent: 'center',
15 | };
16 |
17 | export const loadBtn: SxProps = {
18 | width: '200px',
19 | alignSelf: 'center',
20 | };
21 |
22 | export const breadcrumps: SxProps = {
23 | margin: '16px 0px 16px 0px',
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/poll-teachers-page/components/PollTeacherSearchList.module.scss:
--------------------------------------------------------------------------------
1 | @import "src/styles/partials/typography-mixins";
2 | @import "src/styles/partials/breakpoints";
3 |
4 | @media only screen and (max-width: $breakpoint-mobile-medium){
5 | .form{
6 | column-gap: 15px;
7 | }
8 | }
--------------------------------------------------------------------------------
/src/components/pages/search-pages/poll-teachers-page/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PollTeacherPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/search-form/SearchForm.module.scss:
--------------------------------------------------------------------------------
1 | @import "src/styles/partials/breakpoints";
2 |
3 | .form {
4 | display: grid;
5 | grid-template-columns: 35% 15% 15% 5%;
6 | grid-template-rows: 1fr;
7 | gap: 12px;
8 | margin-bottom: 34px;
9 | align-items: center;
10 |
11 | }
12 |
13 |
14 | @media screen and (max-width: $breakpoint-tablet) {
15 | .form {
16 | grid-template-columns: 35% 45% 10%;
17 | }
18 | .input {
19 | grid-column: 1 / span 2;
20 | }
21 | }
22 |
23 | @media only screen and (max-width: $breakpoint-mobile){
24 | .form{
25 | column-gap: 15px;
26 | margin-bottom: 24px;
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/search-form/constants.ts:
--------------------------------------------------------------------------------
1 | import { SearchFormFields } from './types';
2 |
3 | export const TeacherInitialValues: SearchFormFields = {
4 | search: '',
5 | order: 'asc',
6 | sort: 'lastName',
7 | group: '',
8 | };
9 |
10 | export const SubjectInitialValues: SearchFormFields = {
11 | search: '',
12 | order: 'asc',
13 | sort: 'name',
14 | group: '',
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/search-form/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SearchForm';
2 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/search-form/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface SearchFormFields {
2 | search: string;
3 | order: 'asc' | 'desc';
4 | sort: string;
5 | group: string;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/subject-search/components/SubjectSearchList.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps } from '@mui/material/styles';
2 | import { Theme } from '@mui/system';
3 |
4 | export const masonry: SxProps = {
5 | margin: '0',
6 | li: {
7 | listStyle: 'none',
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/subject-search/components/constants/breakpoints.tsx:
--------------------------------------------------------------------------------
1 | export const breakpoints = {
2 | desktop: 4,
3 | tablet: 3,
4 | mobileSemiMedium: 2,
5 | mobile: 1,
6 | };
7 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/subject-search/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { Breadcrumb } from '@/components/common/ui/breadcrumbs/types';
2 | import { DropDownOption } from '@/components/common/ui/form/dropdown/types';
3 |
4 | export const filterOptions: DropDownOption[] = [
5 | { id: 'name', label: 'За назвою' },
6 | ];
7 |
8 | export const breadcrumbs: Breadcrumb[] = [
9 | {
10 | label: 'Головна',
11 | href: '/',
12 | },
13 | {
14 | label: 'Предмети',
15 | href: '/subjects',
16 | },
17 | ];
18 |
19 | export const PAGE_SIZE = 20;
20 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/subject-search/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SubjectSearchPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/subject-teacher-search/SearchTeacherPage.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const breadcrumbs: SxProps = {
4 | margin: '16px 0px 16px 0px',
5 | };
6 |
7 | export const layout: SxProps = {
8 | width: '100%',
9 | display: 'flex',
10 | flexDirection: 'column',
11 | padding: {
12 | mobile: '0px 16px 32px',
13 | desktopSemiMedium: '0px 80px 32px',
14 | },
15 | };
16 |
17 | export const pageLoader: SxProps = {
18 | paddingTop: '30px',
19 | paddingBottom: '30px',
20 | width: '100%',
21 | display: 'flex',
22 | justifyContent: 'center',
23 | };
24 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/subject-teacher-search/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SearchTeacherPage';
2 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/teacher-search/components/TeacherSearchList.styles.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | export const teacherSearchList: SxProps = {
4 | marginTop: '40px',
5 | marginBottom: '16px',
6 | display: 'grid',
7 | gridTemplateColumns: {
8 | mobile: 'repeat(2, 1fr)',
9 | desktop: 'repeat(3, 1fr)',
10 | desktopSemiMedium: 'repeat(4, 1fr)',
11 | },
12 | columnGap: {
13 | mobile: '16px',
14 | desktop: '32px',
15 | desktopSemiMedium: '3rem',
16 | },
17 | rowGap: '4rem',
18 | gridAutoRows: 'max-content',
19 | alignItems: 'center',
20 | };
21 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/teacher-search/constants/index.ts:
--------------------------------------------------------------------------------
1 | import { Breadcrumb } from '@/components/common/ui/breadcrumbs/types';
2 | import { DropDownOption } from '@/components/common/ui/form/dropdown/types';
3 |
4 | export const filterOptions: DropDownOption[] = [
5 | { id: 'firstName', label: 'Іменем' },
6 | { id: 'lastName', label: 'Прізвищем' },
7 | ];
8 |
9 | export const breadcrumbs: Breadcrumb[] = [
10 | {
11 | label: 'Головна',
12 | href: '/',
13 | },
14 | {
15 | label: 'Викладачі',
16 | href: '/teachers',
17 | },
18 | ];
19 |
20 | export const PAGE_SIZE = 20;
21 |
--------------------------------------------------------------------------------
/src/components/pages/search-pages/teacher-search/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TeacherSearchPage';
2 |
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
1 | const config = {
2 | service: 'FICT Advisor',
3 | };
4 |
5 | export default config;
6 |
--------------------------------------------------------------------------------
/src/hooks/use-authentication/authentication-context/index.ts:
--------------------------------------------------------------------------------
1 | export { default, useAuthenticationContext } from './AuthenticationContext';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-authentication/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './useAuthentication';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-authentication/types/index.ts:
--------------------------------------------------------------------------------
1 | import { User } from '@/types/user';
2 |
3 | export interface AuthenticationContext {
4 | user: User;
5 | update: () => Promise;
6 | }
7 |
8 | export interface UseAuthenticationReturn extends AuthenticationContext {
9 | isLoggedIn: boolean;
10 | }
11 |
--------------------------------------------------------------------------------
/src/hooks/use-authentication/useAuthentication.tsx:
--------------------------------------------------------------------------------
1 | import { useAuthenticationContext } from '@/hooks/use-authentication/authentication-context';
2 | import { UseAuthenticationReturn } from '@/hooks/use-authentication/types';
3 |
4 | const useAuthentication = (): UseAuthenticationReturn => {
5 | const { user, update } = useAuthenticationContext();
6 |
7 | const isLoggedIn = !!user;
8 |
9 | return {
10 | user,
11 | isLoggedIn,
12 | update,
13 | };
14 | };
15 |
16 | export default useAuthentication;
17 |
--------------------------------------------------------------------------------
/src/hooks/use-outside-click/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './UseOutsideClick';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-tab-close/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './useTabClose';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-tab-close/useTabClose.tsx:
--------------------------------------------------------------------------------
1 | import { DependencyList, useEffect } from 'react';
2 |
3 | const useTabClose = (cb: () => void, deps: DependencyList = []) => {
4 | useEffect(() => {
5 | const handleTabClose = (event: BeforeUnloadEvent) => {
6 | event.preventDefault();
7 | cb();
8 | };
9 | window.addEventListener('beforeunload', handleTabClose);
10 | return () => {
11 | window.removeEventListener('beforeunload', handleTabClose);
12 | };
13 | }, deps);
14 | };
15 |
16 | export default useTabClose;
17 |
--------------------------------------------------------------------------------
/src/hooks/use-tab-state/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './UseTabState';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-toast/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './useToast';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-toast/toast-context/index.ts:
--------------------------------------------------------------------------------
1 | export { default, useToastContext } from './ToastContext';
2 |
--------------------------------------------------------------------------------
/src/hooks/use-toast/types/index.ts:
--------------------------------------------------------------------------------
1 | import { AlertType } from '@/components/common/ui/alert/types';
2 |
3 | export interface ToastState {
4 | open: boolean;
5 | title: string;
6 | type: AlertType;
7 | description?: string;
8 | timer?: number;
9 | }
10 |
11 | export type ToastActionProps = Omit;
12 |
13 | export interface ToastContext {
14 | showToast: (options: ToastActionProps) => void;
15 | }
16 |
17 | export type ToastFunction = (
18 | title: string,
19 | description?: string,
20 | timer?: number,
21 | ) => void;
22 |
23 | export type UseToastReturn = Record;
24 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/AuthBody.ts:
--------------------------------------------------------------------------------
1 | export interface AuthBody {
2 | username: string;
3 | password: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/ChangePasswordBody.ts:
--------------------------------------------------------------------------------
1 | export interface ChangePasswordBody {
2 | oldPassword: string;
3 | newPassword: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/CheckRegisterTelegramResponse.ts:
--------------------------------------------------------------------------------
1 | export interface CheckRegisterTelegramResponse {
2 | isRegistered: boolean;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/ForgotPasswordBody.ts:
--------------------------------------------------------------------------------
1 | export interface ForgotPasswordBody {
2 | email: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/RefreshAccesTokenResponse.ts:
--------------------------------------------------------------------------------
1 | export interface RefreshAccessTokenResponse {
2 | accessToken: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/RegisterBody.ts:
--------------------------------------------------------------------------------
1 | import { TelegramUser } from '@/types/telegram';
2 |
3 | interface Student {
4 | groupId: string;
5 | firstName: string;
6 | middleName: string;
7 | lastName: string;
8 | isCaptain: boolean;
9 | }
10 |
11 | export interface RegisterBody {
12 | student: Student;
13 | user: {
14 | username: string;
15 | email: string;
16 | password: string;
17 | };
18 | telegram?: TelegramUser;
19 | }
20 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/ResetPasswordBody.ts:
--------------------------------------------------------------------------------
1 | export interface ResetPasswordBody {
2 | password: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/ResetPasswordResponse.ts:
--------------------------------------------------------------------------------
1 | export interface ResetPasswordResponse {
2 | token: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/auth/types/VerifyEmailBody.ts:
--------------------------------------------------------------------------------
1 | export interface VerifyEmailBody {
2 | email: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/contract/types/AdminContractBody.ts:
--------------------------------------------------------------------------------
1 | import { EntrantBody } from '@/types/contract';
2 |
3 | export interface ContractAdminBody {
4 | number: string;
5 | date: string;
6 | }
7 |
8 | export interface AdminContractBody {
9 | entrant: EntrantBody;
10 | contract: ContractAdminBody;
11 | }
12 |
--------------------------------------------------------------------------------
/src/lib/api/contract/types/DeleteEntrantBody.ts:
--------------------------------------------------------------------------------
1 | import { Fullname } from '@/types/contract';
2 |
3 | export enum EntrantDeleteOptions {
4 | PRIORITY = 'priority',
5 | CONTRACT = 'contract',
6 | ENTRANT = 'entrant',
7 | }
8 |
9 | export interface DeleteEntrantBody extends Fullname {
10 | action: EntrantDeleteOptions;
11 | }
12 |
--------------------------------------------------------------------------------
/src/lib/api/contract/types/DeleteEntrantDataBody.ts:
--------------------------------------------------------------------------------
1 | export enum Actions {
2 | PRIORITY = 'пріоритет',
3 | CONTRACT = 'договір',
4 | ENTRANT = 'вступник',
5 | ENTRANT_DATA = 'дані',
6 | }
7 |
8 | export interface DeleteEntrantDataBody {
9 | action: Actions;
10 | entrantId: string;
11 | }
12 |
--------------------------------------------------------------------------------
/src/lib/api/contract/types/PriorityDataBody.ts:
--------------------------------------------------------------------------------
1 | import { Fullname } from '@/types/contract';
2 |
3 | export interface PriorityDataBody extends Fullname {
4 | specialty: string;
5 | email: string;
6 | day: string;
7 | isToAdmission: boolean;
8 | priorities: {
9 | 1: string;
10 | 2: string;
11 | 3?: string;
12 | };
13 | }
14 |
15 | export interface ExtendedPriorityDataBody extends PriorityDataBody {
16 | secretNumber: string;
17 | noMiddleName: boolean;
18 | isForcePushed: boolean;
19 | forcePushedNumber: string;
20 | }
21 |
--------------------------------------------------------------------------------
/src/lib/api/dates/DatesAPI.ts:
--------------------------------------------------------------------------------
1 | import { GetCurrentSemester } from '@/lib/api/dates/types/GetCurrentSemester';
2 | import { GetDates } from '@/lib/api/dates/types/GetDates';
3 | import { client } from '@/lib/api/instance';
4 | class DatesAPI {
5 | async getDates(isFinished = false) {
6 | const { data } = await client.get(`dates/semesters`, {
7 | params: {
8 | isFinished,
9 | },
10 | });
11 |
12 | return data;
13 | }
14 |
15 | async getCurrentSemester() {
16 | const { data } = await client.get(
17 | 'dates/current/semester',
18 | );
19 | return data;
20 | }
21 | }
22 | export default new DatesAPI();
23 |
--------------------------------------------------------------------------------
/src/lib/api/dates/types/GetCurrentSemester.ts:
--------------------------------------------------------------------------------
1 | import { Semester } from '@/types/dates';
2 |
3 | export interface GetCurrentSemester extends Semester {
4 | isFinished: boolean;
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/dates/types/GetDates.ts:
--------------------------------------------------------------------------------
1 | import { Semester } from '@/types/dates';
2 |
3 | export interface GetDates {
4 | semesters: Semester[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/AddStudentsByMailBody.ts:
--------------------------------------------------------------------------------
1 | export interface AddStudentsByMailBody {
2 | emails: string[];
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/AddStudentsByMailResponse.ts:
--------------------------------------------------------------------------------
1 | interface StudentEmail {
2 | id: string;
3 | email: string;
4 | }
5 |
6 | export interface AddStudentsByMailResponse {
7 | users: StudentEmail[];
8 | }
9 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/GetAllResponse.ts:
--------------------------------------------------------------------------------
1 | import { Group } from '@/types/group';
2 |
3 | export interface GetAllResponse {
4 | groups: Group[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/GetGroupDisciplines.ts:
--------------------------------------------------------------------------------
1 | import { Discipline } from '@/types/discipline';
2 |
3 | export interface GetGroupDisciplines {
4 | disciplines: Discipline[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/GetGroupStudentsResponse.ts:
--------------------------------------------------------------------------------
1 | import { GroupStudent } from '@/types/student';
2 |
3 | export interface GetGroupStudentResponse {
4 | students: GroupStudent[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/GetGroupTeachers.ts:
--------------------------------------------------------------------------------
1 | import { Teacher } from '@/types/teacher';
2 |
3 | export interface TeacherWithDisciplineId extends Omit {
4 | disciplineTeacherId: string;
5 | }
6 | export interface GetDisciplineWithTeachers {
7 | id: string;
8 | subject: {
9 | id: string;
10 | name: string;
11 | };
12 | year: number;
13 | semester: number;
14 | isSelective: boolean;
15 | teachers: TeacherWithDisciplineId[];
16 | }
17 |
18 | export type GetDisciplinesWithTeachers = GetDisciplineWithTeachers[];
19 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/GetPendingStudentsResponse.ts:
--------------------------------------------------------------------------------
1 | import { PendingStudent } from '@/types/student';
2 |
3 | export interface GetPendingStudentsResponse {
4 | students: PendingStudent[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/UpdateStudentRoleBody.ts:
--------------------------------------------------------------------------------
1 | import { UserGroupRole } from '@/types/user';
2 |
3 | export interface UpdateStudentRoleBody {
4 | roleName: Exclude;
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/group/types/VerifyStudentBody.ts:
--------------------------------------------------------------------------------
1 | import { UserGroupState } from '@/types/user';
2 |
3 | export interface VerifyStudentBody {
4 | state: UserGroupState;
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/instance.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const baseURL = process.browser
4 | ? process.env.NEXT_PUBLIC_API_BASE_URL
5 | : process.env.API_BASE_URL;
6 | export const client = axios.create({ baseURL });
7 |
--------------------------------------------------------------------------------
/src/lib/api/poll/types/CreateTeacherGradeBody.ts:
--------------------------------------------------------------------------------
1 | import { Answer } from '@/types/poll';
2 |
3 | export interface CreateTeacherGradeBody {
4 | answers: Answer[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/poll/types/GetTeacherQuestionsResponse.ts:
--------------------------------------------------------------------------------
1 | import { Category, PollTeacher } from '@/types/poll';
2 | import { TeacherSubject } from '@/types/teacher';
3 |
4 | export interface GetTeacherQuestionsResponse {
5 | teacher: PollTeacher;
6 | subject: TeacherSubject;
7 | categories: Category[];
8 | }
9 |
--------------------------------------------------------------------------------
/src/lib/api/poll/types/PollTeachersResponse.ts:
--------------------------------------------------------------------------------
1 | import { DisciplineTeacher } from '@/types/teacher';
2 |
3 | export interface PollTeachersResponse {
4 | teachers: DisciplineTeacher[];
5 | hasSelectedInLastSemester: boolean;
6 | }
7 |
--------------------------------------------------------------------------------
/src/lib/api/schedule/types/DetailedEventBody.ts:
--------------------------------------------------------------------------------
1 | import { Event, TDiscipline } from '@/types/schedule';
2 | import { TEventPeriod } from '@/types/schedule';
3 |
4 | export interface DetailedEventBody extends Omit {
5 | url?: string;
6 | eventInfo?: string;
7 | disciplineType: TDiscipline | string;
8 | disciplineInfo?: string;
9 | period: TEventPeriod | string;
10 | teachers: {
11 | id: string;
12 | firstName: string;
13 | middleName: string;
14 | lastName: string;
15 | }[];
16 | }
17 |
--------------------------------------------------------------------------------
/src/lib/api/schedule/types/GetEventBody.ts:
--------------------------------------------------------------------------------
1 | import { Event } from '@/types/schedule';
2 |
3 | export interface GetEventBody {
4 | startTime: string;
5 | week: string;
6 | events: Event[];
7 | }
8 |
9 | export interface EventDay {
10 | week: string;
11 | day: Date;
12 | events: (Event | Event[])[];
13 | }
14 | export interface GetEventTransformedBody {
15 | week: string;
16 | days: EventDay[];
17 | }
18 |
--------------------------------------------------------------------------------
/src/lib/api/schedule/types/PatchEventBody.ts:
--------------------------------------------------------------------------------
1 | import { SharedEventBody } from './shared';
2 |
3 | export interface PatchEventBody
4 | extends Partial> {
5 | week: number;
6 | changeStartDate: boolean;
7 | changeEndDate: boolean;
8 | disciplineType: string | null;
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/api/schedule/types/PostEventBody.ts:
--------------------------------------------------------------------------------
1 | import { SharedEventBody } from './shared';
2 |
3 | export interface PostEventBody extends Required {
4 | groupId: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/schedule/types/getDisciplinesAndTeachers.ts:
--------------------------------------------------------------------------------
1 | import { GetGroupDisciplines } from '@/lib/api/group/types/GetGroupDisciplines';
2 | import { GetTeachersResponse } from '@/lib/api/teacher/types/GetTeachersResponse';
3 | export interface getDisciplinesAndTeachers {
4 | disciplines: GetGroupDisciplines;
5 | teachers: GetTeachersResponse;
6 | }
7 |
--------------------------------------------------------------------------------
/src/lib/api/schedule/types/shared.ts:
--------------------------------------------------------------------------------
1 | import { DetailedEventBody } from '@/lib/api/schedule/types/DetailedEventBody';
2 |
3 | export interface SharedEventBody
4 | extends Omit {
5 | teachers: string[];
6 | disciplineId: string;
7 | }
8 |
--------------------------------------------------------------------------------
/src/lib/api/student-resources/StudentResourcesAPI.ts:
--------------------------------------------------------------------------------
1 | import { client } from '@/lib/api/instance';
2 | import { GetStudentResourcesResponse } from '@/lib/api/student-resources/types/GetStudentResourcesResponse';
3 |
4 | class StudentResourcesAPI {
5 | async getAll() {
6 | const { data } =
7 | await client.get('/studentResources');
8 | return data;
9 | }
10 | }
11 |
12 | export default new StudentResourcesAPI();
13 |
--------------------------------------------------------------------------------
/src/lib/api/student-resources/types/GetStudentResourcesResponse.ts:
--------------------------------------------------------------------------------
1 | export interface StudentResource {
2 | icon: string;
3 | id: string;
4 | name: string;
5 | link: string;
6 | }
7 |
8 | export interface GetStudentResourcesResponse {
9 | studentResources: StudentResource[];
10 | }
11 |
--------------------------------------------------------------------------------
/src/lib/api/subject/types/GetListOfSubjectsResponse.ts:
--------------------------------------------------------------------------------
1 | import { Meta } from '@/types/api';
2 | import { Subject } from '@/types/subject';
3 |
4 | export interface GetListOfSubjectsResponse {
5 | subjects: Subject[];
6 | meta?: Meta;
7 | }
8 |
--------------------------------------------------------------------------------
/src/lib/api/subject/types/GetTeachersBySubjectResponse.ts:
--------------------------------------------------------------------------------
1 | import { Teacher } from '@/types/teacher';
2 |
3 | export interface GetTeachersBySubjectResponse {
4 | subjectName: string;
5 | teachers: Teacher[];
6 | }
7 |
--------------------------------------------------------------------------------
/src/lib/api/teacher/types/GetTeacherCommentsResponse.ts:
--------------------------------------------------------------------------------
1 | import { TeacherQuestion } from '@/types/teacher';
2 |
3 | export interface GetTeacherCommentsResponse {
4 | questions: TeacherQuestion[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/teacher/types/GetTeacherDisciplinesResponse.ts:
--------------------------------------------------------------------------------
1 | import { TeacherDiscipline } from '@/types/teacher';
2 |
3 | export type GetTeacherDisciplinesResponse = TeacherDiscipline[];
4 |
--------------------------------------------------------------------------------
/src/lib/api/teacher/types/GetTeacherMarksResponse.ts:
--------------------------------------------------------------------------------
1 | import { TeacherAmountMark, TeacherRadarCircleMark } from '@/types/teacher';
2 |
3 | export interface GetTeacherMarksResponse {
4 | marks: (TeacherRadarCircleMark | TeacherAmountMark)[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/teacher/types/GetTeacherSubjectsResponse.ts:
--------------------------------------------------------------------------------
1 | import { TeacherSubject } from '@/types/teacher';
2 |
3 | export interface GetTeacherSubjectsResponse {
4 | subjects: TeacherSubject[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/teacher/types/GetTeachersResponse.ts:
--------------------------------------------------------------------------------
1 | import { Meta } from '@/types/api';
2 | import { Teacher } from '@/types/teacher';
3 |
4 | export interface GetTeachersResponse {
5 | teachers: Omit[];
6 | meta?: Meta;
7 | }
8 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/AddContactBody.ts:
--------------------------------------------------------------------------------
1 | import { Contact } from '@/types/contact';
2 |
3 | export type AddContactBody = Omit;
4 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/ChangeAvatarResponse.ts:
--------------------------------------------------------------------------------
1 | export interface ChangeAvatarResponse {
2 | id: string;
3 | email: string;
4 | username: string;
5 | telegramId: number;
6 | avatar: string;
7 | state: string;
8 | }
9 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/ChangeInfoBody.ts:
--------------------------------------------------------------------------------
1 | import { UserGroupState } from '@/types/user';
2 |
3 | export interface ChangeInfoBody {
4 | firstName?: string;
5 | lastName?: string;
6 | middleName?: string;
7 | groupId?: string;
8 | state?: UserGroupState;
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/ChangeRoleBody.ts:
--------------------------------------------------------------------------------
1 | export interface ChangeRoleBody {
2 | roleId: string;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/GetContactsResponse.ts:
--------------------------------------------------------------------------------
1 | import { Contact } from '@/types/contact';
2 |
3 | export interface GetContactsResponse {
4 | contacts: Contact[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/GetSelectiveDisciplinesBySemesterResponse.ts:
--------------------------------------------------------------------------------
1 | import { UserSelective } from '@/types/user';
2 |
3 | export interface GetSelectiveDisciplinesBySemesterResponse {
4 | selective: UserSelective[];
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/GetSelectiveDisciplinesResponse.ts:
--------------------------------------------------------------------------------
1 | import { UserRemainingSelective } from '@/types/user';
2 |
3 | export interface GetSelectiveDisciplinesResponse {
4 | availableSelectiveAmount: number;
5 | year: number;
6 | semester: 1 | 2;
7 | remainingSelective: UserRemainingSelective[];
8 | }
9 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/GetSelectiveResponse.ts:
--------------------------------------------------------------------------------
1 | export interface GetSelectiveResponse {
2 | disciplines: string[];
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/PostSelectiveDisciplinesBody.ts:
--------------------------------------------------------------------------------
1 | export interface PostSelectiveDisciplinesBody {
2 | disciplines: string[];
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/PostSuperheroBody.ts:
--------------------------------------------------------------------------------
1 | export interface PostSuperheroBody {
2 | dorm: boolean;
3 | }
4 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/RequestNewGroupBody.ts:
--------------------------------------------------------------------------------
1 | export interface RequestNewGroupBody {
2 | groupId: string;
3 | isCaptain: boolean;
4 | }
5 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/VerifyStudentBody.ts:
--------------------------------------------------------------------------------
1 | import { UserGroupState } from '@/types/user';
2 |
3 | export interface VerifyStudentBody {
4 | state: UserGroupState;
5 | isCaptain: boolean;
6 | }
7 |
--------------------------------------------------------------------------------
/src/lib/api/user/types/VerifySuperheroBody.ts:
--------------------------------------------------------------------------------
1 | import { UserGroupState } from '@/types/user';
2 |
3 | export interface VerifySuperheroBody {
4 | dorm: boolean;
5 | state: UserGroupState;
6 | }
7 |
--------------------------------------------------------------------------------
/src/lib/api/utils.ts:
--------------------------------------------------------------------------------
1 | import StorageUtil from '@/lib/utils/StorageUtil';
2 |
3 | export const getAuthorizationHeader = () => {
4 | return {
5 | headers: { Authorization: `Bearer ${StorageUtil.getAccessToken()}` },
6 | };
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/services/auth/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './AuthService';
2 |
--------------------------------------------------------------------------------
/src/lib/services/permisson/PermissionService.ts:
--------------------------------------------------------------------------------
1 | import TeacherAPI from '@/lib/api/teacher/TeacherAPI';
2 |
3 | import { PERMISSION } from './types';
4 |
5 | const MIN_MARKS_LENGTH = 8;
6 |
7 | class PermissionService {
8 | async getPermisson(
9 | permissions: PERMISSION[],
10 | userId: string | undefined,
11 | groupId: string | undefined,
12 | $roleId: string | undefined,
13 | $teacherId: string | undefined,
14 | ): Promise {
15 | const hasPermission = true;
16 | return hasPermission;
17 | }
18 | }
19 |
20 | export default new PermissionService();
21 |
--------------------------------------------------------------------------------
/src/lib/services/teacher/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TeacherService';
2 |
--------------------------------------------------------------------------------
/src/lib/services/telegram/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './TelegramService';
2 |
--------------------------------------------------------------------------------
/src/lib/utils/MergeSxStylesUtil.ts:
--------------------------------------------------------------------------------
1 | import { SxProps, Theme } from '@mui/material/styles';
2 |
3 | const mergeSx = (...sxProps: SxProps[]): SxProps => {
4 | return sxProps
5 | .filter(value => value)
6 | .reduce((prev, currentValue) => {
7 | return [
8 | ...(Array.isArray(prev) ? prev : [prev]),
9 | ...(Array.isArray(currentValue) ? currentValue : [currentValue]),
10 | ];
11 | }, [] as SxProps);
12 | };
13 |
14 | export default mergeSx;
15 |
--------------------------------------------------------------------------------
/src/lib/utils/getErrorMessage.ts:
--------------------------------------------------------------------------------
1 | import { isAxiosError } from 'axios';
2 |
3 | const getErrorMessage = (error: unknown) => {
4 | let message = '';
5 | if (isAxiosError(error)) {
6 | if (error.response?.data.message) {
7 | message = error.response.data.message;
8 | } else if (error.response?.data.messages) {
9 | message = error.response.data.messages.join(', ');
10 | }
11 | }
12 | return message;
13 | };
14 | export default getErrorMessage;
15 |
--------------------------------------------------------------------------------
/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout';
4 | import NotFoundPage from '@/components/pages/404-page';
5 |
6 | const NotFound: FC = () => {
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | export default NotFound;
15 |
--------------------------------------------------------------------------------
/src/pages/about.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import AboutPage from '@/components/pages/about-page';
3 |
4 | const About = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default About;
11 |
--------------------------------------------------------------------------------
/src/pages/account.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import AccountPage from '@/components/pages/account-page';
3 |
4 | const Account = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default Account;
11 |
--------------------------------------------------------------------------------
/src/pages/admin/departments/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/departments/edit/[departmentId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const DepartmentId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default DepartmentId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/departments/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/disciplines/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/disciplines/edit/[disciplineId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const DisciplineId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default DisciplineId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/disciplines/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/groups/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/groups/edit/[groupId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const GroupId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default GroupId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/groups/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 | import AdminMainPage from '@/components/pages/admin/admin-default/AdminMainPage';
5 |
6 | const AdminMain = () => {
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | export default AdminMain;
15 |
--------------------------------------------------------------------------------
/src/pages/admin/rights/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/rights/edit/[rightId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const RightId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default RightId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/rights/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/roles/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/roles/edit/[roleId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const RoleId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default RoleId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/roles/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/students/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/students/edit/[studentId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const StudentId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default StudentId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/students/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/subjects/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/subjects/edit/[subjectId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const SubjectId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default SubjectId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/subjects/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/teachers/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/teachers/edit/[teacherId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const TeacherId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default TeacherId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/teachers/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/users/create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Create = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Create;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/users/edit/[userId].tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const UserId = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default UserId;
14 |
--------------------------------------------------------------------------------
/src/pages/admin/users/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AdminPanelLayout from '@/components/common/layout/admin-panel-layout/AdminPanelLayout';
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Index;
14 |
--------------------------------------------------------------------------------
/src/pages/contract-admin.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import ContractAdminPage from '@/components/pages/contract-admin-page/ContractAdminPage';
3 |
4 | const ContractAdminSubmission = () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
12 | export default ContractAdminSubmission;
13 |
--------------------------------------------------------------------------------
/src/pages/contract/index.tsx:
--------------------------------------------------------------------------------
1 | import ContractPage from '@/components/pages/contract-page';
2 | export default ContractPage;
3 |
--------------------------------------------------------------------------------
/src/pages/discipline.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import PersonalTeacherSubjectPage from '@/components/pages/personal-teacher-subject-page';
3 |
4 | const PersonalTeacherSubject = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default PersonalTeacherSubject;
11 |
--------------------------------------------------------------------------------
/src/pages/entrant-admin.tsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout';
4 | import EntrantAdminPage from '@/components/pages/entrant-admin-page';
5 | import useAuthentication from '@/hooks/use-authentication';
6 | const EntrantAdmin = () => {
7 | const { isLoggedIn } = useAuthentication();
8 | const router = useRouter();
9 |
10 | if (!isLoggedIn) router.push('/login');
11 | return (
12 |
13 |
14 |
15 | );
16 | };
17 |
18 | export default EntrantAdmin;
19 |
--------------------------------------------------------------------------------
/src/pages/entrant-dashboard.tsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/router';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout';
4 | import EntrantDashboardPage from '@/components/pages/entrant-dashboard-page';
5 | import useAuthentication from '@/hooks/use-authentication';
6 | const DeleteEntrantAdmin = () => {
7 | const { isLoggedIn } = useAuthentication();
8 | const router = useRouter();
9 |
10 | if (!isLoggedIn) router.push('/login');
11 | return (
12 |
13 |
14 |
15 | );
16 | };
17 |
18 | export default DeleteEntrantAdmin;
19 |
--------------------------------------------------------------------------------
/src/pages/login.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout';
4 | import LoginPage from '@/components/pages/login-page';
5 |
6 | const Login: FC = () => {
7 | return (
8 |
14 |
15 |
16 | );
17 | };
18 |
19 | export default Login;
20 |
--------------------------------------------------------------------------------
/src/pages/password-recovery/[token].tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import CreatePasswordPage from '@/components/pages/password-recovery/create-password-page/CreatePasswordPage';
3 |
4 | const CreatePassword = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default CreatePassword;
11 |
--------------------------------------------------------------------------------
/src/pages/password-recovery/email-verification.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import PasswordResetEmailConfirmationPage from '@/components/pages/password-recovery/email-confirmation-page';
3 |
4 | const PasswordResetEmailConfirmation = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default PasswordResetEmailConfirmation;
11 |
--------------------------------------------------------------------------------
/src/pages/password-recovery/index.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import ForgotPasswordPage from '@/components/pages/password-recovery/forgot-password-page/ForgotPasswordPage';
3 |
4 | const ForgotPassword = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default ForgotPassword;
11 |
--------------------------------------------------------------------------------
/src/pages/password-recovery/invalid.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import PasswordResetLinkExpiredPage from '@/components/pages/password-recovery/link-expired';
3 |
4 | const PasswordResetLinkExpired = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default PasswordResetLinkExpired;
11 |
--------------------------------------------------------------------------------
/src/pages/password-recovery/valid.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import PasswordResetValidLinkPage from '@/components/pages/password-recovery/link-valid';
3 |
4 | const PasswordResetValidLink = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default PasswordResetValidLink;
11 |
--------------------------------------------------------------------------------
/src/pages/poll/[disciplineTeacherId].tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout/PageLayout';
4 | import PollPage from '@/components/pages/poll-page';
5 |
6 | const Poll: FC = () => {
7 | return (
8 |
12 |
13 |
14 | );
15 | };
16 |
17 | export default Poll;
18 |
--------------------------------------------------------------------------------
/src/pages/poll/index.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import PollTeacherPage from '@/components/pages/search-pages/poll-teachers-page';
3 | const PollTeacher = () => (
4 |
5 |
6 |
7 | );
8 | export default PollTeacher;
9 |
--------------------------------------------------------------------------------
/src/pages/priority-approve.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout';
4 | import EntrantPriorityPage from '@/components/pages/priority-approve-page';
5 |
6 | const PriorityApprove = () => {
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | export default PriorityApprove;
15 |
--------------------------------------------------------------------------------
/src/pages/privacy.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout';
4 | import PrivacyPage from '@/components/pages/privacy-page';
5 |
6 | const Privacy: FC = () => {
7 | return (
8 |
12 |
13 |
14 | );
15 | };
16 |
17 | export default Privacy;
18 |
--------------------------------------------------------------------------------
/src/pages/register/email-verification/[token].tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import VerifyEmailTokenPage from '@/components/pages/register/verify-email-token-page';
3 |
4 | const VerifyEmailToken = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default VerifyEmailToken;
11 |
--------------------------------------------------------------------------------
/src/pages/register/email-verification/index.tsx:
--------------------------------------------------------------------------------
1 | import PageLayout from '@/components/common/layout/page-layout';
2 | import RegistrationEmailConfirmationPage from '@/components/pages/register/email-confirmation-page';
3 |
4 | const RegistrationEmailConfirmation = () => (
5 |
6 |
7 |
8 | );
9 |
10 | export default RegistrationEmailConfirmation;
11 |
--------------------------------------------------------------------------------
/src/pages/subjects/[subjectId]/teachers.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout/PageLayout';
4 | import SubjectTeacherPage from '@/components/pages/search-pages/subject-teacher-search';
5 |
6 | const SubjectPage: FC = () => {
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | export default SubjectPage;
15 |
--------------------------------------------------------------------------------
/src/pages/teachers/index.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import PageLayout from '@/components/common/layout/page-layout/PageLayout';
4 | import TeacherSearchPage from '@/components/pages/search-pages/teacher-search';
5 |
6 | const TeacherPage: FC = () => {
7 | return (
8 |
12 |
13 |
14 | );
15 | };
16 |
17 | export default TeacherPage;
18 |
--------------------------------------------------------------------------------
/src/store/schedule/utils/findFirstOf5.ts:
--------------------------------------------------------------------------------
1 | export const findFirstOf5 = (week: number) => {
2 | const rem = week % 5 === 0 ? 5 : week % 5;
3 | return week - rem + 1;
4 | };
5 |
--------------------------------------------------------------------------------
/src/store/schedule/utils/getCurrentWeek.ts:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs';
2 |
3 | import { GetCurrentSemester } from '@/lib/api/dates/types/GetCurrentSemester';
4 | export const getCurrentWeek = (semester: GetCurrentSemester) => {
5 | const startDateMs = dayjs(semester.startDate).tz().valueOf();
6 | const nowDateMs = dayjs().tz().valueOf();
7 |
8 | const weekFloating = (nowDateMs - startDateMs) / (1000 * 60 * 60 * 24 * 7);
9 |
10 | return Math.ceil(weekFloating);
11 | };
12 |
--------------------------------------------------------------------------------
/src/store/schedule/utils/getFirstDayOfAWeek.ts:
--------------------------------------------------------------------------------
1 | import dayjs, { Dayjs } from 'dayjs';
2 | const HourMs = 1000 * 60 * 60;
3 | const DayMs = HourMs * 24;
4 | const WeekMs = DayMs * 7;
5 |
6 | import { GetCurrentSemester } from '@/lib/api/dates/types/GetCurrentSemester';
7 |
8 | export const getFirstDayOfAWeek = (
9 | semester: GetCurrentSemester,
10 | week: number,
11 | ): Dayjs => {
12 | const startDateMs = dayjs(semester.startDate).tz().valueOf();
13 | return dayjs(startDateMs + WeekMs * week - DayMs * 7 + HourMs).tz();
14 | };
15 |
--------------------------------------------------------------------------------
/src/store/schedule/utils/getWeekByDate.ts:
--------------------------------------------------------------------------------
1 | import dayjs, { Dayjs } from 'dayjs';
2 |
3 | import { GetCurrentSemester } from '@/lib/api/dates/types/GetCurrentSemester';
4 | const WeekMs = 1000 * 60 * 60 * 24 * 7;
5 | export const getWeekByDate = (
6 | semester: GetCurrentSemester,
7 | date: Dayjs,
8 | ): number => {
9 | const startTimeMs = dayjs(semester.startDate).tz().valueOf();
10 | const thisDateMs = date.tz().valueOf();
11 |
12 | const delta = thisDateMs - startTimeMs;
13 | const decimalWeek = delta / WeekMs;
14 |
15 | return Math.ceil(decimalWeek % 1 === 0 ? decimalWeek + 1 : decimalWeek);
16 | };
17 |
--------------------------------------------------------------------------------
/src/store/schedule/utils/setUrlParams.ts:
--------------------------------------------------------------------------------
1 | export const setUrlParams = (param: string, value: string) => {
2 | const url = new URL(window.location.href);
3 |
4 | const params = new URLSearchParams(url.search);
5 |
6 | params.set(param, value);
7 |
8 | url.search = params.toString();
9 |
10 | window.history.replaceState(null, '', url.toString());
11 | };
12 |
--------------------------------------------------------------------------------
/src/styles/partials/_breakpoints.scss:
--------------------------------------------------------------------------------
1 | $breakpoint-mobile: 375px;
2 | $breakpoint-mobile-medium: 480px;
3 | $breakpoint-tablet: 768px;
4 | $breakpoint-desktop: 1024px;
5 | $breakpoint-desktop-semi-medium: 1200px;
6 | $breakpoint-desktop-medium: 1440px;
7 | $breakpoint-desktop-large: 1920px;
--------------------------------------------------------------------------------
/src/styles/partials/_utils.scss:
--------------------------------------------------------------------------------
1 | @mixin flex-center {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/src/styles/theme/constants/breakpoints/breakpoints.ts:
--------------------------------------------------------------------------------
1 | import { BreakpointsOptions } from '@mui/system';
2 |
3 | const breakpoints: BreakpointsOptions = {
4 | values: {
5 | mobile: 0,
6 | mobileSemiMedium: 375,
7 | mobileMedium: 480,
8 | tablet: 768,
9 | desktop: 1024,
10 | desktopSemiMedium: 1200,
11 | desktopMedium: 1440,
12 | desktopSemiLarge: 1600,
13 | desktopLarge: 1920,
14 | },
15 | };
16 |
17 | export default breakpoints;
18 |
--------------------------------------------------------------------------------
/src/styles/theme/constants/breakpoints/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './breakpoints';
2 |
--------------------------------------------------------------------------------
/src/styles/theme/constants/breakpoints/interfaces.ts:
--------------------------------------------------------------------------------
1 | import '@mui/material/styles';
2 |
3 | declare module '@mui/material/styles' {
4 | interface BreakpointOverrides {
5 | xs: false;
6 | sm: false;
7 | md: false;
8 | lg: false;
9 | xl: false;
10 | mobile: true;
11 | mobileSemiMedium: true;
12 | mobileMedium: true;
13 | tablet: true;
14 | desktop: true;
15 | desktopSemiMedium: true;
16 | desktopMedium: true;
17 | desktopSemiLarge: true;
18 | desktopLarge: true;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/styles/theme/constants/pallete/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './palette';
2 |
--------------------------------------------------------------------------------
/src/styles/theme/constants/typography/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './typography';
2 |
--------------------------------------------------------------------------------
/src/styles/theme/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './theme';
2 |
--------------------------------------------------------------------------------
/src/styles/theme/theme.ts:
--------------------------------------------------------------------------------
1 | import { ukUA as MaterialLocale } from '@mui/material/locale';
2 | import { createTheme } from '@mui/material/styles';
3 | import { ukUA as DatePickerLocale } from '@mui/x-date-pickers';
4 |
5 | import customBreakpoints from '@/styles/theme/constants/breakpoints';
6 | import customPalette from '@/styles/theme/constants/pallete';
7 | import customTypography from '@/styles/theme/constants/typography';
8 |
9 | const theme = createTheme(
10 | {
11 | palette: customPalette,
12 | typography: customTypography,
13 | breakpoints: customBreakpoints,
14 | },
15 | MaterialLocale,
16 | DatePickerLocale,
17 | );
18 |
19 | export default theme;
20 |
--------------------------------------------------------------------------------
/src/types/api.ts:
--------------------------------------------------------------------------------
1 | export interface Meta {
2 | pageSize: number;
3 | page: number;
4 | prevPageElems: number;
5 | nextPageElems: number;
6 | }
7 |
--------------------------------------------------------------------------------
/src/types/contact.ts:
--------------------------------------------------------------------------------
1 | export enum ContactType {
2 | YOUTUBE = 'YOUTUBE',
3 | DISCORD = 'DISCORD',
4 | TELEGRAM = 'TELEGRAM',
5 | INSTAGRAM = 'INSTAGRAM',
6 | FACEBOOK = 'FACEBOOK',
7 | GITHUB = 'GITHUB',
8 | TWITTER = 'TWITTER',
9 | MAIL = 'MAIL',
10 | }
11 |
12 | export interface Contact {
13 | link: string;
14 | id: string;
15 | name: ContactType;
16 | displayName: string;
17 | }
18 |
--------------------------------------------------------------------------------
/src/types/dates.ts:
--------------------------------------------------------------------------------
1 | export interface Semester {
2 | year: string;
3 | semester: string;
4 | startDate: string;
5 | endDate: string;
6 | }
7 |
--------------------------------------------------------------------------------
/src/types/discipline.ts:
--------------------------------------------------------------------------------
1 | export interface Discipline {
2 | id: string;
3 | year: number;
4 | isSelective: boolean;
5 | semester: number;
6 | subject: {
7 | id: string;
8 | name: string;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/src/types/group.ts:
--------------------------------------------------------------------------------
1 | export interface Group {
2 | id: string;
3 | code: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/types/schedule.ts:
--------------------------------------------------------------------------------
1 | export enum TDiscipline {
2 | LECTURE = 'LECTURE',
3 | PRACTICE = 'PRACTICE',
4 | LABORATORY = 'LABORATORY',
5 | CONSULTATION = 'CONSULTATION',
6 | WORKOUT = 'WORKOUT',
7 | EXAM = 'EXAM',
8 | }
9 |
10 | export interface Event {
11 | id: string;
12 | name: string;
13 | startTime: string;
14 | endTime: string;
15 | disciplineType: {
16 | id: string;
17 | disciplineId: string;
18 | name: TDiscipline;
19 | } | null;
20 | }
21 |
22 | export enum TEventPeriod {
23 | NO_PERIOD = 'NO_PERIOD',
24 | EVERY_WEEK = 'EVERY_WEEK',
25 | EVERY_FORTNIGHT = 'EVERY_FORTNIGHT',
26 | }
27 |
--------------------------------------------------------------------------------
/src/types/storage.ts:
--------------------------------------------------------------------------------
1 | export enum STORAGE_KEYS {
2 | ACCESS_TOKEN = 'ACCESS_TOKEN',
3 | REFRESH_TOKEN = 'REFRESH_TOKEN',
4 | TELEGRAM_INFO = 'TELEGRAM_INFO',
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/student.ts:
--------------------------------------------------------------------------------
1 | import { User, UserGroupRole } from '@/types/user';
2 |
3 | export interface PendingStudent extends Omit {
4 | group: {
5 | id: string;
6 | code: string;
7 | };
8 | }
9 |
10 | export interface GroupStudent extends Omit {
11 | group: {
12 | id: string;
13 | code: string;
14 | role: UserGroupRole;
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/src/types/subject.ts:
--------------------------------------------------------------------------------
1 | export interface Subject {
2 | id: string;
3 | name: string;
4 | amount: number;
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/telegram.ts:
--------------------------------------------------------------------------------
1 | export interface TelegramUser {
2 | auth_date: number;
3 | first_name: string;
4 | hash: string;
5 | id: number;
6 | last_name: string;
7 | photo_url: string;
8 | username: string;
9 | }
10 |
--------------------------------------------------------------------------------
/src/types/tokens.ts:
--------------------------------------------------------------------------------
1 | export interface Tokens {
2 | accessToken: string;
3 | refreshToken: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/types/utils/PartialBy.ts:
--------------------------------------------------------------------------------
1 | export type PartialBy = Omit & Partial>;
2 |
--------------------------------------------------------------------------------