├── .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 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/icons/schedule-line.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /public/icons/schedule-page/grid-pattern.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /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 | 9 | 16 | 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 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/pages/schedule-page/schedule-event-edit-section/schedule-form/icons/End.tsx: -------------------------------------------------------------------------------- 1 | export const End = () => { 2 | return ( 3 | 10 | 17 | 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 | --------------------------------------------------------------------------------