├── .dockerignore ├── src ├── pages │ ├── Regions │ │ ├── Modal.module.css │ │ ├── ActionRegion.module.css │ │ ├── RegionDetailDrawer.less │ │ ├── CheckActiveCitiesForm.less │ │ ├── AddRegionSecretaryForm.less │ │ ├── Form.module copy.css │ │ ├── AddDocumentModal.less │ │ └── Form.module.css │ ├── City │ │ ├── City │ │ │ ├── Modal.module.css │ │ │ ├── CheckActiveMembersForm.less │ │ │ └── Form.module.css │ │ ├── Cities │ │ │ └── ActionCities.module.css │ │ ├── CityDetailDrawer │ │ │ └── CityDetailDrawer.less │ │ ├── AddAdministratorModal │ │ │ ├── AddCitiesSecretaryForm.less │ │ │ └── AddAdministrationModal.less │ │ └── AddDocumentModal │ │ │ └── AddDocumentModal.less │ ├── Club │ │ ├── Club │ │ │ ├── Modal.module.css │ │ │ ├── CheckActiveMembersForm.less │ │ │ └── Form.module.css │ │ ├── Clubs │ │ │ └── ActionClubs.module.css │ │ ├── ClubDetailDrawer │ │ │ └── ClubDetailDrawer.less │ │ ├── AddAdministratorModal │ │ │ ├── AddClubsSecretaryForm.less │ │ │ └── AddAdministrationModal.less │ │ └── AddDocumentModal │ │ │ └── AddDocumentModal.less │ ├── DecisionTable │ │ ├── FormEditDecision.module.css │ │ ├── Interfaces │ │ │ └── DecisionTableInfo.tsx │ │ ├── FormAddDecision.module.css │ │ ├── DeleteConfirm.tsx │ │ └── EditDecisionModal.tsx │ ├── Interfaces │ │ └── SwitcherProps.ts │ ├── AnnualReport │ │ ├── Interfaces │ │ │ ├── Club.ts │ │ │ ├── Region.ts │ │ │ ├── User.ts │ │ │ ├── City.ts │ │ │ ├── RegionAnnualReportQuestions.ts │ │ │ ├── MembersStatistic.ts │ │ │ ├── ClubAnnualReport.ts │ │ │ ├── AnnualReport.ts │ │ │ └── RegionMembersInfo.tsx │ │ ├── AnnualReportTable │ │ │ ├── TableStyles.module.css │ │ │ ├── ClubSelectModal │ │ │ │ └── ClubSelectModal.less │ │ │ ├── Dropdowns │ │ │ │ ├── Dropdown.module.css │ │ │ │ ├── SavedDropdown │ │ │ │ │ └── SavedDropdownProps.tsx │ │ │ │ ├── ConfirmedDropdown │ │ │ │ │ └── ConfirmedDropdownProps.tsx │ │ │ │ └── UnconfirmedDropdown │ │ │ │ │ └── UnconfirmedDropdownProps.tsx │ │ │ ├── CitySelectModal │ │ │ │ └── CitySelectModal.less │ │ │ ├── DropdownsForRegionReports │ │ │ │ ├── Dropdown.module.css │ │ │ │ ├── ConfirmedDropdown │ │ │ │ │ └── ConfirmedRegionDropdownProps.tsx │ │ │ │ ├── SavedDropdown │ │ │ │ │ └── SavedRegionDropdownProps.tsx │ │ │ │ └── UnconfirmedDropdown │ │ │ │ │ └── UnconfirmedRegionDropdownProps.tsx │ │ │ ├── DropdownsForClubAnnualReports │ │ │ │ ├── Dropdown.module.css │ │ │ │ ├── SavedDropdown │ │ │ │ │ └── SavedDropdownProps.tsx │ │ │ │ ├── ConfirmedDropdown │ │ │ │ │ └── ConfirmedDropdownProps.tsx │ │ │ │ └── UnconfirmedDropdown │ │ │ │ │ └── UnconfirmedDropdownProps.tsx │ │ │ ├── RegionSelectModal │ │ │ │ └── RegionSelectModal.less │ │ │ ├── Form.module.css │ │ │ ├── ClubAnnualReportInformation │ │ │ │ └── ClubAnnualReportInformation.less │ │ │ └── AnnualReportInformation │ │ │ │ └── AnnualReportInformation.less │ │ ├── RegionAnnualReportForm │ │ │ └── RegionAnnualReportFormProps.tsx │ │ ├── AnnualReportForm │ │ │ ├── AnnualReportFormProps.tsx │ │ │ └── AnnualReportForm.less │ │ ├── AnnualReportEdit │ │ │ └── AnnualReportEdit.less │ │ ├── AnnualReportCreate │ │ │ └── AnnualReportCreate.less │ │ ├── RegionAnnualReportCreateEditView │ │ │ └── RegionAnnualReportCreate.less │ │ ├── ClubAnnualReportEdit │ │ │ └── ClubAnnualReportEdit.less │ │ ├── ClubAnnualReportForm │ │ │ └── ClubAnnualReportForm.less │ │ ├── ClubAnnualReportCreate │ │ │ └── ClubAnnualReportCreate.less │ │ ├── columnsClubsMembers.tsx │ │ ├── AnnualReportMenu.less │ │ └── ClubMembersTable.tsx │ ├── GoverningBody │ │ ├── GoverningBody │ │ │ └── GoverningBodyAdministration.module.css │ │ ├── AddAdministratorModal │ │ │ └── AddAdministrationModal.less │ │ ├── Announcement │ │ │ ├── Form.module.css │ │ │ ├── DeleteConfirm.tsx │ │ │ └── AddAnnouncementModal.tsx │ │ ├── Sector │ │ │ ├── SectorAnnouncement │ │ │ │ ├── Form.module.css │ │ │ │ └── DeleteConfirm.tsx │ │ │ └── SectorAdminTypes.ts │ │ ├── AddDocumentModal │ │ │ └── AddDocumentModal.less │ │ └── GoverningBodyAdminTypes.ts │ ├── Statistics │ │ └── Interfaces │ │ │ ├── Region.tsx │ │ │ ├── City.tsx │ │ │ ├── YearStatistics.tsx │ │ │ ├── StatisticsItem.tsx │ │ │ ├── RegionStatistics.tsx │ │ │ ├── CityStatistics.tsx │ │ │ ├── DataFromResponse.tsx │ │ │ ├── CitiesStatisticsParameters.tsx │ │ │ ├── RegionsStatisticsParameters.tsx │ │ │ └── StatisticsItemIndicator.tsx │ ├── UserTable │ │ ├── Interfaces │ │ │ ├── Degree.tsx │ │ │ └── TableFilterParameters.tsx │ │ ├── DeleteCityFollowerModal.less │ │ ├── ChangeUserRoleModal.less │ │ ├── Filter.less │ │ ├── UserComment.less │ │ ├── AcceptUserToCityModal.tsx │ │ ├── DeleteGoverningBodyAdminModal.tsx │ │ ├── ChangeUserGoverningBodyModal.tsx │ │ └── ChangeUserRoleModal.tsx │ ├── Precaution │ │ ├── Interfaces │ │ │ ├── Precaution.ts │ │ │ ├── SuggestedUser.ts │ │ │ ├── PrecautionUser.ts │ │ │ ├── UserPrecauctionsTableInfo.ts │ │ │ ├── UserPrecautionAdd.ts │ │ │ ├── UserPrecautionEdit.ts │ │ │ ├── UserPrecautionTableItem.ts │ │ │ ├── UserPrecaution.ts │ │ │ ├── UserPrecautionStatus.ts │ │ │ └── DropDownPrecautionTableProps.ts │ │ └── PrecautionTable │ │ │ ├── Filter.less │ │ │ ├── Form.module.css │ │ │ ├── DeleteTypeConfirm.tsx │ │ │ ├── DeleteConfirm.tsx │ │ │ ├── EditPrecautionModal.tsx │ │ │ ├── AddPrecautionModal.tsx │ │ │ └── FormEdit.module.css │ ├── UserRenewal │ │ ├── Types │ │ │ ├── CityForRenewal.ts │ │ │ ├── UserRenewal.ts │ │ │ ├── DropDownProps.ts │ │ │ └── UserRenewalTableData.ts │ │ └── UserRenewalTable │ │ │ └── Filter.less │ ├── userPage │ │ ├── Blanks │ │ │ ├── Blank.less │ │ │ └── UserAchievements │ │ │ │ └── ListOfAchievements.module.css │ │ ├── Secretaries │ │ │ ├── SectorModelForTable.ts │ │ │ ├── SecretaryModelForTable.ts │ │ │ ├── SecretaryModel.tsx │ │ │ └── columnsSectors.tsx │ │ ├── EditUserPage │ │ │ ├── EditUserPage.less │ │ │ └── Services.tsx │ │ ├── Menu │ │ │ └── Menu.less │ │ ├── ActiveMembership │ │ │ ├── PlastDegree │ │ │ │ ├── FormAddPlastDegree.module.css │ │ │ │ └── DeleteDegreeConfirm.tsx │ │ │ └── UserDates │ │ │ │ ├── ModalChangeUserDates.module.css │ │ │ │ └── columnsFormerUser.tsx │ │ └── Approvers │ │ │ └── DeleteApproveButton.tsx │ ├── Actions │ │ ├── ActionEvent │ │ │ ├── EventInfo │ │ │ │ ├── EventInfo.module.css │ │ │ │ ├── ParticipantsTable.less │ │ │ │ ├── EventDetailsHeader.less │ │ │ │ └── GalleryPictureAdd.tsx │ │ │ ├── EventCard │ │ │ │ └── EventCard.module.css │ │ │ ├── ActionEvent.module.css │ │ │ ├── EventCategoriesEdit │ │ │ │ └── EventCategoriesEditFormValidators.ts │ │ │ └── EventEdit │ │ │ │ └── EventEditDrawer.tsx │ │ ├── EventTypes │ │ │ ├── EventTypeCard.module.css │ │ │ ├── EventTypes.module.css │ │ │ └── EventTypeCard.tsx │ │ └── Actions.module.css │ ├── Distinction │ │ ├── Interfaces │ │ │ ├── User.tsx │ │ │ ├── UserDistinctionEdit.tsx │ │ │ └── UserDistinctionTableInfo.tsx │ │ └── DistinctionTable │ │ │ ├── DeleteConfirm.tsx │ │ │ ├── FormEditDistinctionTypes │ │ │ ├── DistinctionTypeInputValidator.tsx │ │ │ └── DeleteTypeConfirm.tsx │ │ │ ├── EditDistinctionModal.tsx │ │ │ ├── AddDistinctionModal.tsx │ │ │ ├── EditDistinctionTypesModal.tsx │ │ │ ├── Form.module.css │ │ │ └── FormEdit.module.css │ ├── KadraVykhovnykiv │ │ ├── Interfaces │ │ │ ├── KadraTableSettings.ts │ │ │ └── KadraTableInfo.tsx │ │ ├── Types │ │ │ └── EducatorsStaffTableData.ts │ │ ├── Form.module.css │ │ └── DeleteConfirm.tsx │ ├── ActionCard │ │ └── ActionCard.module.css │ ├── Spinner │ │ ├── Spinner.less │ │ └── Spinner.tsx │ ├── SignIn │ │ ├── SignIn.less │ │ ├── FacebookDataInterface.tsx │ │ ├── FacebookLoginWrapper.tsx │ │ └── GoogleLoginWrapper.tsx │ ├── Error │ │ ├── NotAuthorized.tsx │ │ ├── NotFound.tsx │ │ └── Errors.module.css │ ├── AnnouncementsTable │ │ ├── Forms │ │ │ └── Form.module.css │ │ └── Modals │ │ │ ├── AddAnnouncementModal.tsx │ │ │ └── EditAnnouncementModal.tsx │ ├── Documents │ │ ├── DeleteConfirm.tsx │ │ └── AddDocumetsModal.tsx │ ├── AboutBase │ │ ├── DeleteSubsectConfirm.tsx │ │ ├── TextEditor.css │ │ ├── DeleteSectConfirm.tsx │ │ ├── AskQuestionModal.tsx │ │ └── AddSubsectionModal.tsx │ ├── RegionsBoard │ │ └── AddMainAdministratorModal │ │ │ └── AddRegionBoardMainAdminModal.tsx │ ├── Contacts │ │ └── Contacts.module.css │ ├── SignUp │ │ ├── CheckboxsItem.tsx │ │ └── TabList.tsx │ └── WebChat │ │ └── Demo.js ├── react-app-env.d.ts ├── config.ts ├── models │ ├── AnnualReport │ │ ├── ReportType.ts │ │ └── ReportStatus.ts │ ├── Documents │ │ ├── MethodicDocumentType.tsx │ │ ├── DocumentWraper.tsx │ │ ├── Document.tsx │ │ ├── DocumentOnCreateData.tsx │ │ ├── DocumentPost.tsx │ │ └── DocumentsTableInfo.tsx │ ├── EventEdit │ │ ├── Pysar.tsx │ │ ├── Alternate.tsx │ │ ├── Commandant.tsx │ │ ├── Bunchuzhnyi.tsx │ │ ├── EventEdit.tsx │ │ └── Event.tsx │ ├── Events │ │ ├── EventGallery.ts │ │ ├── EventAdmin.ts │ │ ├── EventParticipant.ts │ │ ├── EventDetails.ts │ │ └── EventInformation.ts │ ├── Region │ │ ├── ActiveRegion.tsx │ │ ├── RegionForAdmin.tsx │ │ ├── RegionForAdministration.tsx │ │ ├── RegionDocument.tsx │ │ ├── RegionUser.tsx │ │ ├── RegionFollower.tsx │ │ ├── RegionAdmin.tsx │ │ └── RegionProfile.tsx │ ├── PDF │ │ └── fonts.tsx │ ├── City │ │ ├── CityForAdmin.tsx │ │ ├── CityDocumentType.tsx │ │ ├── CityUser.tsx │ │ ├── CityMember.tsx │ │ ├── CityDocument.tsx │ │ ├── CityAdmin.tsx │ │ └── CityProfile.tsx │ ├── Club │ │ ├── ClubForAdmin.tsx │ │ ├── ClubDocumentType.tsx │ │ ├── ClubByPage.tsx │ │ ├── Club.tsx │ │ ├── ClubMember.tsx │ │ ├── ClubDocument.tsx │ │ ├── ClubAdmin.tsx │ │ ├── ClubProfile.tsx │ │ └── ClubUser.tsx │ ├── TermsOfUse │ │ └── TermsOfUseModel.tsx │ ├── Distinction │ │ ├── Distinction.tsx │ │ ├── DistinctionTableSettings.tsx │ │ └── UserDistinction.tsx │ ├── Admin │ │ ├── AdminType.tsx │ │ └── AdminTypesEnum.ts │ ├── EventCreate │ │ ├── EventTypes.tsx │ │ ├── EventSections.tsx │ │ ├── Users.tsx │ │ └── EventCategories.tsx │ ├── GoverningBody │ │ ├── Sector │ │ │ ├── SectorForAdmin.tsx │ │ │ ├── SectorDocumentType.tsx │ │ │ ├── SectorUser.tsx │ │ │ ├── SectorDocument.tsx │ │ │ ├── SectorProfile.tsx │ │ │ └── SectorAdmin.tsx │ │ ├── GoverningBodyForAdmin.tsx │ │ ├── GoverningBodyDocumentType.tsx │ │ ├── Announcement │ │ │ └── Announcement.tsx │ │ ├── GoverningBodyUser.tsx │ │ ├── GoverningBodyAnnouncement.tsx │ │ ├── GoverningBodyDocument.tsx │ │ ├── GoverningBodyProfile.tsx │ │ └── GoverningBodyAdmin.tsx │ ├── RegionBoard │ │ ├── RegionBoardForAdmin.tsx │ │ └── RegionBoardProfile.tsx │ ├── EventUser │ │ ├── User.tsx │ │ ├── PlannedEvents.tsx │ │ ├── VisitedEvents.tsx │ │ ├── EventFeedback.ts │ │ ├── CreatedEvents.tsx │ │ └── EventUser.tsx │ ├── AboutBase │ │ ├── SubsectionModel.tsx │ │ └── SectionModel.tsx │ ├── Course │ │ └── Course.tsx │ ├── Blank │ │ └── BlankDocument.tsx │ ├── Roles │ │ ├── NonAdminRole.tsx │ │ └── AdminRole.tsx │ ├── Precaution │ │ └── PrecautionTableSettings.tsx │ ├── Oblast │ │ └── UkraineOblasts.ts │ ├── UserTable │ │ ├── DropdownFunc.tsx │ │ ├── User.tsx │ │ ├── Gender.tsx │ │ └── ShortUserInfo.tsx │ └── UserAccess │ │ └── IUserAccess.ts ├── components │ ├── NotificationBox │ │ ├── NotificationBox.less │ │ ├── NotificationBox.module.css │ │ └── WebSocketConnection.tsx │ ├── Quill │ │ └── FormWithQuill.css │ ├── Notifications │ │ ├── Notification.js │ │ └── Modals.tsx │ ├── ScrollToTop │ │ └── ScrollToTop.tsx │ ├── ButtonCollapse │ │ ├── ButtonCollapse.module.css │ │ └── ButtonCollapse.tsx │ ├── Tooltip.tsx │ ├── Footer │ │ ├── Footer.module.css │ │ └── FooterContainer.tsx │ ├── PrivateLayout │ │ ├── PrivateLayout.module.css │ │ └── useOneClickOutside.tsx │ ├── ImagePreview │ │ ├── ImagePreview.tsx │ │ └── ImagePreview.less │ └── HistoryNavi │ │ └── historyPseudo.tsx ├── assets │ └── images │ │ ├── add.png │ │ ├── user.jpg │ │ ├── KV1YPN.png │ │ ├── KV1YPU.png │ │ ├── KV2YPN.png │ │ ├── KV2YPU.png │ │ ├── google.png │ │ ├── ActionLogo.png │ │ ├── EventAdmin.png │ │ ├── facebook.png │ │ ├── handshake.png │ │ ├── logo_PLAST.png │ │ ├── menu-info.png │ │ ├── no-avatar.png │ │ ├── no_degree.png │ │ ├── user_add.png │ │ ├── clubBuryverkhy.png │ │ ├── ePlastLogotype.png │ │ ├── homeMenuPicture.png │ │ ├── menu-desicion.png │ │ ├── menu-documents.png │ │ ├── default_city_image.jpg │ │ ├── default_club_image.jpg │ │ ├── default_user_image.png │ │ ├── homeMenuPicture(1).jpg │ │ ├── homeMenuPicture(3).jpg │ │ └── lgbt.svg ├── typings.d.ts ├── constants │ └── TimeConstants.tsx ├── api │ ├── courseApi.tsx │ ├── regionsBoardApi.tsx │ ├── termsApi.tsx │ └── announcementsApi.ts ├── setupTests.ts ├── App.test.tsx ├── index.tsx ├── RouteWithLayout.tsx ├── AuthLocalStorage.ts └── index.css ├── public ├── robots.txt ├── favicon.ico └── manifest.json ├── manifests ├── service.yml ├── ingress-prod.yml └── deployment.yml ├── debug.log ├── nginx └── nginx.conf ├── .gitignore ├── tsconfig.json ├── .github ├── ISSUE_TEMPLATE │ └── user-story.md ├── pull_request_template.md └── PULL_REQUEST_TEMPLATE │ ├── master.md │ └── develop.md ├── .eslintrc.js ├── web.config ├── Dockerfile ├── craco.config.js └── LICENSE /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /src/pages/Regions/Modal.module.css: -------------------------------------------------------------------------------- 1 | .Style{ 2 | margin: 15; 3 | } -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/pages/City/City/Modal.module.css: -------------------------------------------------------------------------------- 1 | .Style{ 2 | margin: 15; 3 | } -------------------------------------------------------------------------------- /src/pages/Club/Club/Modal.module.css: -------------------------------------------------------------------------------- 1 | .Style{ 2 | margin: 15; 3 | } -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | const BASE_URL = "https://localhost:44350/api/"; 2 | export default BASE_URL; -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/pages/DecisionTable/FormEditDecision.module.css: -------------------------------------------------------------------------------- 1 | .buttons 2 | { 3 | margin: 3.5px; 4 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/models/AnnualReport/ReportType.ts: -------------------------------------------------------------------------------- 1 | export enum ReportType { 2 | City, 3 | Club, 4 | Region, 5 | } 6 | -------------------------------------------------------------------------------- /src/components/NotificationBox/NotificationBox.less: -------------------------------------------------------------------------------- 1 | .ant-drawer-content-wrapper { 2 | max-width: 100%; 3 | } 4 | -------------------------------------------------------------------------------- /src/pages/Interfaces/SwitcherProps.ts: -------------------------------------------------------------------------------- 1 | interface Props { 2 | switcher: boolean; 3 | } 4 | export default Props; 5 | -------------------------------------------------------------------------------- /src/assets/images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/add.png -------------------------------------------------------------------------------- /src/assets/images/user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/user.jpg -------------------------------------------------------------------------------- /src/assets/images/KV1YPN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/KV1YPN.png -------------------------------------------------------------------------------- /src/assets/images/KV1YPU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/KV1YPU.png -------------------------------------------------------------------------------- /src/assets/images/KV2YPN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/KV2YPN.png -------------------------------------------------------------------------------- /src/assets/images/KV2YPU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/KV2YPU.png -------------------------------------------------------------------------------- /src/assets/images/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/google.png -------------------------------------------------------------------------------- /src/models/AnnualReport/ReportStatus.ts: -------------------------------------------------------------------------------- 1 | export enum ReportStatus { 2 | Unconfirmed, 3 | Confirmed, 4 | Saved, 5 | } 6 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.png"; 2 | declare module "*.jpg"; 3 | declare module "*.svg"; 4 | declare module "*.css"; 5 | -------------------------------------------------------------------------------- /src/assets/images/ActionLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/ActionLogo.png -------------------------------------------------------------------------------- /src/assets/images/EventAdmin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/EventAdmin.png -------------------------------------------------------------------------------- /src/assets/images/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/facebook.png -------------------------------------------------------------------------------- /src/assets/images/handshake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/handshake.png -------------------------------------------------------------------------------- /src/assets/images/logo_PLAST.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/logo_PLAST.png -------------------------------------------------------------------------------- /src/assets/images/menu-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/menu-info.png -------------------------------------------------------------------------------- /src/assets/images/no-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/no-avatar.png -------------------------------------------------------------------------------- /src/assets/images/no_degree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/no_degree.png -------------------------------------------------------------------------------- /src/assets/images/user_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/user_add.png -------------------------------------------------------------------------------- /src/constants/TimeConstants.tsx: -------------------------------------------------------------------------------- 1 | import moment from "moment" 2 | 3 | export const minAvailableDate = moment("01.01.1900", "DD-MM-YYYY"); -------------------------------------------------------------------------------- /src/models/Documents/MethodicDocumentType.tsx: -------------------------------------------------------------------------------- 1 | export type MethodicDocumentType = { 2 | text: string; 3 | value: string; 4 | }; 5 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/Club.ts: -------------------------------------------------------------------------------- 1 | interface Club { 2 | id: number; 3 | name: string; 4 | } 5 | 6 | export default Club; 7 | -------------------------------------------------------------------------------- /src/assets/images/clubBuryverkhy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/clubBuryverkhy.png -------------------------------------------------------------------------------- /src/assets/images/ePlastLogotype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/ePlastLogotype.png -------------------------------------------------------------------------------- /src/assets/images/homeMenuPicture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/homeMenuPicture.png -------------------------------------------------------------------------------- /src/assets/images/menu-desicion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/menu-desicion.png -------------------------------------------------------------------------------- /src/assets/images/menu-documents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/menu-documents.png -------------------------------------------------------------------------------- /src/pages/GoverningBody/GoverningBody/GoverningBodyAdministration.module.css: -------------------------------------------------------------------------------- 1 | .governingBodyAdminSettingsIcon>* { 2 | font-size: 20px ; 3 | } -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/Region.ts: -------------------------------------------------------------------------------- 1 | interface Region { 2 | id: number; 3 | regionName: string; 4 | } 5 | 6 | export default Region; 7 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/Region.tsx: -------------------------------------------------------------------------------- 1 | interface Region { 2 | id: number; 3 | regionName: string; 4 | } 5 | 6 | export default Region; 7 | -------------------------------------------------------------------------------- /src/pages/UserTable/Interfaces/Degree.tsx: -------------------------------------------------------------------------------- 1 | interface Degree { 2 | id: number; 3 | degreeName: string; 4 | } 5 | 6 | export default Degree; 7 | -------------------------------------------------------------------------------- /src/assets/images/default_city_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/default_city_image.jpg -------------------------------------------------------------------------------- /src/assets/images/default_club_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/default_club_image.jpg -------------------------------------------------------------------------------- /src/assets/images/default_user_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/default_user_image.png -------------------------------------------------------------------------------- /src/assets/images/homeMenuPicture(1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/homeMenuPicture(1).jpg -------------------------------------------------------------------------------- /src/assets/images/homeMenuPicture(3).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ita-social-projects/EPlast-Client/HEAD/src/assets/images/homeMenuPicture(3).jpg -------------------------------------------------------------------------------- /src/models/EventEdit/Pysar.tsx: -------------------------------------------------------------------------------- 1 | export default class Pysar { 2 | userId: string; 3 | 4 | constructor() { 5 | this.userId = ""; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/models/Events/EventGallery.ts: -------------------------------------------------------------------------------- 1 | export interface EventGallery { 2 | galleryId: number; 3 | fileName: string; 4 | encodedData: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/Precaution.ts: -------------------------------------------------------------------------------- 1 | type Precaution = { 2 | id: number; 3 | name: string; 4 | }; 5 | 6 | export default Precaution; 7 | -------------------------------------------------------------------------------- /src/pages/UserTable/DeleteCityFollowerModal.less: -------------------------------------------------------------------------------- 1 | .deleteCityFollower .ant-modal-footer { 2 | display: flex; 3 | justify-content: space-between; 4 | } -------------------------------------------------------------------------------- /src/models/EventEdit/Alternate.tsx: -------------------------------------------------------------------------------- 1 | export default class Alternate { 2 | userId: string; 3 | 4 | constructor() { 5 | this.userId = ""; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/models/EventEdit/Commandant.tsx: -------------------------------------------------------------------------------- 1 | export default class Commandant { 2 | userId: string; 3 | 4 | constructor() { 5 | this.userId = ""; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/models/EventEdit/Bunchuzhnyi.tsx: -------------------------------------------------------------------------------- 1 | export default class Bunchuzhnyi { 2 | userId: string; 3 | 4 | constructor() { 5 | this.userId = ""; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/models/Events/EventAdmin.ts: -------------------------------------------------------------------------------- 1 | export interface EventAdmin { 2 | userId: string; 3 | fullName: string; 4 | adminType: string; 5 | avatarUrl: string; 6 | } 7 | -------------------------------------------------------------------------------- /src/pages/UserTable/ChangeUserRoleModal.less: -------------------------------------------------------------------------------- 1 | .cancelConfirmButtons { 2 | margin-bottom: 0px; 3 | .ant-row { 4 | align-items: baseline; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/pages/UserTable/Filter.less: -------------------------------------------------------------------------------- 1 | .ant-dropdown-menu-item { 2 | color: white; 3 | } 4 | 5 | .ant-dropdown-menu-item-selected { 6 | background-color: inherit; 7 | } 8 | -------------------------------------------------------------------------------- /src/models/Region/ActiveRegion.tsx: -------------------------------------------------------------------------------- 1 | interface ActiveRegion 2 | { 3 | id: number 4 | regionName: string 5 | logo: string 6 | } 7 | 8 | export default ActiveRegion -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/TableStyles.module.css: -------------------------------------------------------------------------------- 1 | .selectedRow { 2 | background-color: #f4f8f1; 3 | box-shadow: 0 0 10px #f4f8f1; 4 | color: #3D5438; 5 | } -------------------------------------------------------------------------------- /src/models/PDF/fonts.tsx: -------------------------------------------------------------------------------- 1 | export const fonts = { 2 | Times: { 3 | normal: "Times-Roman.ttf", 4 | }, 5 | ENGTEST: { 6 | normal: "IslandMoments-Regular.ttf", 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /src/pages/UserRenewal/Types/CityForRenewal.ts: -------------------------------------------------------------------------------- 1 | type City = { 2 | id: number; 3 | name: string; 4 | hasReport: boolean; 5 | isActive: boolean; 6 | }; 7 | 8 | export default City; 9 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/RegionAnnualReportForm/RegionAnnualReportFormProps.tsx: -------------------------------------------------------------------------------- 1 | interface Props { 2 | title: string; 3 | regionId: number; 4 | year: number; 5 | } 6 | 7 | export default Props; 8 | -------------------------------------------------------------------------------- /src/models/City/CityForAdmin.tsx: -------------------------------------------------------------------------------- 1 | export default class CityForAdmin { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/Club/ClubForAdmin.tsx: -------------------------------------------------------------------------------- 1 | export default class ClubForAdmin { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/TermsOfUse/TermsOfUseModel.tsx: -------------------------------------------------------------------------------- 1 | type TermsOfUse = { 2 | termsId: number; 3 | termsTitle: string; 4 | termsText: string; 5 | datePublication: Date; 6 | }; 7 | export default TermsOfUse; 8 | -------------------------------------------------------------------------------- /src/models/Distinction/Distinction.tsx: -------------------------------------------------------------------------------- 1 | export default class Distinction { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/Documents/DocumentWraper.tsx: -------------------------------------------------------------------------------- 1 | import { DocumentPost } from "./DocumentPost"; 2 | 3 | export type DocumentWrapper = { 4 | MethodicDocument: DocumentPost; 5 | fileAsBase64: string | null; 6 | }; 7 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/ClubSelectModal/ClubSelectModal.less: -------------------------------------------------------------------------------- 1 | .clubCreatedReportStamp { 2 | float: right; 3 | font-size: 12px; 4 | margin-top: 2px; 5 | margin-right: 10px; 6 | } 7 | -------------------------------------------------------------------------------- /manifests/service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: eplastweb 5 | spec: 6 | type: ClusterIP 7 | ports: 8 | - port: 80 9 | selector: 10 | app: eplastweb -------------------------------------------------------------------------------- /src/models/City/CityDocumentType.tsx: -------------------------------------------------------------------------------- 1 | export default class CityDocumentType { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/Club/ClubDocumentType.tsx: -------------------------------------------------------------------------------- 1 | export default class ClubDocumentType { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/userPage/Blanks/Blank.less: -------------------------------------------------------------------------------- 1 | .title{ 2 | .ant-popover-message-title{ 3 | padding-left: 0px; 4 | } 5 | } 6 | 7 | div.ant-typography, .ant-typography p { 8 | overflow-wrap: break-word; 9 | } -------------------------------------------------------------------------------- /src/models/Admin/AdminType.tsx: -------------------------------------------------------------------------------- 1 | export default class AdminType { 2 | id: number; 3 | adminTypeName: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.adminTypeName = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportForm/AnnualReportFormProps.tsx: -------------------------------------------------------------------------------- 1 | interface Props { 2 | title: string; 3 | cityMembers: any; 4 | cityLegalStatuses: any; 5 | formHook?: any; 6 | } 7 | 8 | export default Props; 9 | -------------------------------------------------------------------------------- /src/models/EventCreate/EventTypes.tsx: -------------------------------------------------------------------------------- 1 | export default class EventTypes { 2 | id: number; 3 | eventTypeName: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.eventTypeName = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/GoverningBody/Sector/SectorForAdmin.tsx: -------------------------------------------------------------------------------- 1 | export default class SectorForAdmin { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/Region/RegionForAdmin.tsx: -------------------------------------------------------------------------------- 1 | export default class RegionForAdmin { 2 | id: number; 3 | regionName: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.regionName = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventInfo/EventInfo.module.css: -------------------------------------------------------------------------------- 1 | .userTableTitle { 2 | color: #3c5438; 3 | } 4 | 5 | .searchArea { 6 | margin-bottom: 10px; 7 | max-width: 500px; 8 | align-self: center; 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/User.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | phoneNumber?: string; 6 | email?: string; 7 | } 8 | 9 | export default User; 10 | -------------------------------------------------------------------------------- /src/pages/Distinction/Interfaces/User.tsx: -------------------------------------------------------------------------------- 1 | type User = { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | email: string; 6 | isInLowerRole: boolean; 7 | }; 8 | 9 | export default User; 10 | -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyForAdmin.tsx: -------------------------------------------------------------------------------- 1 | export default class GoverningBodyForAdmin { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportForm/AnnualReportForm.less: -------------------------------------------------------------------------------- 1 | .annualreport-form { 2 | .w100 { 3 | width: 100%; 4 | } 5 | } 6 | 7 | .column{ 8 | max-height: 150px; 9 | min-height: 130px; 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/KadraVykhovnykiv/Interfaces/KadraTableSettings.ts: -------------------------------------------------------------------------------- 1 | export type KadraTableSettings = { 2 | KadraTypeId: number; 3 | PageSize: number; 4 | Page: number; 5 | SearchedData: string; 6 | SortByOrder: string[]; 7 | }; 8 | -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/Filter.less: -------------------------------------------------------------------------------- 1 | .ant-table-thead { 2 | -moz-user-select: none; 3 | -khtml-user-select: none; 4 | -webkit-user-select: none; 5 | -ms-user-select: none; 6 | user-select: none; 7 | } -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/City.tsx: -------------------------------------------------------------------------------- 1 | import Region from "./Region"; 2 | 3 | interface City { 4 | id: number; 5 | name: string; 6 | regionId: number; 7 | region: Region; 8 | } 9 | 10 | export default City; 11 | -------------------------------------------------------------------------------- /src/pages/UserRenewal/Types/UserRenewal.ts: -------------------------------------------------------------------------------- 1 | type UserRenewal = { 2 | id: number; 3 | userId: string; 4 | cityId: number; 5 | requestDate: Date; 6 | approved: boolean; 7 | }; 8 | 9 | export default UserRenewal; 10 | -------------------------------------------------------------------------------- /src/models/GoverningBody/Sector/SectorDocumentType.tsx: -------------------------------------------------------------------------------- 1 | export default class SectorDocumentType { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/RegionBoard/RegionBoardForAdmin.tsx: -------------------------------------------------------------------------------- 1 | export default class RegionForAdmin { 2 | id: number; 3 | regionName: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.regionName = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/UserRenewal/UserRenewalTable/Filter.less: -------------------------------------------------------------------------------- 1 | .ant-table-thead { 2 | -moz-user-select: none; 3 | -khtml-user-select: none; 4 | -webkit-user-select: none; 5 | -ms-user-select: none; 6 | user-select: none; 7 | } -------------------------------------------------------------------------------- /debug.log: -------------------------------------------------------------------------------- 1 | [1019/103241.952:ERROR:directory_reader_win.cc(43)] FindFirstFile: Ñèñòåìå íå óäàåòñÿ íàéòè óêàçàííûé ïóòü. (0x3) 2 | [1022/102807.424:ERROR:directory_reader_win.cc(43)] FindFirstFile: Ñèñòåìå íå óäàåòñÿ íàéòè óêàçàííûé ïóòü. (0x3) -------------------------------------------------------------------------------- /src/models/Documents/Document.tsx: -------------------------------------------------------------------------------- 1 | export type Document = { 2 | id: number; 3 | name: string; 4 | type: string; 5 | governingBody: string; 6 | description: string; 7 | date: Date; 8 | fileName: string | null; 9 | }; 10 | -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyDocumentType.tsx: -------------------------------------------------------------------------------- 1 | export default class GoverningBodyDocumentType { 2 | id: number; 3 | name: string; 4 | 5 | constructor() { 6 | this.id = 0; 7 | this.name = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/Region/RegionForAdministration.tsx: -------------------------------------------------------------------------------- 1 | interface RegionForAdministration { 2 | id: number, 3 | regionName: string, 4 | yearsHasReport: number, 5 | isActive: boolean 6 | } 7 | 8 | export default RegionForAdministration -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/SuggestedUser.ts: -------------------------------------------------------------------------------- 1 | type SuggestedUser = { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | email: string; 6 | isAvailable: boolean 7 | } 8 | 9 | export default SuggestedUser -------------------------------------------------------------------------------- /src/components/Quill/FormWithQuill.css: -------------------------------------------------------------------------------- 1 | .ql-picker-label .ql-stroke:nth-child(2){ 2 | display: none; 3 | } 4 | 5 | .ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg { 6 | margin-top: -12px; 7 | right: 12px; 8 | } -------------------------------------------------------------------------------- /src/models/Club/ClubByPage.tsx: -------------------------------------------------------------------------------- 1 | export default class ClubByPage { 2 | id: number; 3 | name: string; 4 | logo: string; 5 | 6 | constructor() { 7 | this.id = 0; 8 | this.name = ""; 9 | this.logo = ""; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/YearStatistics.tsx: -------------------------------------------------------------------------------- 1 | import StatisticsItem from "./StatisticsItem"; 2 | 3 | interface YearStatistics { 4 | year: number; 5 | statisticsItems: Array; 6 | } 7 | 8 | export default YearStatistics; 9 | -------------------------------------------------------------------------------- /src/models/EventCreate/EventSections.tsx: -------------------------------------------------------------------------------- 1 | export default class EventSections { 2 | eventSectionId: number; 3 | eventSectionName: string; 4 | 5 | constructor() { 6 | this.eventSectionId = 0; 7 | this.eventSectionName = ""; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/models/EventUser/User.tsx: -------------------------------------------------------------------------------- 1 | export default class User { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | 6 | constructor() { 7 | this.id = ""; 8 | this.firstName = ""; 9 | this.lastName = ""; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/models/Events/EventParticipant.ts: -------------------------------------------------------------------------------- 1 | export interface EventParticipant { 2 | participantId: number; 3 | fullName: string; 4 | email: string; 5 | userId: string; 6 | statusId: number; 7 | status: string; 8 | wasPresent: boolean; 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportEdit/AnnualReportEdit.less: -------------------------------------------------------------------------------- 1 | .annualreport-form { 2 | background-color: #ffffff; 3 | border: 2px solid #3c5438; 4 | border-radius: 15px; 5 | box-shadow: 0px 4px 4px rgba(3, 80, 0, 0.65); 6 | padding: 1%; 7 | } 8 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/Dropdowns/Dropdown.module.css: -------------------------------------------------------------------------------- 1 | .menu { 2 | box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2) !important; 3 | position: absolute; 4 | display: block; 5 | } 6 | 7 | .menuHidden { 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/StatisticsItem.tsx: -------------------------------------------------------------------------------- 1 | import StatisticsItemIndicator from "./StatisticsItemIndicator"; 2 | 3 | interface StatisticsItem { 4 | indicator: StatisticsItemIndicator; 5 | value: number; 6 | } 7 | 8 | export default StatisticsItem; 9 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportCreate/AnnualReportCreate.less: -------------------------------------------------------------------------------- 1 | .annualreport-form { 2 | background-color: #ffffff; 3 | border: 2px solid #3c5438; 4 | border-radius: 15px; 5 | box-shadow: 0px 4px 4px rgba(3, 80, 0, 0.65); 6 | padding: 1%; 7 | } 8 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/CitySelectModal/CitySelectModal.less: -------------------------------------------------------------------------------- 1 | .stampCitiesCreatedReport { 2 | float: right; 3 | font-size: 12px; 4 | margin-top: 2px; 5 | margin-right: 10px; 6 | } 7 | 8 | .ant-modal-title { 9 | width: 90%; 10 | } -------------------------------------------------------------------------------- /src/api/courseApi.tsx: -------------------------------------------------------------------------------- 1 | import api from "./api"; 2 | 3 | export const getAllCourse = async () => { 4 | return api.get(`Courses`); 5 | }; 6 | 7 | export const getAllCourseByUserId = async (id:string) => { 8 | return api.get(`Courses/${id}`); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForRegionReports/Dropdown.module.css: -------------------------------------------------------------------------------- 1 | .menu { 2 | box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2) !important; 3 | position: absolute; 4 | display: block; 5 | } 6 | 7 | .menuHidden { 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/ActionCard/ActionCard.module.css: -------------------------------------------------------------------------------- 1 | .cardStyles{ 2 | margin: 15px; 3 | width: 242px; 4 | } 5 | .titleText{ 6 | text-align: center; 7 | font-size: 20px; 8 | font-weight: 700; 9 | } 10 | .titleText:hover{ 11 | text-decoration: underline; 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForClubAnnualReports/Dropdown.module.css: -------------------------------------------------------------------------------- 1 | .menu { 2 | box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2) !important; 3 | position: absolute; 4 | display: block; 5 | } 6 | 7 | .menuHidden { 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/Spinner/Spinner.less: -------------------------------------------------------------------------------- 1 | .spaceWrapper { 2 | top: 0; 3 | left: 0; 4 | z-index: 999; 5 | background-color: white; 6 | } 7 | 8 | .loader { 9 | position: fixed !important; 10 | top: 50%; 11 | left: 50%; 12 | transform: translateX(-50%); 13 | } -------------------------------------------------------------------------------- /src/pages/Actions/EventTypes/EventTypeCard.module.css: -------------------------------------------------------------------------------- 1 | .cardStyles { 2 | margin: 15px; 3 | width: 242px; 4 | } 5 | .titleText { 6 | text-align: center; 7 | font-size: 20px; 8 | font-weight: 700; 9 | } 10 | .titleText:hover { 11 | text-decoration: underline; 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/RegionAnnualReportCreateEditView/RegionAnnualReportCreate.less: -------------------------------------------------------------------------------- 1 | .annualreport-form { 2 | background-color: #ffffff; 3 | border: 2px solid #3c5438; 4 | border-radius: 15px; 5 | box-shadow: 0px 4px 4px rgba(3, 80, 0, 0.65); 6 | padding: 1%; 7 | } 8 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import "@testing-library/jest-dom/extend-expect"; 6 | -------------------------------------------------------------------------------- /src/pages/Distinction/Interfaces/UserDistinctionEdit.tsx: -------------------------------------------------------------------------------- 1 | type UserDistinctionEdit = { 2 | id: number; 3 | distinctionId: number; 4 | reporter: string; 5 | reason: string; 6 | number: number; 7 | date: Date; 8 | userId: string; 9 | }; 10 | export default UserDistinctionEdit; 11 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/PrecautionUser.ts: -------------------------------------------------------------------------------- 1 | type PrecautionUser = { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | fatherName: string; 6 | imagePath: string; 7 | email: string; 8 | phoneNumber: string; 9 | }; 10 | 11 | export default PrecautionUser; 12 | -------------------------------------------------------------------------------- /src/pages/SignIn/SignIn.less: -------------------------------------------------------------------------------- 1 | #SignInForm 2 | { 3 | .ant-input-affix-wrapper 4 | { 5 | padding-left: 0px !important; 6 | } 7 | } 8 | #SignInForm_Password 9 | { 10 | padding-left: 11px !important; 11 | } 12 | 13 | .ant-input-suffix 14 | { 15 | padding-left: 8px !important; 16 | } -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/RegionStatistics.tsx: -------------------------------------------------------------------------------- 1 | import Region from "./Region"; 2 | import YearStatistics from "./YearStatistics"; 3 | 4 | interface RegionStatistics { 5 | region: Region; 6 | yearStatistics: Array; 7 | } 8 | 9 | export default RegionStatistics; 10 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventCard/EventCard.module.css: -------------------------------------------------------------------------------- 1 | .actionsWrapper { 2 | display: flex; 3 | justify-content: center; 4 | flex-wrap: wrap; 5 | width: 100%; 6 | margin: 0 auto; 7 | } 8 | .cardStyles { 9 | width: 180px; 10 | margin: 15px; 11 | text-align: center; 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/UserPrecauctionsTableInfo.ts: -------------------------------------------------------------------------------- 1 | import UserPrecautionTableItem from "./UserPrecautionTableItem"; 2 | 3 | type UserPrecautionsTableInfo = { 4 | totalItems: number; 5 | userPrecautions: UserPrecautionTableItem[]; 6 | }; 7 | 8 | export default UserPrecautionsTableInfo; 9 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/CityStatistics.tsx: -------------------------------------------------------------------------------- 1 | import City from "./City"; 2 | import YearStatistics from "./YearStatistics"; 3 | 4 | interface CityStatistics { 5 | id: number; 6 | city: City; 7 | yearStatistics: Array; 8 | } 9 | 10 | export default CityStatistics; 11 | -------------------------------------------------------------------------------- /src/models/EventCreate/Users.tsx: -------------------------------------------------------------------------------- 1 | export default class Users { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | userName: string; 6 | 7 | constructor() { 8 | this.id = ""; 9 | this.firstName = ""; 10 | this.lastName = ""; 11 | this.userName = ""; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/DataFromResponse.tsx: -------------------------------------------------------------------------------- 1 | import StatisticsItem from "./StatisticsItem"; 2 | 3 | interface DataFromResponse { 4 | id: number; 5 | cityName: string; 6 | regionName: string; 7 | year: number; 8 | number: StatisticsItem[]; 9 | } 10 | export default DataFromResponse; 11 | -------------------------------------------------------------------------------- /src/models/AboutBase/SubsectionModel.tsx: -------------------------------------------------------------------------------- 1 | export default class Subsection { 2 | id: number; 3 | sectionId: number; 4 | title: string; 5 | description: string; 6 | constructor() { 7 | this.id = 0; 8 | this.sectionId = 0; 9 | this.title = ""; 10 | this.description = ""; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/models/Documents/DocumentOnCreateData.tsx: -------------------------------------------------------------------------------- 1 | import { GoverningBody } from "../../api/decisionsApi"; 2 | import { MethodicDocumentType } from "./MethodicDocumentType"; 3 | 4 | export type DocumentOnCreateData = { 5 | governingBodies: GoverningBody[]; 6 | methodicDocumentTypesItems: MethodicDocumentType[]; 7 | }; 8 | -------------------------------------------------------------------------------- /src/models/Documents/DocumentPost.tsx: -------------------------------------------------------------------------------- 1 | import { GoverningBody } from "../../api/decisionsApi"; 2 | 3 | export type DocumentPost = { 4 | id: number; 5 | name: string; 6 | type: number; 7 | governingBody: GoverningBody; 8 | description: string; 9 | date: string; 10 | fileName: string | null; 11 | }; 12 | -------------------------------------------------------------------------------- /src/models/Course/Course.tsx: -------------------------------------------------------------------------------- 1 | export default class Course { 2 | id: number; 3 | name: string; 4 | link: string; 5 | isFinishedByUser :boolean; 6 | 7 | constructor() { 8 | this.id = 0; 9 | this.name = ""; 10 | this.link = ""; 11 | this.isFinishedByUser= false; 12 | } 13 | } -------------------------------------------------------------------------------- /src/pages/userPage/Secretaries/SectorModelForTable.ts: -------------------------------------------------------------------------------- 1 | type SectorModelForTable = { 2 | id: number; 3 | userId: string; 4 | userName: string; 5 | adminType: string; 6 | startDate: Date; 7 | endDate: Date; 8 | sectorName: string; 9 | status: boolean; 10 | }; 11 | 12 | export default SectorModelForTable; 13 | -------------------------------------------------------------------------------- /src/models/EventCreate/EventCategories.tsx: -------------------------------------------------------------------------------- 1 | export default class EventCategories { 2 | eventCategoryId: number; 3 | eventCategoryName: string; 4 | eventSectionId: number; 5 | 6 | constructor() { 7 | this.eventCategoryId = 0; 8 | this.eventCategoryName = ""; 9 | this.eventSectionId = 0; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { render } from "@testing-library/react"; 3 | import App from "./App"; 4 | 5 | test("renders learn react link", () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/components/Notifications/Notification.js: -------------------------------------------------------------------------------- 1 | import { notification } from "antd"; 2 | 3 | const openNotificationWithIcon = (type, text, icon = null) => { 4 | notification[type]({ 5 | message: "Сповіщення", 6 | icon: icon, 7 | description: text, 8 | }); 9 | }; 10 | 11 | export default openNotificationWithIcon; 12 | -------------------------------------------------------------------------------- /src/models/AboutBase/SectionModel.tsx: -------------------------------------------------------------------------------- 1 | import SubSectionModel from "./SubsectionModel"; 2 | export default class Section { 3 | id: number; 4 | title: string; 5 | subsection: SubSectionModel; 6 | constructor() { 7 | this.id = 0; 8 | this.title = ""; 9 | this.subsection = new SubSectionModel(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/KadraVykhovnykiv/Interfaces/KadraTableInfo.tsx: -------------------------------------------------------------------------------- 1 | export type KadraTableInfo = { 2 | total: number; 3 | subtotal: number; 4 | id: number; 5 | userName: string; 6 | numberInRegister: number; 7 | kadraVykhovnykivTypeId: number; 8 | kadraName: string; 9 | dateOfGranting: Date; 10 | userId: string; 11 | }; 12 | -------------------------------------------------------------------------------- /src/models/Documents/DocumentsTableInfo.tsx: -------------------------------------------------------------------------------- 1 | type DocumentsTableInfo = { 2 | total: number; 3 | count: number; 4 | id: number; 5 | name: string; 6 | governingBody: string; 7 | description: string; 8 | date: string; 9 | fileName: string | null; 10 | type: string; 11 | }; 12 | 13 | export default DocumentsTableInfo; 14 | -------------------------------------------------------------------------------- /src/pages/userPage/Secretaries/SecretaryModelForTable.ts: -------------------------------------------------------------------------------- 1 | type SecretaryModelForTable = { 2 | id: number; 3 | userId: string; 4 | userName: string; 5 | adminType: string; 6 | startDate: Date; 7 | endDate: Date; 8 | governBodyName: string; 9 | status: boolean; 10 | }; 11 | 12 | export default SecretaryModelForTable; 13 | -------------------------------------------------------------------------------- /src/components/ScrollToTop/ScrollToTop.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useLocation } from "react-router-dom"; 3 | 4 | export default function ScrollToTop() { 5 | const { pathname } = useLocation(); 6 | 7 | useEffect(() => { 8 | window.scrollTo(0, 0); 9 | }, [pathname]); 10 | 11 | return null; 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/Actions/Actions.module.css: -------------------------------------------------------------------------------- 1 | .mainTitle { 2 | text-align: center; 3 | font-size: 40px; 4 | color: #3c5438; 5 | } 6 | 7 | .actionsWrapper { 8 | display: flex; 9 | justify-content: center; 10 | flex-wrap: wrap; 11 | width: 90%; 12 | margin: 0 auto; 13 | } 14 | 15 | .pagination { 16 | text-align: center; 17 | } 18 | -------------------------------------------------------------------------------- /src/models/Club/Club.tsx: -------------------------------------------------------------------------------- 1 | export default class Club { 2 | id: number; 3 | clubName: string; 4 | clubURL: string; 5 | description: string; 6 | logo: string; 7 | 8 | constructor() { 9 | this.id = 0; 10 | this.clubName = ""; 11 | this.clubURL = ""; 12 | this.description = ""; 13 | this.logo = ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/CitiesStatisticsParameters.tsx: -------------------------------------------------------------------------------- 1 | import StatisticsItemIndicator from "./StatisticsItemIndicator"; 2 | 3 | interface CitiesStatisticsParameters { 4 | CityIds: Array; 5 | Years: Array; 6 | Indicators: Array; 7 | } 8 | 9 | export default CitiesStatisticsParameters; 10 | -------------------------------------------------------------------------------- /src/models/Club/ClubMember.tsx: -------------------------------------------------------------------------------- 1 | import ClubUser from "./ClubUser"; 2 | 3 | export default class ClubMember { 4 | id: number; 5 | userId: string; 6 | user: ClubUser; 7 | ClubId: number; 8 | 9 | constructor() { 10 | this.id = 0; 11 | this.userId = ""; 12 | this.user = new ClubUser(); 13 | this.ClubId = 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/models/EventUser/PlannedEvents.tsx: -------------------------------------------------------------------------------- 1 | export default class PlannedEvents { 2 | id: number; 3 | eventName: string; 4 | eventDateStart?: Date; 5 | eventDateEnd?: Date; 6 | 7 | constructor() { 8 | this.id = 0; 9 | this.eventName = ""; 10 | this.eventDateStart = undefined; 11 | this.eventDateEnd = undefined; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/models/EventUser/VisitedEvents.tsx: -------------------------------------------------------------------------------- 1 | export default class VisitedEvents { 2 | id: number; 3 | eventName: string; 4 | eventDateStart?: Date; 5 | eventDateEnd?: Date; 6 | 7 | constructor() { 8 | this.id = 0; 9 | this.eventName = ""; 10 | this.eventDateStart = undefined; 11 | this.eventDateEnd = undefined; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/RegionsStatisticsParameters.tsx: -------------------------------------------------------------------------------- 1 | import StatisticsItemIndicator from "./StatisticsItemIndicator"; 2 | 3 | interface RegionsStatisticsParameters { 4 | RegionIds: Array; 5 | Years: Array; 6 | Indicators: Array; 7 | } 8 | 9 | export default RegionsStatisticsParameters; 10 | -------------------------------------------------------------------------------- /src/models/City/CityUser.tsx: -------------------------------------------------------------------------------- 1 | export default class CityUser { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | email: string; 6 | imagePath: string; 7 | 8 | constructor() { 9 | this.id = ""; 10 | this.firstName = ""; 11 | this.lastName = ""; 12 | this.email = ""; 13 | this.imagePath = ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/models/GoverningBody/Announcement/Announcement.tsx: -------------------------------------------------------------------------------- 1 | export type Announcement = { 2 | id: number; 3 | text: string; 4 | title: string; 5 | date: Date; 6 | firstName: string; 7 | lastName: string; 8 | userId: string; 9 | profileImage: string; 10 | images?: string[]; 11 | imagesPresent?: boolean; 12 | isPined: boolean; 13 | }; 14 | -------------------------------------------------------------------------------- /src/models/Blank/BlankDocument.tsx: -------------------------------------------------------------------------------- 1 | export default class BlankDocument { 2 | id: number; 3 | blobName: string; 4 | fileName: string; 5 | userId: string; 6 | courseId?: number; 7 | 8 | constructor() { 9 | this.id = 0; 10 | this.blobName = ""; 11 | this.fileName = ""; 12 | this.userId = ""; 13 | this.courseId = 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/models/Distinction/DistinctionTableSettings.tsx: -------------------------------------------------------------------------------- 1 | export default class DistinctionTableSettings { 2 | sortByOrder?: Array; 3 | searchedData: string; 4 | page: number; 5 | pageSize: number; 6 | 7 | constructor() { 8 | this.sortByOrder = []; 9 | this.searchedData = ""; 10 | this.page = 0; 11 | this.pageSize = 0; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/models/Roles/NonAdminRole.tsx: -------------------------------------------------------------------------------- 1 | export enum NonAdminRole { 2 | FormerPlastMember = 0, //Колишній член 3 | PlastMember = 1, //Дійсний член - має більше менюшок 4 | Supporter = 2, //Прихильник - має більше менюшок 5 | RegisteredUser = 3, //Зареєстрований 6 | } 7 | 8 | //This enum is used to make dropdown menus based on 9 | //selected user role in Plast 10 | -------------------------------------------------------------------------------- /src/pages/SignIn/FacebookDataInterface.tsx: -------------------------------------------------------------------------------- 1 | export default interface FacebookData { 2 | accessToken: string; 3 | data_access_expiration_time: number; 4 | email: string; 5 | expiresIn: number; 6 | graphDomain: string; 7 | id: number; 8 | name: string; 9 | picture: any; 10 | userID: number; 11 | birthday: string; 12 | gender: string; 13 | } 14 | -------------------------------------------------------------------------------- /src/pages/UserRenewal/Types/DropDownProps.ts: -------------------------------------------------------------------------------- 1 | type DropDownProps = { 2 | id: number; 3 | userId: string; 4 | cityId: number; 5 | isRecordActive: boolean; 6 | pageX: number; 7 | pageY: number; 8 | showDropdown: boolean; 9 | roles: string[]; 10 | currentCity: number; 11 | onConfirm: () => void; 12 | }; 13 | 14 | export default DropDownProps; 15 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/City.ts: -------------------------------------------------------------------------------- 1 | import Region from "./Region"; 2 | 3 | interface City { 4 | id: number; 5 | name: string; 6 | regionId: number; 7 | region: Region | null; 8 | cityMembers: any | null; 9 | } 10 | 11 | export interface ActiveCity { 12 | id: number; 13 | name: string; 14 | logo: string 15 | } 16 | 17 | export default City; 18 | -------------------------------------------------------------------------------- /src/models/GoverningBody/Sector/SectorUser.tsx: -------------------------------------------------------------------------------- 1 | export default class SectorUser { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | imagePath: string; 6 | email: string; 7 | 8 | constructor() { 9 | this.id = ""; 10 | this.firstName = ""; 11 | this.lastName = ""; 12 | this.imagePath = ""; 13 | this.email = ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/DecisionTable/Interfaces/DecisionTableInfo.tsx: -------------------------------------------------------------------------------- 1 | export type DecisionTableInfo = { 2 | total: number; 3 | count: number; 4 | id: number; 5 | name: string; 6 | governingBody: string; 7 | decisionStatusType: string; 8 | decisionTarget: string; 9 | description: string; 10 | date: string; 11 | userId: string; 12 | fileName: string | null; 13 | }; 14 | -------------------------------------------------------------------------------- /src/models/Region/RegionDocument.tsx: -------------------------------------------------------------------------------- 1 | export default class RegionDocument { 2 | id: number; 3 | blobName: string; 4 | fileName: string; 5 | submitDate?: string; 6 | regionId: number; 7 | 8 | constructor() { 9 | this.id = 0; 10 | this.blobName = ""; 11 | this.fileName = ""; 12 | this.submitDate = undefined; 13 | this.regionId = 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/AddAdministratorModal/AddAdministrationModal.less: -------------------------------------------------------------------------------- 1 | .addAdministrationModal { 2 | 3 | .ant-form-item-required { 4 | align-items: flex-start; 5 | } 6 | } 7 | 8 | @media (max-width: 575px) { 9 | .addAdministrationModal { 10 | .cancelConfirmButtons { 11 | .publishButton { 12 | text-align: end; 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/components/ButtonCollapse/ButtonCollapse.module.css: -------------------------------------------------------------------------------- 1 | .ButtonCollapse{ 2 | position: absolute !important; 3 | top: 0; 4 | right: 0; 5 | padding: 20px !important; 6 | padding-top: 15px !important; 7 | width: 56px; 8 | height: 54px !important; 9 | border: 0 !important; 10 | background: none !important; 11 | color: #949996 !important; 12 | font-weight: bold !important; 13 | } -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import { ConfigProvider } from "antd"; 6 | import UkLocale from "antd/es/locale/uk_UA"; 7 | 8 | ReactDOM.render( 9 | 10 | 11 | , 12 | document.getElementById("root") 13 | ); 14 | -------------------------------------------------------------------------------- /src/pages/Distinction/Interfaces/UserDistinctionTableInfo.tsx: -------------------------------------------------------------------------------- 1 | type UserDistinctionTableInfo = { 2 | count: number; 3 | total: number; 4 | id: number; 5 | number: number; 6 | distinctionName: string; 7 | userId: string; 8 | userName: string; 9 | reporter: string; 10 | reason: string; 11 | date: Date; 12 | }; 13 | 14 | export default UserDistinctionTableInfo; 15 | -------------------------------------------------------------------------------- /src/pages/KadraVykhovnykiv/Types/EducatorsStaffTableData.ts: -------------------------------------------------------------------------------- 1 | type EducatorsStaffTableData = { 2 | id: number; 3 | subtotal: number; 4 | total: number; 5 | userId: string; 6 | userName: string; 7 | dateOfGranting: Date; 8 | numberInRegister: number; 9 | kadraVykhovnykivTypeId: number; 10 | kadraName: string; 11 | }; 12 | 13 | export default EducatorsStaffTableData; 14 | -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | 3 | listen 80; 4 | 5 | location / { 6 | root /usr/share/nginx/html; 7 | include /etc/nginx/mime.types; 8 | index index.html index.htm; 9 | try_files $uri $uri/ /index.html; 10 | } 11 | 12 | error_page 500 502 503 504 /50x.html; 13 | 14 | location = /50x.html { 15 | root /usr/share/nginx/html; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/UserPrecautionAdd.ts: -------------------------------------------------------------------------------- 1 | import UserPrecautionStatus from "./UserPrecautionStatus"; 2 | 3 | type UserPrecautionAdd = { 4 | precautionId: number; 5 | reporter: string; 6 | reason: string; 7 | status: UserPrecautionStatus; 8 | number: number; 9 | date: Date; 10 | userId: string; 11 | }; 12 | 13 | export default UserPrecautionAdd; 14 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/ActionEvent.module.css: -------------------------------------------------------------------------------- 1 | .mainTitle { 2 | text-align: center; 3 | font-size: 40px; 4 | color: #3c5438; 5 | } 6 | .actionsWrapper { 7 | display: flex; 8 | justify-content: center; 9 | flex-wrap: wrap; 10 | width: 90%; 11 | margin: 0 auto; 12 | } 13 | 14 | .swapper { 15 | margin-left: 10px; 16 | font-size: 15px; 17 | font-weight: bold; 18 | } 19 | -------------------------------------------------------------------------------- /src/pages/City/Cities/ActionCities.module.css: -------------------------------------------------------------------------------- 1 | .mainTitle{ 2 | text-align: center; 3 | font-size: 65px; 4 | color:#3c5438; 5 | } 6 | .actionsWrapper{ 7 | display: flex; 8 | justify-content: center; 9 | flex-wrap: wrap; 10 | width: 90%; 11 | margin: 0 auto; 12 | } 13 | 14 | .swapper{ 15 | margin-left: 10px; 16 | font-size: 15px; 17 | font-weight: bold; 18 | } -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/UserPrecautionEdit.ts: -------------------------------------------------------------------------------- 1 | import UserPrecautionStatus from "./UserPrecautionStatus"; 2 | 3 | type UserPrecautionEdit = { 4 | id: number; 5 | precautionId: number; 6 | reporter: string; 7 | reason: string; 8 | status: UserPrecautionStatus; 9 | number: number; 10 | date: Date; 11 | userId: string; 12 | }; 13 | 14 | export default UserPrecautionEdit; 15 | -------------------------------------------------------------------------------- /src/pages/Club/Clubs/ActionClubs.module.css: -------------------------------------------------------------------------------- 1 | 2 | .mainTitle{ 3 | text-align: center; 4 | font-size: 65px; 5 | color:#3c5438; 6 | } 7 | .actionsWrapper{ 8 | display: flex; 9 | justify-content: center; 10 | flex-wrap: wrap; 11 | width: 90%; 12 | margin: 0 auto; 13 | } 14 | 15 | .swapper{ 16 | margin-left: 10px; 17 | font-size: 15px; 18 | font-weight: bold; 19 | } -------------------------------------------------------------------------------- /src/pages/Regions/ActionRegion.module.css: -------------------------------------------------------------------------------- 1 | .mainTitle{ 2 | text-align: center; 3 | font-size: 65px; 4 | color:#3c5438; 5 | } 6 | 7 | .actionsWrapper{ 8 | display: flex; 9 | justify-content: center; 10 | flex-wrap: wrap; 11 | width: 90%; 12 | margin: 0 auto; 13 | } 14 | 15 | .swapper{ 16 | margin-left: 10px; 17 | font-size: 15px; 18 | font-weight: bold; 19 | } -------------------------------------------------------------------------------- /src/pages/UserRenewal/Types/UserRenewalTableData.ts: -------------------------------------------------------------------------------- 1 | type UserRenewalTableData = { 2 | id: number; 3 | subtotal: number; 4 | total: number; 5 | userId: string; 6 | userName: string; 7 | cityId: number; 8 | cityName: string; 9 | regionName: string; 10 | requestDate: Date; 11 | email: string; 12 | approved: boolean; 13 | comment: string; 14 | }; 15 | 16 | export default UserRenewalTableData; 17 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/RegionSelectModal/RegionSelectModal.less: -------------------------------------------------------------------------------- 1 | .regionSelectModalStamp { 2 | float: right; 3 | font-size: 12px; 4 | margin-top: 2px; 5 | margin-right: 10px; 6 | } 7 | 8 | .regionSelectModalClearOutlined { 9 | margin-left: 5px; 10 | margin-top: -10px; 11 | float: right; 12 | font-size: large; 13 | cursor: pointer; 14 | margin-bottom: 10px; 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/ClubAnnualReportEdit/ClubAnnualReportEdit.less: -------------------------------------------------------------------------------- 1 | .annualreport-form { 2 | background-color: #ffffff; 3 | border: 2px solid #3c5438; 4 | border-radius: 15px; 5 | box-shadow: 0px 4px 4px rgba(3, 80, 0, 0.65); 6 | padding: 1%; 7 | } 8 | 9 | .clubButtons { 10 | text-align: center; 11 | 12 | .ant-btn-primary { 13 | width: 65%; 14 | margin: 5px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/components/Tooltip.tsx: -------------------------------------------------------------------------------- 1 | import { Tooltip } from "antd"; 2 | import React from "react"; 3 | 4 | function extendedTitleTooltip(number: number, text: string) { 5 | return text?.length > number ? ( 6 | 7 | {text.slice(0, number - 1) + "..."} 8 | 9 | ) : ( 10 | text 11 | ); 12 | } 13 | export const parameterMaxLength = 20; 14 | export default extendedTitleTooltip; 15 | -------------------------------------------------------------------------------- /src/models/City/CityMember.tsx: -------------------------------------------------------------------------------- 1 | import CityUser from "./CityUser"; 2 | 3 | export default class CityMember { 4 | id: number; 5 | userId: string; 6 | user: CityUser; 7 | cityId: number; 8 | wasInRegisteredUserRole: boolean; 9 | 10 | constructor() { 11 | this.id = 0; 12 | this.userId = ""; 13 | this.user = new CityUser(); 14 | this.cityId = 0; 15 | this.wasInRegisteredUserRole = false; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/models/EventUser/EventFeedback.ts: -------------------------------------------------------------------------------- 1 | export default class EventFeedback { 2 | id: number; 3 | text: string; 4 | rating: number; 5 | authorName: string; 6 | authorAvatarUrl: string; 7 | authorUserId: string; 8 | 9 | constructor() { 10 | this.id = 0; 11 | this.text = ""; 12 | this.rating = 0; 13 | this.authorName = ""; 14 | this.authorAvatarUrl = ""; 15 | this.authorUserId = ""; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/pages/Club/Club/CheckActiveMembersForm.less: -------------------------------------------------------------------------------- 1 | .cityItems { 2 | display: flex; 3 | 4 | .cityMemberItem { 5 | cursor: pointer; 6 | } 7 | 8 | .cityMemberItem :hover { 9 | text-decoration: underline; 10 | } 11 | 12 | .name { 13 | text-align: center; 14 | align-items: center; 15 | -webkit-line-clamp: 1; 16 | } 17 | } 18 | 19 | .formField { 20 | align-items: center; 21 | } -------------------------------------------------------------------------------- /src/pages/Regions/RegionDetailDrawer.less: -------------------------------------------------------------------------------- 1 | .cityDetail { 2 | .detailsForm { 3 | .ant-form-item-label { 4 | padding: 0; 5 | } 6 | 7 | .ant-input[disabled] { 8 | color: rgba(0, 0, 0, 0.85); 9 | cursor: default; 10 | } 11 | } 12 | } 13 | 14 | .ant-drawer-content-wrapper { 15 | width: auto; 16 | 17 | @media (max-width: 768px) { 18 | width: 75%; 19 | } 20 | } -------------------------------------------------------------------------------- /src/RouteWithLayout.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Route } from "react-router-dom"; 3 | 4 | export default function RouteWithLayout({ layout, component, ...rest }: any) { 5 | return ( 6 | 9 | React.createElement( 10 | layout, 11 | props, 12 | React.createElement(component, props) 13 | ) 14 | } 15 | /> 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/pages/UserTable/Interfaces/TableFilterParameters.tsx: -------------------------------------------------------------------------------- 1 | interface TableFilterParameters { 2 | Page: number; 3 | PageSize: number; 4 | Cities?: Array; 5 | Regions?: Array; 6 | Clubs?: Array; 7 | Degrees?: Array; 8 | Tab: string; 9 | SortKey: number; 10 | FilterRoles?: Array; 11 | FilterKadras?: Array; 12 | SearchData: string; 13 | } 14 | 15 | export default TableFilterParameters; 16 | -------------------------------------------------------------------------------- /src/pages/userPage/EditUserPage/EditUserPage.less: -------------------------------------------------------------------------------- 1 | .ant-popover-message-title{ 2 | padding-left: 0px !important; 3 | } 4 | 5 | .buttons{ 6 | display: flex; 7 | justify-content: center; 8 | padding-top: 10px; 9 | } 10 | 11 | .buttons Button{ 12 | margin-right: 10px; 13 | margin-left: 10px; 14 | width: 200px; 15 | } 16 | 17 | @media(max-width: 768px){ 18 | .buttons{ 19 | flex-direction: column; 20 | } 21 | } -------------------------------------------------------------------------------- /src/pages/City/CityDetailDrawer/CityDetailDrawer.less: -------------------------------------------------------------------------------- 1 | .cityDetail { 2 | .detailsForm { 3 | .ant-form-item-label { 4 | padding: 0; 5 | } 6 | 7 | .ant-input[disabled] { 8 | color: rgba(0, 0, 0, 0.85); 9 | cursor: default; 10 | } 11 | } 12 | } 13 | 14 | .ant-drawer-content-wrapper { 15 | width: auto; 16 | 17 | @media (max-width: 768px) { 18 | width: 75%; 19 | } 20 | } -------------------------------------------------------------------------------- /src/pages/Club/ClubDetailDrawer/ClubDetailDrawer.less: -------------------------------------------------------------------------------- 1 | .ClubDetail { 2 | .detailsForm { 3 | .ant-form-item-label { 4 | padding: 0; 5 | } 6 | 7 | .ant-input[disabled] { 8 | color: rgba(0, 0, 0, 0.85); 9 | cursor: default; 10 | } 11 | } 12 | } 13 | 14 | .ant-drawer-content-wrapper { 15 | width: auto; 16 | 17 | @media (max-width: 768px) { 18 | width: 75%; 19 | } 20 | } -------------------------------------------------------------------------------- /src/pages/Regions/CheckActiveCitiesForm.less: -------------------------------------------------------------------------------- 1 | .cityItems { 2 | display: flex; 3 | margin-top: 5px; 4 | 5 | .cityMemberItem { 6 | cursor: pointer; 7 | } 8 | 9 | .cityMemberItem :hover { 10 | text-decoration: underline; 11 | } 12 | 13 | .name { 14 | text-align: center; 15 | align-items: center; 16 | -webkit-line-clamp: 1; 17 | } 18 | } 19 | 20 | .formField { 21 | align-items: center; 22 | } -------------------------------------------------------------------------------- /src/pages/UserTable/UserComment.less: -------------------------------------------------------------------------------- 1 | .commentContainer { 2 | display: inline-flex; 3 | align-items: center; 4 | justify-content: space-between; 5 | width: 100%; 6 | 7 | .commentText { 8 | display: -webkit-box; 9 | -webkit-line-clamp: 10; 10 | -webkit-box-orient: vertical; 11 | overflow: hidden; 12 | } 13 | 14 | .commentIcon { 15 | font-size: 1em; 16 | margin-left: 10px; 17 | } 18 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .idea/ 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # VSCode 27 | /.vscode 28 | -------------------------------------------------------------------------------- /src/models/Events/EventDetails.ts: -------------------------------------------------------------------------------- 1 | import { EventInformation } from "./EventInformation"; 2 | 3 | export interface EventDetails { 4 | event: EventInformation; 5 | participantAssessment: number; 6 | isUserParticipant: boolean; 7 | isUserApprovedParticipant: boolean; 8 | isUserUndeterminedParticipant: boolean; 9 | isUserRejectedParticipant: boolean; 10 | isEventFinished: boolean; 11 | isEventNotApproved: boolean; 12 | canEstimate: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /src/AuthLocalStorage.ts: -------------------------------------------------------------------------------- 1 | export default class AuthLocalStorage { 2 | static STORAGE_KEY: string = "token"; 3 | 4 | static getToken() { 5 | return window.localStorage.getItem(AuthLocalStorage.STORAGE_KEY); 6 | } 7 | 8 | static setToken(token: string) { 9 | window.localStorage.setItem(AuthLocalStorage.STORAGE_KEY, token); 10 | } 11 | 12 | static removeToken(): void { 13 | window.localStorage.removeItem(AuthLocalStorage.STORAGE_KEY); 14 | } 15 | } -------------------------------------------------------------------------------- /src/models/EventUser/CreatedEvents.tsx: -------------------------------------------------------------------------------- 1 | export default class CreatedEvents { 2 | id: number; 3 | eventName: string; 4 | eventDateStart?: Date; 5 | eventDateEnd?: Date; 6 | eventStatusID: number; 7 | eventTypeID: number; 8 | 9 | constructor() { 10 | this.id = 0; 11 | this.eventName = ""; 12 | this.eventDateStart = undefined; 13 | this.eventDateEnd = undefined; 14 | this.eventStatusID = 0; 15 | this.eventTypeID = 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/ClubAnnualReportForm/ClubAnnualReportForm.less: -------------------------------------------------------------------------------- 1 | .clubAnnualReportResponsiveCols { 2 | align-self: flex-end; 3 | } 4 | 5 | .clubAnnualReportFormDescription { 6 | width: 100%; 7 | word-break: break-all; 8 | } 9 | 10 | .ClubAnnualReportFormDescriptionDate { 11 | justify-content: right; 12 | } 13 | 14 | @media (max-width: 780px) { 15 | .ClubAnnualReportFormDescriptionDate { 16 | justify-content: left; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/Footer/Footer.module.css: -------------------------------------------------------------------------------- 1 | .footerContainer{ 2 | text-align: center; 3 | padding: 10px 0px 10px; 4 | user-select: none; 5 | } 6 | .footerContacts{ 7 | display: flex; 8 | justify-content: center; 9 | } 10 | .footerContacts a{ 11 | margin-right: 10px; 12 | } 13 | .footerContacts img{ 14 | width: 45px; 15 | } 16 | .footerContacts img:hover{ 17 | transform: scale(1.3); 18 | } 19 | .footerCopyright{ 20 | margin: 10px 0 0; 21 | } 22 | -------------------------------------------------------------------------------- /src/models/Region/RegionUser.tsx: -------------------------------------------------------------------------------- 1 | export default class RegionUser { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | fatherName: string; 6 | imagePath: string; 7 | email: string; 8 | phoneNumber: string; 9 | 10 | constructor() { 11 | this.id = ""; 12 | this.firstName = ""; 13 | this.lastName = ""; 14 | this.fatherName = ""; 15 | this.imagePath = ""; 16 | this.email = ""; 17 | this.phoneNumber = ""; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/api/regionsBoardApi.tsx: -------------------------------------------------------------------------------- 1 | import api from "./api"; 2 | 3 | export const getUserAccess = async (userId: string) => { 4 | return await api 5 | .get(`RegionsBoard/GetUserAccesses/${userId}`, userId) 6 | .catch((error) => { 7 | throw error; 8 | }); 9 | }; 10 | 11 | export const getDocs = async (regionId: number) => { 12 | return await api 13 | .get("RegionsBoard/getDocs/" + regionId, regionId) 14 | .catch((error) => { 15 | throw error; 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 4 | -webkit-font-smoothing: antialiased; 5 | -moz-osx-font-smoothing: grayscale; 6 | min-width: 300px; 7 | width: auto !important; 8 | width: 300px; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; 13 | } -------------------------------------------------------------------------------- /src/pages/userPage/Menu/Menu.less: -------------------------------------------------------------------------------- 1 | .wrapperMenu{ 2 | width:100%; 3 | display: contents; 4 | align-self: center; 5 | } 6 | 7 | .menu{ 8 | background-color: rgb(240, 245, 240)!important; 9 | border-bottom: 1px solid #dee2e6; 10 | display: flex; 11 | justify-content: center; 12 | } 13 | 14 | @media(max-width: 1174px){ 15 | .menuItem{ 16 | padding: 0 15px; 17 | } 18 | } 19 | @media(max-width: 1000px){ 20 | .menuItem{ 21 | padding: 0 5px; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/UserPrecautionTableItem.ts: -------------------------------------------------------------------------------- 1 | import UserPrecautionStatus from "./UserPrecautionStatus"; 2 | 3 | type UserPrecautionTableItem = { 4 | id: number; 5 | precautionId: number; 6 | precautionName: string; 7 | reporter: string; 8 | reason: string; 9 | status: UserPrecautionStatus | null; 10 | number: number; 11 | date: Date; 12 | endDate: Date; 13 | isActive: boolean; 14 | userId: string; 15 | userName: string; 16 | }; 17 | export default UserPrecautionTableItem; 18 | -------------------------------------------------------------------------------- /src/models/City/CityDocument.tsx: -------------------------------------------------------------------------------- 1 | import CityDocumentType from "./CityDocumentType"; 2 | 3 | export default class CityDocument { 4 | id: number; 5 | cityDocumentType: CityDocumentType; 6 | blobName: string; 7 | fileName: string; 8 | submitDate?: string; 9 | cityId: number; 10 | 11 | constructor() { 12 | this.id = 0; 13 | this.cityDocumentType = new CityDocumentType(); 14 | this.blobName = ""; 15 | this.fileName = ""; 16 | this.submitDate = undefined; 17 | this.cityId = 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/models/Club/ClubDocument.tsx: -------------------------------------------------------------------------------- 1 | import ClubDocumentType from "./ClubDocumentType"; 2 | 3 | export default class ClubDocument { 4 | id: number; 5 | clubDocumentType: ClubDocumentType; 6 | blobName: string; 7 | fileName: string; 8 | submitDate?: string; 9 | ClubId: number; 10 | 11 | constructor() { 12 | this.id = 0; 13 | this.clubDocumentType = new ClubDocumentType(); 14 | this.blobName = ""; 15 | this.fileName = ""; 16 | this.submitDate = undefined; 17 | this.ClubId = 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/userPage/ActiveMembership/PlastDegree/FormAddPlastDegree.module.css: -------------------------------------------------------------------------------- 1 | 2 | .inputField{ 3 | float: right; 4 | text-align: left; 5 | max-width: 320px; 6 | } 7 | 8 | .selectField{ 9 | float: center; 10 | text-align: center; 11 | max-width: 100%; 12 | width: 470px; 13 | } 14 | 15 | .formField{ 16 | width: 100%; 17 | } 18 | 19 | .cardButton{ 20 | float: center; 21 | margin-top: 7px; 22 | border-color: #3c5438; 23 | max-width: 100%; 24 | width: 470px; 25 | } -------------------------------------------------------------------------------- /src/components/ButtonCollapse/ButtonCollapse.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button } from "antd"; 3 | import classes from "./ButtonCollapse.module.css"; 4 | import { MinusOutlined } from "@ant-design/icons"; 5 | type props = { 6 | handleClose: () => void; 7 | }; 8 | const ButtonCollapse = ({ handleClose }: props) => { 9 | return ( 10 | 13 | ); 14 | }; 15 | export default ButtonCollapse; 16 | -------------------------------------------------------------------------------- /src/pages/Spinner/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Space, Spin } from "antd"; 3 | import "./Spinner.less"; 4 | import { LoadingOutlined } from "@ant-design/icons"; 5 | 6 | const Spinner = () => { 7 | const antIcon = ; 8 | 9 | return ( 10 |
11 | 12 | 13 | 14 |
15 | ); 16 | }; 17 | 18 | export default Spinner; 19 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/RegionAnnualReportQuestions.ts: -------------------------------------------------------------------------------- 1 | interface RegionAnnualReportQuestions { 2 | stateOfPreparation: string; 3 | characteristic: string; 4 | statusOfStrategy: string; 5 | involvementOfVolunteers: string; 6 | trainedNeeds: string; 7 | publicFunding: string; 8 | churchCooperation: string; 9 | socialProjects: string; 10 | problemSituations: string; 11 | importantNeeds: string; 12 | successStories: string; 13 | fundraising: string; 14 | } 15 | 16 | export default RegionAnnualReportQuestions; 17 | -------------------------------------------------------------------------------- /src/components/PrivateLayout/PrivateLayout.module.css: -------------------------------------------------------------------------------- 1 | .profilePhoto { 2 | text-align: center; 3 | margin: 5px 0; 4 | } 5 | 6 | .profilePhoto img { 7 | max-width: 80px; 8 | } 9 | 10 | .sidebar { 11 | position: fixed; 12 | height: 100vh; 13 | z-index: 200; 14 | top: 0; 15 | box-shadow: 2px 0 5px 2px #00000066; 16 | } 17 | 18 | .backButton { 19 | position: fixed; 20 | width: 36px !important; 21 | background-color: #3c5438; 22 | color: white; 23 | z-index: 2; 24 | top: 120px; 25 | left: 0; 26 | } -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/Dropdowns/SavedDropdown/SavedDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | import AnnualReport from "../../../Interfaces/AnnualReport"; 3 | 4 | interface Props { 5 | record: AnnualReport; 6 | pageX: number; 7 | pageY: number; 8 | userAnnualReportAccess: IUserAnnualReportAccess; 9 | showDropdown: boolean; 10 | onView: (id: number) => Promise; 11 | onViewPDF: (id: number) => Promise; 12 | } 13 | 14 | export default Props; 15 | -------------------------------------------------------------------------------- /src/assets/images/lgbt.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/City/City/CheckActiveMembersForm.less: -------------------------------------------------------------------------------- 1 | .cityItems { 2 | display: flex; 3 | 4 | .cityMemberItem { 5 | cursor: pointer; 6 | } 7 | 8 | .cityMemberItem :hover { 9 | text-decoration: underline; 10 | } 11 | 12 | .cityMemberItem.notAccess :hover { 13 | text-decoration: none; 14 | cursor: default; 15 | } 16 | 17 | .name { 18 | text-align: center; 19 | align-items: center; 20 | -webkit-line-clamp: 1; 21 | } 22 | } 23 | .formField { 24 | align-items: center; 25 | } -------------------------------------------------------------------------------- /src/models/GoverningBody/Sector/SectorDocument.tsx: -------------------------------------------------------------------------------- 1 | import SectorDocumentType from "./SectorDocumentType"; 2 | 3 | export default class SectorDocument { 4 | id: number; 5 | sectorDocumentType: SectorDocumentType; 6 | blobName: string; 7 | fileName: string; 8 | submitDate?: string; 9 | sectorId: number; 10 | 11 | constructor() { 12 | this.id = 0; 13 | this.sectorDocumentType = new SectorDocumentType(); 14 | this.blobName = ""; 15 | this.fileName = ""; 16 | this.submitDate = undefined; 17 | this.sectorId = 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/Regions/AddRegionSecretaryForm.less: -------------------------------------------------------------------------------- 1 | .formAddSecretaryModal { 2 | .ant-select { 3 | max-width: 310px; 4 | } 5 | 6 | .formItemExplain { 7 | max-width: 310px; 8 | width: 100%; 9 | float: right; 10 | } 11 | 12 | .ant-picker { 13 | max-width: 310px; 14 | } 15 | 16 | @media (max-width: 575px) { 17 | .ant-select { 18 | max-width: 100%; 19 | } 20 | 21 | .formItemExplain { 22 | max-width: 100%; 23 | } 24 | 25 | .ant-picker { 26 | max-width: 100%; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/Error/NotAuthorized.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Result, Button } from "antd"; 3 | import classes from "./Errors.module.css"; 4 | 5 | const NotAuthorizedPage = () => { 6 | return ( 7 | 13 | На головну 14 | 15 | } 16 | /> 17 | ); 18 | }; 19 | export default NotAuthorizedPage; 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": false, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | "jsx": "react" 17 | }, 18 | "include": ["src", "craco.config.js"] 19 | } 20 | -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyUser.tsx: -------------------------------------------------------------------------------- 1 | export default class GoverningBodyUser { 2 | id: string; 3 | firstName: string; 4 | lastName: string; 5 | imagePath: string; 6 | email: string; 7 | phoneNumber: string; 8 | isInLowerRole: boolean; 9 | isInDeputyRole: boolean; 10 | 11 | constructor() { 12 | this.id = ""; 13 | this.firstName = ""; 14 | this.lastName = ""; 15 | this.imagePath = ""; 16 | this.email = ""; 17 | this.phoneNumber = ""; 18 | this.isInLowerRole = false; 19 | this.isInDeputyRole = false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/pages/Statistics/Interfaces/StatisticsItemIndicator.tsx: -------------------------------------------------------------------------------- 1 | enum StatisticsItemIndicator { 2 | NumberOfPtashata, 3 | NumberOfNovatstva, 4 | NumberOfUnatstva, 5 | NumberOfUnatstvaNoname, 6 | NumberOfUnatstvaSupporters, 7 | NumberOfUnatstvaMembers, 8 | NumberOfUnatstvaProspectors, 9 | NumberOfUnatstvaSkobVirlyts, 10 | NumberOfSenior, 11 | NumberOfSeniorPlastynSupporters, 12 | NumberOfSeniorPlastynMembers, 13 | NumberOfSeigneur, 14 | NumberOfSeigneurSupporters, 15 | NumberOfSeigneurMembers, 16 | } 17 | 18 | export default StatisticsItemIndicator; 19 | -------------------------------------------------------------------------------- /src/models/Precaution/PrecautionTableSettings.tsx: -------------------------------------------------------------------------------- 1 | export default class PrecautionTableSettings { 2 | sortByOrder?: Array; 3 | statusFilter?: Array; 4 | precautionNameFilter?: Array; 5 | dateFilter?: Array; 6 | searchedData: string; 7 | page: number; 8 | pageSize: number; 9 | 10 | constructor() { 11 | this.sortByOrder = []; 12 | this.statusFilter = []; 13 | this.precautionNameFilter = []; 14 | this.dateFilter = []; 15 | this.searchedData = ""; 16 | this.page = 0; 17 | this.pageSize = 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForClubAnnualReports/SavedDropdown/SavedDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | import ClubAnnualReport from "../../../Interfaces/ClubAnnualReport"; 3 | 4 | interface Props { 5 | record: ClubAnnualReport; 6 | pageX: number; 7 | pageY: number; 8 | userAnnualReportAccess: IUserAnnualReportAccess; 9 | showDropdown: boolean; 10 | onView: (id: number) => Promise; 11 | onViewPDF: (id: number) => Promise; 12 | } 13 | 14 | export default Props; 15 | -------------------------------------------------------------------------------- /src/pages/City/AddAdministratorModal/AddCitiesSecretaryForm.less: -------------------------------------------------------------------------------- 1 | .formAddSecretaryModal { 2 | .ant-select { 3 | max-width: 310px; 4 | } 5 | 6 | .formItemExplain { 7 | max-width: 310px; 8 | width: 100%; 9 | float: right; 10 | } 11 | 12 | .ant-picker { 13 | max-width: 310px; 14 | } 15 | 16 | @media (max-width: 575px) { 17 | .ant-select { 18 | max-width: 100%; 19 | } 20 | 21 | .formItemExplain { 22 | max-width: 100%; 23 | } 24 | 25 | .ant-picker { 26 | max-width: 100%; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/Club/AddAdministratorModal/AddClubsSecretaryForm.less: -------------------------------------------------------------------------------- 1 | .formAddSecretaryModal { 2 | .ant-select { 3 | max-width: 310px; 4 | } 5 | 6 | .formItemExplain { 7 | max-width: 310px; 8 | width: 100%; 9 | float: right; 10 | } 11 | 12 | .ant-picker { 13 | max-width: 310px; 14 | } 15 | 16 | @media (max-width: 575px) { 17 | .ant-select { 18 | max-width: 100%; 19 | } 20 | 21 | .formItemExplain { 22 | max-width: 100%; 23 | } 24 | 25 | .ant-picker { 26 | max-width: 100%; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/models/City/CityAdmin.tsx: -------------------------------------------------------------------------------- 1 | import AdminType from "../Admin/AdminType"; 2 | import CityUser from "./CityUser"; 3 | 4 | export default class CityAdmin { 5 | id: number; 6 | userId: string; 7 | user: CityUser; 8 | adminType: AdminType; 9 | cityId: number; 10 | startDate?: string; 11 | endDate?: string; 12 | 13 | constructor() { 14 | this.id = 0; 15 | this.userId = ""; 16 | this.user = new CityUser(); 17 | this.adminType = new AdminType(); 18 | this.cityId = 0; 19 | this.startDate = undefined; 20 | this.endDate = undefined; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/models/Club/ClubAdmin.tsx: -------------------------------------------------------------------------------- 1 | import AdminType from "../Admin/AdminType"; 2 | import ClubUser from "./ClubUser"; 3 | 4 | export default class ClubAdmin { 5 | id: number; 6 | userId: string; 7 | user: ClubUser; 8 | adminType: AdminType; 9 | clubId: number; 10 | startDate?: string; 11 | endDate?: string; 12 | 13 | constructor() { 14 | this.id = 0; 15 | this.userId = ""; 16 | this.user = new ClubUser(); 17 | this.adminType = new AdminType(); 18 | this.clubId = 0; 19 | this.startDate = undefined; 20 | this.endDate = undefined; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/UserPrecaution.ts: -------------------------------------------------------------------------------- 1 | import Precaution from "./Precaution"; 2 | import User from "../../Distinction/Interfaces/User"; 3 | import UserPrecautionStatus from "./UserPrecautionStatus"; 4 | 5 | type UserPrecaution = { 6 | id: number; 7 | precautionId: number; 8 | precaution: Precaution; 9 | reporter: string; 10 | reason: string; 11 | status: UserPrecautionStatus | null; 12 | number: number; 13 | date: Date; 14 | endDate: Date; 15 | isActive: boolean; 16 | userId: string; 17 | user: User; 18 | }; 19 | 20 | export default UserPrecaution; 21 | -------------------------------------------------------------------------------- /src/api/termsApi.tsx: -------------------------------------------------------------------------------- 1 | import TermsOfUse from "../models/TermsOfUse/TermsOfUseModel"; 2 | import api from "./api"; 3 | 4 | const getTerms = async () => { 5 | return (await api.get(`Terms/Data`)).data; 6 | }; 7 | 8 | const getUsersId = async () => { 9 | return (await api.get(`Terms/UsersId`)).data; 10 | }; 11 | 12 | const putTermById = async (data: TermsOfUse) => { 13 | return await api.put(`Terms/Data/${data.termsId}`, data).catch((error) => { 14 | throw new Error(error); 15 | }); 16 | }; 17 | 18 | export default { 19 | getTerms, 20 | getUsersId, 21 | putTermById, 22 | }; 23 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/ClubAnnualReportCreate/ClubAnnualReportCreate.less: -------------------------------------------------------------------------------- 1 | .annualreport-form { 2 | background-color: #ffffff; 3 | border: 2px solid #3c5438; 4 | border-radius: 15px; 5 | box-shadow: 0px 4px 4px rgba(3, 80, 0, 0.65); 6 | padding: 1%; 7 | } 8 | 9 | .annualreport-modal { 10 | .textCenter { 11 | text-align: center; 12 | } 13 | 14 | .container { 15 | width: 100%; 16 | } 17 | } 18 | 19 | .clubButtons { 20 | text-align: center; 21 | 22 | .ant-btn-primary { 23 | width: 65%; 24 | margin: 5px; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/userPage/ActiveMembership/UserDates/ModalChangeUserDates.module.css: -------------------------------------------------------------------------------- 1 | 2 | .inputField{ 3 | float: right; 4 | text-align: left; 5 | max-width: 320px; 6 | } 7 | 8 | .selectField{ 9 | float: center; 10 | text-align: center; 11 | max-width: 100%; 12 | width: 470px; 13 | } 14 | 15 | .formField{ 16 | width: 100%; 17 | 18 | } 19 | 20 | .formLabel{ 21 | font-size: 16px; 22 | } 23 | 24 | .cardButton{ 25 | float: center; 26 | margin-top: 7px; 27 | border-color: #3c5438; 28 | max-width: 100%; 29 | width: 470px; 30 | } -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyAnnouncement.tsx: -------------------------------------------------------------------------------- 1 | export default class GoverningBodyAnnouncement { 2 | date: Date; 3 | id: number; 4 | governingBodyId?: number; 5 | sectorId?: number; 6 | text: string; 7 | title: string; 8 | user: any; 9 | userId: string; 10 | imagesPresent: boolean; 11 | isPined: boolean; 12 | 13 | constructor() { 14 | this.date = new Date(); 15 | this.id = 0; 16 | this.text = ""; 17 | this.title = ""; 18 | this.user = null; 19 | this.userId = ""; 20 | this.imagesPresent = false; 21 | this.isPined = false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/models/Oblast/UkraineOblasts.ts: -------------------------------------------------------------------------------- 1 | export enum UkraineOblasts { 2 | NotSpecified = 0, 3 | Cherkasy = 1, 4 | Chernihiv, 5 | Chernivtsi, 6 | Crimea, 7 | Dnipropetrovsk, 8 | Donetsk, 9 | IvanoFrankivsk, 10 | Kharkiv, 11 | Kherson, 12 | Khmelnytskyi, 13 | Kyiv, 14 | Kirovohrad, 15 | Luhansk, 16 | Lviv, 17 | Mykolaiv, 18 | Odessa, 19 | Poltava, 20 | Rivne, 21 | Sumy, 22 | Ternopil, 23 | Vinnytsia, 24 | Volyn, 25 | Zakarpattia, 26 | Zaporizhzhia, 27 | Zhytomyr 28 | } 29 | 30 | export default UkraineOblasts; -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/Dropdowns/ConfirmedDropdown/ConfirmedDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | import AnnualReport from "../../../Interfaces/AnnualReport"; 3 | 4 | interface Props { 5 | record: AnnualReport; 6 | pageX: number; 7 | pageY: number; 8 | showDropdown: boolean; 9 | userAnnualReportAccess: IUserAnnualReportAccess; 10 | onView: (id: number) => Promise; 11 | onViewPDF: (id: number) => Promise; 12 | onCancel: (id: number) => Promise; 13 | } 14 | 15 | export default Props; 16 | -------------------------------------------------------------------------------- /src/models/EventUser/EventUser.tsx: -------------------------------------------------------------------------------- 1 | import User from "./User"; 2 | import PlannedEvents from "./PlannedEvents"; 3 | import VisitedEvents from "./VisitedEvents"; 4 | import CreatedEvents from "./CreatedEvents"; 5 | 6 | export default class EventsUser { 7 | user: User; 8 | planedEvents: PlannedEvents[]; 9 | visitedEvents: VisitedEvents[]; 10 | createdEvents: CreatedEvents[]; 11 | 12 | constructor() { 13 | this.user = new User(); 14 | this.planedEvents = [new PlannedEvents()]; 15 | this.visitedEvents = [new VisitedEvents()]; 16 | this.createdEvents = [new CreatedEvents()]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 2 | import { Modal } from "antd"; 3 | import React from "react"; 4 | 5 | const { confirm } = Modal; 6 | 7 | const DeleteConfirm = (id: number, onDelete: any) => { 8 | return confirm({ 9 | title: "Ви справді хочете видалити відзначення цього користувача?", 10 | icon: , 11 | okText: "Так", 12 | cancelText: "Ні", 13 | async onOk() { 14 | onDelete(id); 15 | }, 16 | }); 17 | }; 18 | export default DeleteConfirm; 19 | -------------------------------------------------------------------------------- /src/pages/Error/NotFound.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Result, Button } from "antd"; 3 | import classes from "./Errors.module.css"; 4 | 5 | const NotFoundPage = () => { 6 | return ( 7 | 13 | На головну 14 | 15 | } 16 | /> 17 | ); 18 | }; 19 | export default NotFoundPage; 20 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/MembersStatistic.ts: -------------------------------------------------------------------------------- 1 | interface MembersStatistic { 2 | id: number; 3 | numberOfPtashata: number; 4 | numberOfNovatstva: number; 5 | numberOfUnatstvaNoname: number; 6 | numberOfUnatstvaSupporters: number; 7 | numberOfUnatstvaMembers: number; 8 | numberOfUnatstvaProspectors: number; 9 | numberOfUnatstvaSkobVirlyts: number; 10 | numberOfSeniorPlastynSupporters: number; 11 | numberOfSeniorPlastynMembers: number; 12 | numberOfSeigneurSupporters: number; 13 | numberOfSeigneurMembers: number; 14 | annualReportId: number; 15 | } 16 | 17 | export default MembersStatistic; 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/user-story.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: User story 3 | about: Describe story goal 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **As a** **I want to** <....> **so that** <...> 11 | 12 | **Description** 13 | Describe feature functionality 14 | Add mockup if needed 15 | 16 | ### Acceptance Criteria 17 | A clear and concise description of what you want to happen. 18 | 19 | **Epic link** 20 | E.g.: Epic #100 [Epic](https://jira.softserve.academy/browse/100) 21 | 22 | **Labels to be added** 23 | "User story" ("story"), Priority ("pri: ") 24 | 25 | ### Tasks 26 | 1. - [ ] sample task. 27 | -------------------------------------------------------------------------------- /src/components/NotificationBox/NotificationBox.module.css: -------------------------------------------------------------------------------- 1 | .Footer{ 2 | display: flex; 3 | } 4 | 5 | .Button{ 6 | margin: 20px 0 0 auto; 7 | } 8 | 9 | .NotificationItem{ 10 | width: 100%; 11 | height: 20%; 12 | display: flex; 13 | } 14 | 15 | .NotificationTextBox{ 16 | width: 90%; 17 | height: 100%; 18 | padding: 5px 10px; 19 | font-size: 16px; 20 | } 21 | 22 | .Text{ 23 | width: 100%; 24 | margin-bottom: 15px; 25 | } 26 | 27 | .Date{ 28 | font-size: 14px; 29 | color: grey; 30 | margin: 0; 31 | } 32 | 33 | .Link{ 34 | color: rgb(87 137 78); 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyDocument.tsx: -------------------------------------------------------------------------------- 1 | import GoverningBodyDocumentType from "./GoverningBodyDocumentType"; 2 | 3 | export default class GoverningBodyDocument { 4 | id: number; 5 | governingBodyDocumentType: GoverningBodyDocumentType; 6 | blobName: string; 7 | fileName: string; 8 | submitDate?: string; 9 | governingBodyId: number; 10 | 11 | constructor() { 12 | this.id = 0; 13 | this.governingBodyDocumentType = new GoverningBodyDocumentType(); 14 | this.blobName = ""; 15 | this.fileName = ""; 16 | this.submitDate = undefined; 17 | this.governingBodyId = 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/KadraVykhovnykiv/Form.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | float: right; 6 | } 7 | .cardButton>* { 8 | margin-right: 8px; 9 | } 10 | .formField { 11 | max-width: 370px; 12 | min-width: 370px; 13 | } 14 | 15 | .selectField { 16 | max-width: 370px; 17 | min-width: 370px; 18 | } 19 | 20 | @media(max-width: 400px) { 21 | .formField{ 22 | max-width: 100%; 23 | min-width: 100%; 24 | } 25 | .selectField { 26 | max-width: 100%; 27 | min-width: 100%; 28 | } 29 | } 30 | .buttons{ 31 | margin-right: 0px !important; 32 | margin-left: 7px; 33 | } -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForClubAnnualReports/ConfirmedDropdown/ConfirmedDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | import ClubAnnualReport from "../../../Interfaces/ClubAnnualReport"; 3 | 4 | interface Props { 5 | record: ClubAnnualReport; 6 | pageX: number; 7 | pageY: number; 8 | showDropdown: boolean; 9 | userAnnualReportAccess: IUserAnnualReportAccess; 10 | onView: (id: number) => Promise; 11 | onViewPDF: (id: number) => Promise; 12 | onCancel: (id: number) => Promise; 13 | } 14 | 15 | export default Props; 16 | -------------------------------------------------------------------------------- /src/pages/DecisionTable/FormAddDecision.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content: flex-end; 5 | float: right; 6 | } 7 | 8 | .cardButton>* { 9 | margin-right: 8px; 10 | } 11 | 12 | .formField { 13 | max-width: 370px; 14 | } 15 | 16 | .selectField { 17 | max-width: 370px; 18 | min-width: 370px; 19 | } 20 | 21 | @media(max-width: 400px) { 22 | .formField{ 23 | max-width: 100%; 24 | min-width: 100%; 25 | } 26 | .selectField { 27 | max-width: 100%; 28 | min-width: 100%; 29 | } 30 | } 31 | .buttons { 32 | margin-left: 7px; 33 | margin-right: 0px; 34 | } 35 | -------------------------------------------------------------------------------- /src/models/Admin/AdminTypesEnum.ts: -------------------------------------------------------------------------------- 1 | export enum AdminTypes { 2 | Admin = 1, 3 | Supporter, 4 | PlastMember, 5 | PlastHead, 6 | EventAdministrator, 7 | KurinHead, 8 | KurinSecretary, 9 | OkrugaHead, 10 | OkrugaSecretary, 11 | CityHead, 12 | CitySecretary, 13 | FormerPlastMember, 14 | RegisteredUser, 15 | Interested, 16 | CityHeadDeputy, 17 | OkrugaHeadDeputy, 18 | KurinHeadDeputy, 19 | RegionBoardHead, 20 | GoverningBodyAdmin, 21 | GoverningBodyHead, 22 | GoverningBodySecretary, 23 | GoverningBodySectorHead, 24 | GoverningBodySectorSecretary, 25 | } 26 | -------------------------------------------------------------------------------- /src/models/EventEdit/EventEdit.tsx: -------------------------------------------------------------------------------- 1 | import Event from "./Event"; 2 | import Commandant from "./Commandant"; 3 | import Alternate from "./Alternate"; 4 | import Bunchuzhnyi from "./Bunchuzhnyi"; 5 | import Pysar from "./Pysar"; 6 | 7 | export default class EventEdit { 8 | event: Event; 9 | commandant: Commandant; 10 | alternate: Alternate; 11 | bunchuzhnyi: Bunchuzhnyi; 12 | pysar: Pysar; 13 | 14 | constructor() { 15 | this.event = new Event(); 16 | this.commandant = new Commandant(); 17 | this.alternate = new Alternate(); 18 | this.bunchuzhnyi = new Bunchuzhnyi(); 19 | this.pysar = new Pysar(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/pages/City/AddAdministratorModal/AddAdministrationModal.less: -------------------------------------------------------------------------------- 1 | .addAdministrationModal { 2 | .adminTypeFormItem { 3 | margin-bottom: 12px; 4 | } 5 | 6 | .ant-form-horizontal .ant-form-item-label { 7 | padding: 0; 8 | } 9 | 10 | .formSelect { 11 | width: 100%; 12 | } 13 | 14 | .cancelConfirmButtons { 15 | margin-bottom: 0px; 16 | } 17 | 18 | .cardButton { 19 | margin-bottom: 1.2rem; 20 | } 21 | } 22 | 23 | @media (max-width: 575px) { 24 | .addAdministrationModal { 25 | .cancelConfirmButtons { 26 | .publishButton { 27 | text-align: end; 28 | } 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/pages/City/City/Form.module.css: -------------------------------------------------------------------------------- 1 | .inputField{ 2 | float: right; 3 | text-align: left; 4 | max-width: 320px; 5 | width:320px; 6 | } 7 | 8 | @media (max-width: 576px){ 9 | .inputField{ 10 | width: 100%; 11 | } 12 | } 13 | 14 | .selectField { 15 | float: right; 16 | text-align: left; 17 | width:320px; 18 | } 19 | 20 | .formField { 21 | width: 100%; 22 | } 23 | 24 | .cardButton{ 25 | float: right; 26 | inline-size: -webkit-fill-available; 27 | margin-top: 7px; 28 | color:#3c5438; 29 | border-color: #3c5438; 30 | max-width: 320px; 31 | min-width: 320px; 32 | } -------------------------------------------------------------------------------- /src/pages/Club/Club/Form.module.css: -------------------------------------------------------------------------------- 1 | .inputField{ 2 | float: right; 3 | text-align: left; 4 | max-width: 320px; 5 | width:320px; 6 | } 7 | 8 | @media (max-width: 576px){ 9 | .inputField{ 10 | width: 100%; 11 | } 12 | } 13 | 14 | .selectField { 15 | float: right; 16 | text-align: left; 17 | width:320px; 18 | } 19 | 20 | .formField { 21 | width: 100%; 22 | } 23 | 24 | .cardButton{ 25 | float: right; 26 | inline-size: -webkit-fill-available; 27 | margin-top: 7px; 28 | color:#3c5438; 29 | border-color: #3c5438; 30 | max-width: 320px; 31 | min-width: 320px; 32 | } -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: "@typescript-eslint/parser", 4 | parserOptions: { 5 | project: "./tsconfig.json", 6 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 7 | sourceType: "module", // Allows for the use of imports 8 | }, 9 | extends: [ 10 | "airbnb-typescript", 11 | "prettier", 12 | "prettier/@typescript-eslint", 13 | "prettier/react", 14 | ], 15 | rules: { 16 | "react/jsx-props-no-spreading": "off", 17 | "no-nested-ternary": "off", 18 | "no-console": "off", 19 | "jsx-a11y/click-events-have-key-events": "off", 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /src/pages/userPage/Secretaries/SecretaryModel.tsx: -------------------------------------------------------------------------------- 1 | import CityUser from "../../../models/City/CityUser"; 2 | 3 | interface SecretaryModel { 4 | id: number; 5 | user: CityUser; 6 | adminType: string; 7 | startDate: Date; 8 | endDate: Date; 9 | club?: { 10 | id: number; 11 | name: string; 12 | }; 13 | city?: { 14 | id: number; 15 | name: string; 16 | }; 17 | region?: { 18 | id: number; 19 | name: string; 20 | }; 21 | governingBody?: { 22 | id: number; 23 | name: string; 24 | }; 25 | sector?: { 26 | id: number; 27 | name: string; 28 | }; 29 | } 30 | 31 | export default SecretaryModel; 32 | -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyProfile.tsx: -------------------------------------------------------------------------------- 1 | import GoverningBodyAdmin from "./GoverningBodyAdmin"; 2 | 3 | export default class GoverningBodyProfile { 4 | id: number; 5 | description: string; 6 | email: string; 7 | governingBodyName: string; 8 | logo: string | null; 9 | phoneNumber: string; 10 | head: GoverningBodyAdmin; 11 | isActive: boolean; 12 | 13 | constructor() { 14 | this.id = 0; 15 | this.description = ""; 16 | this.email = ""; 17 | this.governingBodyName = ""; 18 | this.logo = ""; 19 | this.phoneNumber = ""; 20 | this.head = new GoverningBodyAdmin(); 21 | this.isActive = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/models/GoverningBody/Sector/SectorProfile.tsx: -------------------------------------------------------------------------------- 1 | import SectorAdmin from "./SectorAdmin"; 2 | 3 | export default class SectorProfile { 4 | id: number; 5 | governingBodyId: number; 6 | description: string; 7 | email: string; 8 | name: string; 9 | logo: string | null; 10 | phoneNumber: string; 11 | head: SectorAdmin; 12 | isActive: boolean; 13 | 14 | constructor() { 15 | this.id = 0; 16 | this.governingBodyId = 0; 17 | this.description = ""; 18 | this.email = ""; 19 | this.name = ""; 20 | this.logo = ""; 21 | this.phoneNumber = ""; 22 | this.head = new SectorAdmin(); 23 | this.isActive = true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/columnsClubsMembers.tsx: -------------------------------------------------------------------------------- 1 | import CityUser from "../../models/City/CityUser"; 2 | 3 | const columns = [ 4 | { 5 | title: "№", 6 | dataIndex: "id", 7 | }, 8 | { 9 | title: "Пластовий ступінь", 10 | dataIndex: "id", 11 | }, 12 | { 13 | title: "Ім’я, Прізвище", 14 | dataIndex: "id", 15 | }, 16 | { 17 | title: "Стан в курені (дійсний член чи прихильник)", 18 | dataIndex: "user", 19 | render: (user: CityUser) => { 20 | return user.firstName + " " + user.lastName; 21 | }, 22 | }, 23 | { 24 | title: "Станиця", 25 | dataIndex: "club", 26 | }, 27 | ]; 28 | export default columns; 29 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventCategoriesEdit/EventCategoriesEditFormValidators.ts: -------------------------------------------------------------------------------- 1 | import { Rule } from "antd/lib/form"; 2 | import { 3 | emptyInput, 4 | inputWhiteSpacesAtTheBeginningAndTheEnd, 5 | maxLength, 6 | } from "../../../../components/Notifications/Messages"; 7 | 8 | const inputMaxLength = 200; 9 | 10 | export const eventCategoryInputValidator: Rule[] = [ 11 | { 12 | required: true, 13 | message: emptyInput(), 14 | }, 15 | { 16 | pattern: /^\S.*\S$/, 17 | message: inputWhiteSpacesAtTheBeginningAndTheEnd("Категорія"), 18 | }, 19 | { 20 | max: inputMaxLength, 21 | message: maxLength(inputMaxLength), 22 | }, 23 | ]; 24 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForRegionReports/ConfirmedDropdown/ConfirmedRegionDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | 3 | interface Props { 4 | regionRecord: { 5 | count: number; 6 | date: Date; 7 | id: number; 8 | regionName: string; 9 | status: number; 10 | total: number; 11 | }; 12 | pageX: number; 13 | pageY: number; 14 | showDropdown: boolean; 15 | userAnnualReportAccess: IUserAnnualReportAccess; 16 | onView: (id: number, year: number) => Promise; 17 | onCancel: (id: number) => Promise; 18 | } 19 | 20 | export default Props; 21 | -------------------------------------------------------------------------------- /src/models/GoverningBody/Sector/SectorAdmin.tsx: -------------------------------------------------------------------------------- 1 | import AdminType from "../../Admin/AdminType"; 2 | import SectorUser from "./SectorUser"; 3 | 4 | export default class SectorAdmin { 5 | id: number; 6 | userId: string; 7 | user: SectorUser; 8 | adminType: AdminType; 9 | sectorId: number; 10 | startDate?: string; 11 | endDate?: string; 12 | workEmail?: string; 13 | 14 | constructor() { 15 | this.id = 0; 16 | this.userId = ""; 17 | this.user = new SectorUser(); 18 | this.adminType = new AdminType(); 19 | this.sectorId = 0; 20 | this.startDate = undefined; 21 | this.endDate = undefined; 22 | this.workEmail = undefined; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/Actions/EventTypes/EventTypes.module.css: -------------------------------------------------------------------------------- 1 | .mainTitle { 2 | text-align: center; 3 | font-size: 40px; 4 | color: #3c5438; 5 | } 6 | .actionsWrapper { 7 | display: flex; 8 | justify-content: center; 9 | flex-wrap: wrap; 10 | } 11 | .imageStyle { 12 | width: 60%; 13 | vertical-align: middle; 14 | } 15 | .imageContainer { 16 | height: 205.93px; 17 | display: flex; 18 | justify-content: center; 19 | align-items: center; 20 | } 21 | .cardStyles { 22 | margin: 15px; 23 | width: 242px; 24 | } 25 | .titleText { 26 | text-align: center; 27 | font-size: 20px; 28 | font-weight: 700; 29 | } 30 | .titleText:hover { 31 | text-decoration: underline; 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/Form.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | float: right; 6 | } 7 | .cardButton>* { 8 | margin-right: 8px; 9 | } 10 | .formField { 11 | max-width: 370px; 12 | min-width: 370px; 13 | } 14 | 15 | .selectField { 16 | max-width: 370px; 17 | min-width: 370px; 18 | } 19 | 20 | @media(max-width: 400px) { 21 | .formField{ 22 | max-width: 100%; 23 | min-width: 100%; 24 | } 25 | .selectField { 26 | max-width: 100%; 27 | min-width: 100%; 28 | } 29 | } 30 | .buttons{ 31 | margin-right: 0px !important; 32 | margin-left: 7px; 33 | } 34 | -------------------------------------------------------------------------------- /web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/models/Distinction/UserDistinction.tsx: -------------------------------------------------------------------------------- 1 | import User from "../UserTable/User"; 2 | import Distinction from "./Distinction"; 3 | 4 | export default class UserDistinction { 5 | id: number; 6 | distinctionId: number; 7 | distinction: Distinction; 8 | reporter: string; 9 | reason: string; 10 | number: number; 11 | date: Date; 12 | userId: string; 13 | user: User; 14 | 15 | constructor() { 16 | this.id = 0; 17 | this.distinctionId = 0; 18 | this.distinction = new Distinction(); 19 | this.reporter = ""; 20 | this.reason = ""; 21 | this.number = 0; 22 | this.date = new Date(); 23 | this.userId = ""; 24 | this.user = new User(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/AnnouncementsTable/Forms/Form.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | float: right; 6 | } 7 | .cardButton>* { 8 | margin-right: 8px; 9 | } 10 | .formField { 11 | max-width: 370px; 12 | min-width: 370px; 13 | } 14 | 15 | .selectField { 16 | max-width: 370px; 17 | min-width: 370px; 18 | } 19 | 20 | @media(max-width: 400px) { 21 | .formField{ 22 | max-width: 100%; 23 | min-width: 100%; 24 | } 25 | .selectField { 26 | max-width: 100%; 27 | min-width: 100%; 28 | } 29 | } 30 | .buttons{ 31 | margin-right: 0px !important; 32 | margin-left: 7px; 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForRegionReports/SavedDropdown/SavedRegionDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | import RegionAnnualReport from "../../../Interfaces/RegionAnnualReports"; 3 | 4 | interface Props { 5 | regionRecord: { 6 | count: number; 7 | date: Date; 8 | id: number; 9 | regionName: string; 10 | status: number; 11 | total: number; 12 | }; 13 | userAnnualReportAccess: IUserAnnualReportAccess; 14 | pageX: number; 15 | pageY: number; 16 | showDropdown: boolean; 17 | onView: (id: number, year: number) => Promise; 18 | } 19 | 20 | export default Props; 21 | -------------------------------------------------------------------------------- /src/pages/Regions/Form.module copy.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .inputField{ 5 | float: right; 6 | text-align: left; 7 | max-width: 320px; 8 | width:320px; 9 | } 10 | 11 | @media (max-width: 576px){ 12 | .inputField{ 13 | width: 100%; 14 | } 15 | } 16 | 17 | 18 | .selectField { 19 | float: right; 20 | text-align: left; 21 | width:320px; 22 | 23 | } 24 | 25 | 26 | .formField { 27 | width: 100%; 28 | } 29 | 30 | .cardButton{ 31 | float: right; 32 | inline-size: -webkit-fill-available; 33 | margin-top: 7px; 34 | color:#3c5438; 35 | border-color: #3c5438; 36 | max-width: 320px; 37 | min-width: 320px; 38 | } -------------------------------------------------------------------------------- /src/pages/GoverningBody/Announcement/Form.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | float: right; 6 | } 7 | .cardButton>* { 8 | margin-right: 8px; 9 | } 10 | .formField { 11 | max-width: 370px; 12 | min-width: 370px; 13 | } 14 | 15 | .selectField { 16 | max-width: 370px; 17 | min-width: 370px; 18 | } 19 | 20 | @media(max-width: 400px) { 21 | .formField{ 22 | max-width: 100%; 23 | min-width: 100%; 24 | } 25 | .selectField { 26 | max-width: 100%; 27 | min-width: 100%; 28 | } 29 | } 30 | .buttons{ 31 | margin-right: 0px !important; 32 | margin-left: 7px; 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/models/UserTable/DropdownFunc.tsx: -------------------------------------------------------------------------------- 1 | export enum DropdownFunc { 2 | CheckProfile = 0, // Перевірити профіль користувача 3 | Delete, // Видалити користувача 4 | EditRegion, // Змінити округу користувача 5 | EditCity, // Змінити станицю користувача 6 | EditClub, // Змінити курінь користувача 7 | EditRole, // Змінити поточний стан користувача 8 | EditGoverningBody, // Змінити Крайовий Провід користувача 9 | DeleteGoverningBody, // Відмінити роль Крайового Адміна 10 | ChangeDegree, // Змінити ступінь користувача 11 | AddDegree, // Прийняти до уладу користувача 12 | DeleteFollower, // Видалити користувача зі списку зголошених 13 | } 14 | 15 | // Displays all possible items in dropdown 16 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/Sector/SectorAnnouncement/Form.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | float: right; 6 | } 7 | .cardButton>* { 8 | margin-right: 8px; 9 | } 10 | .formField { 11 | max-width: 370px; 12 | min-width: 370px; 13 | } 14 | 15 | .selectField { 16 | max-width: 370px; 17 | min-width: 370px; 18 | } 19 | 20 | @media(max-width: 400px) { 21 | .formField{ 22 | max-width: 100%; 23 | min-width: 100%; 24 | } 25 | .selectField { 26 | max-width: 100%; 27 | min-width: 100%; 28 | } 29 | } 30 | .buttons{ 31 | margin-right: 0px !important; 32 | margin-left: 7px; 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 as builder 2 | 3 | # install and cache app dependencies 4 | COPY package*.json ./ 5 | RUN npm install && mkdir /EPlast-Client && mv ./node_modules ./EPlast-Client 6 | 7 | WORKDIR /EPlast-Client 8 | 9 | COPY . . 10 | 11 | ENV NODE_OPTIONS=--max_old_space_size=4096 12 | RUN npm run build 13 | 14 | 15 | # ------------------------------------------------------ 16 | # Production Build 17 | # ------------------------------------------------------ 18 | FROM nginx:alpine 19 | COPY --from=builder /EPlast-Client/build /usr/share/nginx/html 20 | RUN rm /etc/nginx/conf.d/default.conf 21 | COPY nginx/nginx.conf /etc/nginx/conf.d 22 | EXPOSE 80 23 | 24 | ENTRYPOINT ["nginx", "-g", "daemon off;"] 25 | 26 | -------------------------------------------------------------------------------- /src/components/Notifications/Modals.tsx: -------------------------------------------------------------------------------- 1 | import { ExclamationCircleOutlined, WarningOutlined } from "@ant-design/icons"; 2 | import { Modal } from "antd"; 3 | import React from "react"; 4 | 5 | export const showRegionNameExistsModal = () => { 6 | return Modal.error({ 7 | title: "Округа з такою назвою вже існує! Будь ласка, вкажіть іншу назву.", 8 | icon: , 9 | okText: "Ок", 10 | maskClosable: true, 11 | }); 12 | }; 13 | 14 | export const showLogOutModal = () => { 15 | return Modal.warning({ 16 | title: "Вам змінили права доступу! Вас буде вилогувано із системи через одну хвилину", 17 | icon: , 18 | okText: "Ок", 19 | maskClosable: false 20 | }); 21 | } -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/FormEditDistinctionTypes/DistinctionTypeInputValidator.tsx: -------------------------------------------------------------------------------- 1 | import { Rule } from "antd/lib/form"; 2 | import { 3 | emptyInput, 4 | inputWhiteSpacesAtTheBeginningAndTheEnd, 5 | maxLength, 6 | } from "../../../../components/Notifications/Messages"; 7 | 8 | const inputMaxLenght = 200; 9 | 10 | const DistinctionTypeInputValidator: Rule[] = [ 11 | { 12 | required: true, 13 | message: emptyInput(), 14 | }, 15 | { 16 | pattern: /^\S.*\S$/, 17 | message: inputWhiteSpacesAtTheBeginningAndTheEnd("Відзначення"), 18 | }, 19 | { 20 | max: inputMaxLenght, 21 | message: maxLength(inputMaxLenght), 22 | }, 23 | ]; 24 | 25 | export default DistinctionTypeInputValidator; 26 | -------------------------------------------------------------------------------- /src/pages/Regions/AddDocumentModal.less: -------------------------------------------------------------------------------- 1 | .addDocumentModal { 2 | .ant-form-horizontal .ant-form-item-label { 3 | width: 25%; 4 | } 5 | 6 | .formFields { 7 | .ant-form-item-control { 8 | max-width: 75%; 9 | } 10 | 11 | .formSelect { 12 | width: 100%; 13 | } 14 | } 15 | 16 | .cancelConfirmButtons { 17 | margin-bottom: 0px; 18 | } 19 | 20 | .cardButton { 21 | margin-bottom: 1.2rem; 22 | } 23 | } 24 | 25 | @media (max-width: 575px) { 26 | .addDocumentModal { 27 | .ant-form-horizontal .ant-form-item-label { 28 | padding: 0; 29 | } 30 | 31 | .cancelConfirmButtons { 32 | .publishButton { 33 | text-align: end; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | dev 2 | ## JIRA 3 | 4 | * [Main JIRA ticket](https://jira.softserve.academy/secure/RapidBoard.jspa?rapidView=id) 5 | 6 | 7 | ## Code reviewers 8 | 9 | - [ ] @github_username 10 | 11 | ### Second Level Review 12 | 13 | - [ ] @github_username 14 | 15 | ## Summary of issue 16 | 17 | ToDo 18 | 19 | ## Summary of change 20 | 21 | ToDo 22 | 23 | ## Testing approach 24 | 25 | ToDo 26 | 27 | ## CHECK LIST 28 | - [ ] СI passed 29 | - [ ] Сode coverage >=95% 30 | - [ ] PR is reviewed manually again (to make sure you have 100% ready code) 31 | - [ ] All reviewers agreed to merge the PR 32 | - [ ] I've checked new feature as logged in and logged out user if needed 33 | - [ ] PR meets all conventions 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/master.md: -------------------------------------------------------------------------------- 1 | master 2 | ## JIRA 3 | 4 | * [Main JIRA ticket](https://jira.softserve.academy/secure/RapidBoard.jspa?rapidView=id) 5 | 6 | 7 | ## Code reviewers 8 | 9 | - [ ] @github_username 10 | 11 | ### Second Level Review 12 | 13 | - [ ] @github_username 14 | 15 | ## Summary of issue 16 | 17 | ToDo 18 | 19 | ## Summary of change 20 | 21 | ToDo 22 | 23 | ## Testing approach 24 | 25 | ToDo 26 | ## CHECK LIST 27 | - [ ] СI passed 28 | - [ ] Сode coverage >=95% 29 | - [ ] PR is reviewed manually again (to make sure you have 100% ready code) 30 | - [ ] All reviewers agreed to merge the PR 31 | - [ ] I've checked new feature as logged in and logged out user if needed 32 | - [ ] PR meets all conventions 33 | -------------------------------------------------------------------------------- /src/models/Club/ClubProfile.tsx: -------------------------------------------------------------------------------- 1 | import ClubAdmin from "./ClubAdmin"; 2 | 3 | export default class ClubProfile { 4 | id: number; 5 | name: string; 6 | logo: string | null; 7 | description: string; 8 | clubURL: string; 9 | phoneNumber: string; 10 | email: string; 11 | slogan: string; 12 | head: ClubAdmin; 13 | headDeputy: ClubAdmin; 14 | isActive: boolean; 15 | 16 | constructor() { 17 | this.id = 0; 18 | this.name = ""; 19 | this.logo = ""; 20 | this.description = ""; 21 | this.clubURL = ""; 22 | this.phoneNumber = ""; 23 | this.email = ""; 24 | this.slogan = ""; 25 | this.head = new ClubAdmin(); 26 | this.headDeputy = new ClubAdmin(); 27 | this.isActive = true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/Documents/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import documentsApi from "../../api/documentsApi"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const DeleteConfirm = (id: number, onDelete: any) => { 9 | return confirm({ 10 | title: "Ви справді хочете видалити документ?", 11 | icon: , 12 | okText: "Так", 13 | cancelText: "Ні", 14 | onOk() { 15 | const remove = async () => { 16 | await documentsApi.remove(id); 17 | }; 18 | remove(); 19 | onDelete(id); 20 | }, 21 | }); 22 | }; 23 | export default DeleteConfirm; 24 | -------------------------------------------------------------------------------- /src/pages/userPage/EditUserPage/Services.tsx: -------------------------------------------------------------------------------- 1 | export const getBase64 = (img: any, callback: any) => { 2 | const reader = new FileReader(); 3 | reader.addEventListener("load", () => callback(reader.result)); 4 | reader.readAsDataURL(img); 5 | }; 6 | 7 | export const getBase64FromUrl = (url: string) => { 8 | return new Promise((resolve) => { 9 | const xhr = new XMLHttpRequest(); 10 | xhr.open("GET", url); 11 | xhr.responseType = "blob"; 12 | xhr.send(); 13 | xhr.addEventListener("load", () => { 14 | const reader = new FileReader(); 15 | reader.readAsDataURL(xhr.response); 16 | reader.addEventListener("loadend", () => { 17 | resolve(reader.result); 18 | }); 19 | }); 20 | }); 21 | }; 22 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/develop.md: -------------------------------------------------------------------------------- 1 | dev 2 | ## JIRA 3 | 4 | * [Main JIRA ticket](https://jira.softserve.academy/secure/RapidBoard.jspa?rapidView=id) 5 | 6 | 7 | ## Code reviewers 8 | 9 | - [ ] @github_username 10 | 11 | ### Second Level Review 12 | 13 | - [ ] @github_username 14 | 15 | ## Summary of issue 16 | 17 | ToDo 18 | 19 | ## Summary of change 20 | 21 | ToDo 22 | 23 | ## Testing approach 24 | 25 | ToDo 26 | 27 | ## CHECK LIST 28 | - [ ] СI passed 29 | - [ ] Сode coverage >=95% 30 | - [ ] PR is reviewed manually again (to make sure you have 100% ready code) 31 | - [ ] All reviewers agreed to merge the PR 32 | - [ ] I've checked new feature as logged in and logged out user if needed 33 | - [ ] PR meets all conventions 34 | -------------------------------------------------------------------------------- /src/pages/City/AddDocumentModal/AddDocumentModal.less: -------------------------------------------------------------------------------- 1 | .addDocumentModal { 2 | .ant-form-horizontal .ant-form-item-label { 3 | width: 25%; 4 | } 5 | 6 | .formFields { 7 | .ant-form-item-control { 8 | max-width: 75%; 9 | } 10 | 11 | .formSelect { 12 | width: 100%; 13 | } 14 | } 15 | 16 | .cancelConfirmButtons { 17 | margin-bottom: 0px; 18 | } 19 | 20 | .cardButton { 21 | margin-bottom: 1.2rem; 22 | } 23 | } 24 | 25 | @media (max-width: 575px) { 26 | .addDocumentModal { 27 | .ant-form-horizontal .ant-form-item-label { 28 | padding: 0; 29 | } 30 | 31 | .cancelConfirmButtons { 32 | .publishButton { 33 | text-align: end; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/models/RegionBoard/RegionBoardProfile.tsx: -------------------------------------------------------------------------------- 1 | export default class RegionBoardProfile { 2 | id: number; 3 | regionName: string; 4 | logo: string | null; 5 | description: string; 6 | link: string; 7 | phoneNumber: string; 8 | email: string; 9 | city: string; 10 | street: string; 11 | houseNumber: string; 12 | officeNumber: string; 13 | postIndex: string; 14 | 15 | constructor() { 16 | this.id = 0; 17 | this.regionName = ""; 18 | this.logo = ""; 19 | this.description = ""; 20 | this.link = ""; 21 | this.phoneNumber = ""; 22 | this.email = ""; 23 | this.city = ""; 24 | this.street = ""; 25 | this.houseNumber = ""; 26 | this.officeNumber = ""; 27 | this.postIndex = ""; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/models/UserTable/User.tsx: -------------------------------------------------------------------------------- 1 | import Gender from "./Gender"; 2 | 3 | export default class User { 4 | id: string; 5 | firstName: string; 6 | lastName: string; 7 | birthday?: Date; 8 | gender: Gender; 9 | userProfileId: number; 10 | pseudo?: string; 11 | email: string; 12 | emailConfirmed: boolean; 13 | userRoles: string; 14 | isInLowerRole: boolean; 15 | 16 | constructor() { 17 | this.id = ""; 18 | this.firstName = ""; 19 | this.lastName = ""; 20 | this.birthday = undefined; 21 | this.gender = new Gender(); 22 | this.userProfileId = 0; 23 | this.pseudo = ""; 24 | this.email = ""; 25 | this.emailConfirmed = false; 26 | this.userRoles = ""; 27 | this.isInLowerRole = false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/FormEditDistinctionTypes/DeleteTypeConfirm.tsx: -------------------------------------------------------------------------------- 1 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 2 | import { Modal } from "antd"; 3 | import React from "react"; 4 | 5 | const { confirm } = Modal; 6 | 7 | const DeleteTypeConfirm = (distinctionId: number, deleteDistinction: any) => { 8 | return confirm({ 9 | title: 10 | "Ви справді хочете видалити цей тип відзначення? Це спричинить видалення всіх створених відзначень із цим типом.", 11 | icon: , 12 | okText: "Так", 13 | cancelText: "Ні", 14 | onOk() { 15 | deleteDistinction(distinctionId); 16 | }, 17 | }); 18 | }; 19 | export default DeleteTypeConfirm; 20 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/AddDocumentModal/AddDocumentModal.less: -------------------------------------------------------------------------------- 1 | .addDocumentModal { 2 | .ant-form-horizontal .ant-form-item-label { 3 | width: 28%; 4 | } 5 | 6 | .formFields { 7 | .ant-form-item-control { 8 | max-width: 72%; 9 | } 10 | 11 | .formSelect { 12 | width: 100%; 13 | } 14 | } 15 | 16 | .cancelConfirmButtons { 17 | margin-bottom: 0px; 18 | } 19 | 20 | .cardButton { 21 | margin-bottom: 1.2rem; 22 | } 23 | } 24 | 25 | @media (max-width: 575px) { 26 | .addDocumentModal { 27 | .ant-form-horizontal .ant-form-item-label { 28 | padding: 0; 29 | } 30 | 31 | .cancelConfirmButtons { 32 | .publishButton { 33 | text-align: end; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/Form.module.css: -------------------------------------------------------------------------------- 1 | .inputField { 2 | float: right; 3 | text-align: left; 4 | max-width: 320px; 5 | width: 320px; 6 | } 7 | 8 | @media (max-width: 576px) { 9 | .inputField { 10 | width: 100%; 11 | } 12 | } 13 | 14 | .clearButton { 15 | float: left; 16 | background-color: grey; 17 | width: 125px; 18 | } 19 | 20 | .selectField { 21 | float: right; 22 | text-align: left; 23 | width: 320px; 24 | } 25 | 26 | .formField { 27 | width: 100%; 28 | } 29 | 30 | .cardButton { 31 | float: right; 32 | inline-size: -webkit-fill-available; 33 | margin-top: 7px; 34 | color: #3c5438; 35 | border-color: #3c5438; 36 | max-width: 320px; 37 | min-width: 320px; 38 | } 39 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/EditDistinctionModal.tsx: -------------------------------------------------------------------------------- 1 | import { Drawer } from "antd"; 2 | import React from "react"; 3 | import { useDistinctions } from "../../../stores/DistinctionsStore"; 4 | import FormEditDistinction from "./FormEditDistinction"; 5 | 6 | const EditDistinctionModal = () => { 7 | const [state, actions] = useDistinctions(); 8 | return ( 9 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default EditDistinctionModal; 24 | -------------------------------------------------------------------------------- /src/pages/AboutBase/DeleteSubsectConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import aboutBase from "../../api/aboutBase"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const DeleteSubsectConfirm = (id: number, onDelete: any) => { 9 | return confirm({ 10 | title: "Ви справді хочете видалити цей підрозділ?", 11 | icon: , 12 | okText: "Так", 13 | cancelText: "Ні", 14 | onOk() { 15 | const remove = async () => { 16 | await aboutBase.deleteAboutBaseSubsection(id); 17 | }; 18 | remove(); 19 | onDelete(id); 20 | }, 21 | }); 22 | }; 23 | export default DeleteSubsectConfirm; 24 | -------------------------------------------------------------------------------- /src/pages/AboutBase/TextEditor.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | } 6 | .cardButton>* { 7 | margin-right: 8px; 8 | } 9 | .formField { 10 | max-width: 370px; 11 | min-width: 370px; 12 | } 13 | 14 | .selectField { 15 | max-width: 370px; 16 | min-width: 370px; 17 | } 18 | 19 | @media(max-width: 400px) { 20 | .formField{ 21 | max-width: 100%; 22 | min-width: 100%; 23 | } 24 | .selectField { 25 | max-width: 100%; 26 | min-width: 100%; 27 | } 28 | } 29 | .buttons{ 30 | width: 100%; 31 | padding: 14px 20px; 32 | margin: 8px 0; 33 | cursor: pointer; 34 | } 35 | .form{ 36 | border-radius: 5px; 37 | background-color: #f2f2f2; 38 | padding: 20px; 39 | 40 | } -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/ClubAnnualReportInformation/ClubAnnualReportInformation.less: -------------------------------------------------------------------------------- 1 | .annualreport-modal { 2 | .textCenter { 3 | text-align: center; 4 | } 5 | 6 | .container { 7 | width: 100%; 8 | } 9 | } 10 | 11 | .card__wrap--outer { 12 | display: flex; 13 | flex-direction: row; 14 | flex-wrap: wrap; 15 | width: 100%; 16 | } 17 | 18 | .card__wrap--inner { 19 | display: flex; 20 | flex-direction: row; 21 | width: 100%; 22 | } 23 | 24 | .flexible { 25 | flex-grow: 1; 26 | } 27 | 28 | .linkText { 29 | font-size: 14px; 30 | } 31 | .ClubAnnualReportInformationDescription { 32 | word-break: break-word; 33 | } 34 | 35 | .clubAnnualReportInformationCol { 36 | margin-left: 10px; 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/Club/AddAdministratorModal/AddAdministrationModal.less: -------------------------------------------------------------------------------- 1 | .addAdministrationModal { 2 | .adminTypeFormItem { 3 | margin-bottom: 12px; 4 | } 5 | 6 | .ant-form-horizontal .ant-form-item-label { 7 | padding: 0; 8 | } 9 | 10 | .formSelect { 11 | width: 100%; 12 | } 13 | 14 | .cancelConfirmButtons { 15 | margin-bottom: 0px; 16 | .ant-row { 17 | align-items: baseline; 18 | } 19 | } 20 | 21 | .cardButton { 22 | margin-bottom: 1.2rem; 23 | } 24 | } 25 | 26 | @media (max-width: 575px) { 27 | .addAdministrationModal { 28 | .cancelConfirmButtons { 29 | .publishButton { 30 | text-align: end; 31 | } 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/AddDistinctionModal.tsx: -------------------------------------------------------------------------------- 1 | import { Drawer } from "antd"; 2 | import React from "react"; 3 | import { useDistinctions } from "../../../stores/DistinctionsStore"; 4 | import FormAddUserDistinction from "./FormAddDistinction"; 5 | 6 | const AddUserDistinctionModal = () => { 7 | const [state, actions] = useDistinctions(); 8 | return ( 9 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default AddUserDistinctionModal; 24 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/Sector/SectorAdminTypes.ts: -------------------------------------------------------------------------------- 1 | import { Roles } from "../../../models/Roles/Roles"; 2 | 3 | enum UniqueSectorAdminTypes { 4 | Secretar = "Секретар Керівного Органу", 5 | Progress = "Член Напряму Керівного Органу з питань організаційного розвитку", 6 | Social = "Член Напряму Керівного Органу з соціального напрямку", 7 | Сommunication = "Член Напряму Керівного Органу відповідальний за зовнішні зв'язки" 8 | } 9 | 10 | enum SectorAdminTypes { 11 | Head = Roles.GoverningBodySectorHead, 12 | Secretar = UniqueSectorAdminTypes.Secretar, 13 | Progress = UniqueSectorAdminTypes.Progress, 14 | Social = UniqueSectorAdminTypes.Social, 15 | Сommunication = UniqueSectorAdminTypes.Сommunication 16 | } 17 | 18 | export default SectorAdminTypes -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForClubAnnualReports/UnconfirmedDropdown/UnconfirmedDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | 3 | interface Props { 4 | record: { 5 | id: number; 6 | status: number; 7 | clubId: number; 8 | clubName: string; 9 | date: Date; 10 | canManage: boolean; 11 | }; 12 | pageX: number; 13 | pageY: number; 14 | showDropdown: boolean; 15 | userAnnualReportAccess: IUserAnnualReportAccess; 16 | onView: (id: number) => Promise; 17 | onViewPDF: (id: number) => Promise; 18 | onEdit: (id: number) => void; 19 | onConfirm: (id: number) => Promise; 20 | onRemove: (id: number) => Promise; 21 | } 22 | 23 | export default Props; 24 | -------------------------------------------------------------------------------- /src/models/UserTable/Gender.tsx: -------------------------------------------------------------------------------- 1 | export default class Gender { 2 | name: string; 3 | 4 | constructor() { 5 | this.name = ""; 6 | } 7 | } 8 | 9 | export enum GenderNameEnum { 10 | NotSpecified = "Не маю бажання вказувати", 11 | Male = "Чоловік", 12 | Female = "Жінка", 13 | UnwillingToChoose = "Не маю бажання вказувати", 14 | } 15 | 16 | export enum GenderIdEnum { 17 | NotSpecified = 0, 18 | Male = 1, 19 | Female = 2, 20 | UnwillingToChoose = 7 21 | } 22 | 23 | export const genderRecords: Record = { 24 | [GenderIdEnum.NotSpecified]: GenderNameEnum.NotSpecified, 25 | [GenderIdEnum.Male]: GenderNameEnum.Male, 26 | [GenderIdEnum.Female]: GenderNameEnum.Female, 27 | [GenderIdEnum.UnwillingToChoose]: GenderNameEnum.UnwillingToChoose 28 | }; -------------------------------------------------------------------------------- /src/pages/GoverningBody/GoverningBodyAdminTypes.ts: -------------------------------------------------------------------------------- 1 | import { Roles } from "../../models/Roles/Roles"; 2 | 3 | enum UniqueGoverningBodyAdminTypes { 4 | Secretar = "Секретар Керівного Органу", 5 | Progress = "Член Керівного Органу з питань організаційного розвитку", 6 | Social = "Член Керівного Органу з соціального напрямку", 7 | Сommunication = "Член Керівного Органу відповідальний за зовнішні зв'язки" 8 | } 9 | 10 | enum GoverningBodyAdminTypes { 11 | Head = Roles.GoverningBodyHead, 12 | Secretar = UniqueGoverningBodyAdminTypes.Secretar, 13 | Progress = UniqueGoverningBodyAdminTypes.Progress, 14 | Social = UniqueGoverningBodyAdminTypes.Social, 15 | Сommunication = UniqueGoverningBodyAdminTypes.Сommunication 16 | } 17 | 18 | export default GoverningBodyAdminTypes -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/Dropdowns/UnconfirmedDropdown/UnconfirmedDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | 3 | interface Props { 4 | record: { 5 | id: number; 6 | status: number; 7 | cityId: number; 8 | cityName: string; 9 | regionName: string; 10 | date: Date; 11 | canManage: boolean; 12 | }; 13 | pageX: number; 14 | pageY: number; 15 | showDropdown: boolean; 16 | userAnnualReportAccess: IUserAnnualReportAccess; 17 | onView: (id: number) => Promise; 18 | onViewPDF: (id: number) => Promise; 19 | onEdit: (id: number) => void; 20 | onConfirm: (id: number) => Promise; 21 | onRemove: (id: number) => Promise; 22 | } 23 | 24 | export default Props; 25 | -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/DeleteTypeConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import precautionApi from "../../../api/precautionApi"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const DeleteTypeConfirm = (id: number, onDelete: any) => { 9 | return confirm({ 10 | title: "Ви справді хочете видалити цей тип перестороги?", 11 | icon: , 12 | okText: "Так", 13 | cancelText: "Ні", 14 | onOk() { 15 | const remove = async () => { 16 | await precautionApi.deletePrecaution(id); 17 | }; 18 | remove(); 19 | onDelete(id); 20 | }, 21 | }); 22 | }; 23 | export default DeleteTypeConfirm; 24 | -------------------------------------------------------------------------------- /src/pages/userPage/Approvers/DeleteApproveButton.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "antd"; 2 | import React, { useState } from "react"; 3 | 4 | interface Props { 5 | approverId: number; 6 | onDeleteApprove: (id: number) => Promise; 7 | } 8 | 9 | const DeleteApproveButton = (props: Props) => { 10 | const { approverId, onDeleteApprove } = props; 11 | const [isLoading, setIsLoading] = useState(false); 12 | 13 | return ( 14 | 26 | ); 27 | }; 28 | 29 | export default DeleteApproveButton; 30 | -------------------------------------------------------------------------------- /src/models/Events/EventInformation.ts: -------------------------------------------------------------------------------- 1 | import EventFeedback from "../EventUser/EventFeedback"; 2 | import { EventAdmin } from "./EventAdmin"; 3 | import { EventParticipant } from "./EventParticipant"; 4 | 5 | export interface EventInformation { 6 | eventId: number; 7 | eventName: string; 8 | description: string; 9 | eventDateStart: string; 10 | eventDateEnd: string; 11 | eventLocation: string; 12 | eventTypeId: number; 13 | eventType: string; 14 | eventCategoryId: number; 15 | eventCategory: string; 16 | eventStatus: string; 17 | formOfHolding: string; 18 | forWhom: string; 19 | rating: number; 20 | numberOfPartisipants: number; 21 | eventAdmins: EventAdmin[]; 22 | eventParticipants: EventParticipant[]; 23 | eventFeedbacks: EventFeedback[]; 24 | gallery: number[]; 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import precautionApi from "../../../api/precautionApi"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const DeleteConfirm = async (id: number, onDelete: any) => { 9 | return confirm({ 10 | title: "Ви справді хочете видалити пересторогу цього користувача?", 11 | icon: , 12 | okText: "Так", 13 | cancelText: "Ні", 14 | async onOk() { 15 | try { 16 | await precautionApi.deleteUserPrecaution(id); 17 | } finally { 18 | await onDelete(id); 19 | } 20 | }, 21 | }); 22 | }; 23 | export default DeleteConfirm; 24 | -------------------------------------------------------------------------------- /src/components/ImagePreview/ImagePreview.tsx: -------------------------------------------------------------------------------- 1 | import { Modal } from "antd"; 2 | import React, { useRef } from "react"; 3 | import "./ImagePreview.less"; 4 | 5 | interface ImagePreviewProps { 6 | fileName: string | undefined; 7 | src: string | undefined; 8 | visible: boolean; 9 | onHide: () => void; 10 | } 11 | 12 | export const ImagePreview: React.FC = ( 13 | p: ImagePreviewProps 14 | ) => { 15 | const imageRef = useRef(null); 16 | 17 | return ( 18 | p.onHide()} 23 | > 24 | {p.fileName} 25 | 26 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /src/pages/DecisionTable/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import decisionsApi from "../../api/decisionsApi"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const remove = async (id: number) => { 9 | await decisionsApi.remove(id); 10 | }; 11 | 12 | const DeleteConfirm = (id: number, onDelete: any) => { 13 | return confirm({ 14 | title: "Ви справді хочете видалити рішення?", 15 | icon: , 16 | okText: "Так", 17 | cancelText: "Ні", 18 | async onOk() { 19 | try { 20 | await remove(id); 21 | } finally { 22 | onDelete(); 23 | } 24 | }, 25 | }); 26 | }; 27 | export default DeleteConfirm; 28 | -------------------------------------------------------------------------------- /src/models/GoverningBody/GoverningBodyAdmin.tsx: -------------------------------------------------------------------------------- 1 | import AdminType from "../Admin/AdminType"; 2 | import GoverningBodyUser from "./GoverningBodyUser"; 3 | 4 | export default class GoverningBodyAdmin { 5 | id: number; 6 | userId: string; 7 | user: GoverningBodyUser; 8 | adminType: AdminType; 9 | governingBodyId: number; 10 | startDate?: string; 11 | endDate?: string; 12 | workEmail?: string; 13 | governingBodyAdminRole?: string; 14 | 15 | constructor() { 16 | this.id = 0; 17 | this.userId = ""; 18 | this.user = new GoverningBodyUser(); 19 | this.adminType = new AdminType(); 20 | this.governingBodyId = 0; 21 | this.startDate = undefined; 22 | this.endDate = undefined; 23 | this.workEmail = undefined; 24 | this.governingBodyAdminRole = undefined; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/NotificationBox/WebSocketConnection.tsx: -------------------------------------------------------------------------------- 1 | import BASE_URL from "../../config"; 2 | 3 | const GetURL = (userId: string): string => { 4 | let url = BASE_URL.substr(0, BASE_URL.length - 5); 5 | url = url.replace("http", "ws"); 6 | return url + "/notifications" + `?userId=${userId}`; 7 | }; 8 | 9 | function ManageConnection(userId: string) { 10 | const url = GetURL(userId); 11 | let socket = new WebSocket(url); 12 | socket.onopen = function (event) { 13 | console.log("opened connection to " + url); 14 | }; 15 | socket.onclose = function (event) { 16 | console.log("closed connection from " + url); 17 | }; 18 | socket.onerror = function (event) { 19 | console.log("error: " + event); 20 | }; 21 | return socket; 22 | } 23 | 24 | export default { 25 | ManageConnection, 26 | }; 27 | -------------------------------------------------------------------------------- /src/models/UserTable/ShortUserInfo.tsx: -------------------------------------------------------------------------------- 1 | import Gender from "./Gender"; 2 | 3 | export default class ShortUserInfo { 4 | id: string; 5 | userProfileId: number; 6 | firstName: string; 7 | lastName: string; 8 | birthday?: Date; 9 | gender: Gender; 10 | imagePath: string; 11 | email: string; 12 | emailConfirmed: boolean; 13 | isInLowerRole: boolean; 14 | isInDeputyRole: boolean; 15 | 16 | constructor() { 17 | this.id = ""; 18 | this.userProfileId = 0; 19 | this.firstName = ""; 20 | this.lastName = ""; 21 | this.birthday = undefined; 22 | this.gender = new Gender(); 23 | this.userProfileId = 0; 24 | this.imagePath = ""; 25 | this.email = ""; 26 | this.emailConfirmed = false; 27 | this.isInLowerRole = false; 28 | this.isInDeputyRole = false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/pages/Club/AddDocumentModal/AddDocumentModal.less: -------------------------------------------------------------------------------- 1 | .addDocumentModal { 2 | .ant-form-horizontal .ant-form-item-label { 3 | width: 25%; 4 | } 5 | 6 | .formFields { 7 | .ant-form-item-control { 8 | max-width: 75%; 9 | } 10 | 11 | .formSelect { 12 | width: 100%; 13 | } 14 | } 15 | 16 | .cancelConfirmButtons { 17 | margin-bottom: 0px; 18 | } 19 | 20 | .cardButton { 21 | margin-bottom: 1.2rem; 22 | } 23 | } 24 | 25 | @media (max-width: 575px) { 26 | .addDocumentModal { 27 | .ant-form-horizontal .ant-form-item-label { 28 | padding: 0; 29 | } 30 | 31 | .cancelConfirmButtons { 32 | .publishButton { 33 | text-align: end; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/DropdownsForRegionReports/UnconfirmedDropdown/UnconfirmedRegionDropdownProps.tsx: -------------------------------------------------------------------------------- 1 | import IUserAnnualReportAccess from "../../../../../models/UserAccess/IUserAccess"; 2 | 3 | interface Props { 4 | regionRecord: { 5 | id: number; 6 | regionId: number; 7 | regionName: string; 8 | date: Date; 9 | status: number; 10 | count: number; 11 | total: number; 12 | canManage: boolean; 13 | }; 14 | pageX: number; 15 | pageY: number; 16 | userAnnualReportAccess: IUserAnnualReportAccess; 17 | showDropdown: boolean; 18 | onView: (id: number, year: number) => Promise; 19 | onEdit: (id: number, year: number) => void; 20 | onConfirm: (id: number) => Promise; 21 | onRemove: (id: number) => Promise; 22 | } 23 | 24 | export default Props; 25 | -------------------------------------------------------------------------------- /src/api/announcementsApi.ts: -------------------------------------------------------------------------------- 1 | import api from "./api"; 2 | 3 | export const getAnnouncementsByPage = async ( 4 | pageNumber: number, 5 | pageSize: number 6 | ) => { 7 | try { 8 | return await api.get(`Announcements/GetAnnouncementsByPage/${pageNumber}`, { 9 | pageNumber, 10 | pageSize, 11 | }); 12 | } catch (error) { 13 | throw new Error(); 14 | } 15 | }; 16 | 17 | export const getAnnouncementsById = async (id: number) => { 18 | try { 19 | return await api.get(`Announcements/GetAnnouncement/${id}`, id); 20 | } catch (error) { 21 | throw new Error(); 22 | } 23 | }; 24 | 25 | export const pinAnnouncement = async (id: number) => { 26 | try { 27 | return await api.put(`Announcements/PinAnnouncement/${id}`, id); 28 | } catch (error) { 29 | throw new Error(); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /src/pages/Error/Errors.module.css: -------------------------------------------------------------------------------- 1 | .button { 2 | margin-top: 30px; 3 | padding-top: 10px; 4 | background: #3C5438; 5 | justify-content: center; 6 | color: white; 7 | border: none; 8 | width: 138px; 9 | height: 40px; 10 | outline: none; 11 | text-align: center; 12 | cursor: pointer; 13 | align-items: center; 14 | box-shadow: 0 7px 14px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); 15 | transition: all 0.3s cubic-bezier(.25, .8, .25, 1); 16 | } 17 | 18 | .button:hover { 19 | border: none; 20 | background: #3C5438; 21 | color:white; 22 | outline: none; 23 | box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015); 24 | transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); 25 | box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); 26 | } -------------------------------------------------------------------------------- /src/pages/userPage/Blanks/UserAchievements/ListOfAchievements.module.css: -------------------------------------------------------------------------------- 1 | .fileIcon{ 2 | font-size: 30px; 3 | } 4 | .deleteIcon{ 5 | font-size: 20px; 6 | color: #910202; 7 | } 8 | .deleteIcon:hover{ 9 | color: #690606; 10 | cursor: pointer; 11 | } 12 | 13 | .downloadIcon{ 14 | font-size: 20px; 15 | color: #3C5438 16 | } 17 | .downloadIcon:hover{ 18 | cursor: pointer; 19 | color: #273625 20 | } 21 | 22 | .reviewIcon{ 23 | font-size: 20px; 24 | color: #3C5438; 25 | } 26 | 27 | .demoInfiniteContainer { 28 | overflow: auto; 29 | padding: 2px 6px; 30 | height: 420px; 31 | } 32 | .demoLoadingContainer { 33 | font-size: 30px; 34 | color: #3C5438; 35 | position: absolute; 36 | bottom: 20px; 37 | width: 100%; 38 | text-align: center; 39 | } -------------------------------------------------------------------------------- /src/pages/KadraVykhovnykiv/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import kadrasApi from "../../api/KadraVykhovnykivApi"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const remove = async (id: number) => { 9 | await kadrasApi.deleteKadra(id); 10 | }; 11 | 12 | const DeleteConfirm = (id: number, onDelete: any) => { 13 | return confirm({ 14 | title: "Ви справді хочете забрати кадру у цього користувача?", 15 | icon: , 16 | okText: "Так", 17 | cancelText: "Ні", 18 | async onOk() { 19 | try { 20 | await remove(id); 21 | } finally { 22 | onDelete(); 23 | } 24 | }, 25 | }); 26 | }; 27 | export default DeleteConfirm; 28 | -------------------------------------------------------------------------------- /src/pages/AboutBase/DeleteSectConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import aboutBase from "../../api/aboutBase"; 5 | 6 | const { confirm } = Modal; 7 | 8 | const DeleteSectConfirm = (id: number, onDelete: any) => { 9 | return confirm({ 10 | title: 11 | "Ви справді хочете видалити цей розділ? Це спричинить видалення всіх підрозділів, які у ньому знаходяться.", 12 | icon: , 13 | okText: "Так", 14 | cancelText: "Ні", 15 | onOk() { 16 | const remove = async () => { 17 | await aboutBase.deleteAboutBaseSection(id); 18 | }; 19 | remove(); 20 | onDelete(id); 21 | }, 22 | }); 23 | }; 24 | export default DeleteSectConfirm; 25 | -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/EditPrecautionModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer } from "antd"; 3 | import FormEditPrecaution from "./FormEditPrecaution"; 4 | import { createHook } from "react-sweet-state"; 5 | import PrecautionStore from "../../../stores/StorePrecaution"; 6 | 7 | const EditPrecautionModal = () => { 8 | const useStore = createHook(PrecautionStore); 9 | const [state, actions] = useStore(); 10 | 11 | return ( 12 | actions.setShowEditModal(false)} 19 | footer={null} 20 | > 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default EditPrecautionModal; 27 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/EditDistinctionTypesModal.tsx: -------------------------------------------------------------------------------- 1 | import { Drawer } from "antd"; 2 | import React from "react"; 3 | import { useDistinctions } from "../../../stores/DistinctionsStore"; 4 | import FormListOfDistinctionTypes from "./FormEditDistinctionTypes/FormListOfDistinctionTypes"; 5 | 6 | const EditDistinctionTypesModal = () => { 7 | const [state, actions] = useDistinctions(); 8 | 9 | return ( 10 | 19 | 20 | 21 | ); 22 | }; 23 | 24 | export default EditDistinctionTypesModal; 25 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventInfo/ParticipantsTable.less: -------------------------------------------------------------------------------- 1 | @plast-color: #3c5438; 2 | 3 | .participant-table-fullName{ 4 | &:hover{ 5 | color: @plast-color; 6 | cursor:pointer; 7 | text-decoration: underline; 8 | } 9 | } 10 | 11 | .iconParticipant{ 12 | color:#ffffff; 13 | } 14 | 15 | .approveButton{ 16 | background-color: #007E33 !important; 17 | &:hover{ 18 | background-color: #00C851 !important; 19 | } 20 | } 21 | 22 | .underReviewButton{ 23 | background-color: #FF8800 !important; 24 | &:hover{ 25 | background-color: #ffbb33 !important; 26 | } 27 | } 28 | 29 | .banButton{ 30 | background-color: #CC0000 !important; 31 | &:hover{ 32 | background-color: #ff4444 !important; 33 | } 34 | } 35 | 36 | .disabledButton { 37 | background-color: lightgrey !important; 38 | } -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportTable/AnnualReportInformation/AnnualReportInformation.less: -------------------------------------------------------------------------------- 1 | .annualreport-modal { 2 | .textCenter { 3 | text-align: center; 4 | } 5 | 6 | .container { 7 | width: 100%; 8 | } 9 | } 10 | 11 | .status-stamp { 12 | margin-right: -5px; 13 | margin-top: -20px; 14 | user-select: none; 15 | float: right; 16 | box-shadow: 0 0 0 3px, 0 0 0 2px inset; 17 | border: 2px solid transparent; 18 | border-radius: 4px; 19 | display: inline-block; 20 | padding: 5px 2px; 21 | line-height: 22px; 22 | font-size: 24px; 23 | font-family: "Black Ops One", cursive, system-ui; 24 | text-transform: uppercase; 25 | text-align: center; 26 | opacity: 0.4; 27 | transform: rotate(9deg); 28 | @media (max-width: 400px) { 29 | font-size: 6vw; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/AboutBase/AskQuestionModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal, Drawer } from "antd"; 3 | import FormAddDecision from "./FormAskQuestion"; 4 | import { Decision } from "../../api/decisionsApi"; 5 | import FormAskQuestion from "./FormAskQuestion"; 6 | 7 | interface Props { 8 | visibleModal: boolean; 9 | setVisibleModal: (visibleModal: boolean) => void; 10 | } 11 | 12 | const AskQuestionModal = ({ visibleModal, setVisibleModal }: Props) => { 13 | const handleCancel = () => setVisibleModal(false); 14 | 15 | return ( 16 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | export default AskQuestionModal; 29 | -------------------------------------------------------------------------------- /src/models/Region/RegionFollower.tsx: -------------------------------------------------------------------------------- 1 | import UkraineOblasts from "../Oblast/UkraineOblasts"; 2 | 3 | export default class RegionFollower { 4 | id: number; 5 | userId: string; 6 | appeal: string; 7 | cityName: string; 8 | cityDescription: string; 9 | logo: string | undefined; 10 | regionId: string; 11 | address: string; 12 | level: number; 13 | cityURL: string; 14 | email: string; 15 | phoneNumber: string; 16 | oblast: UkraineOblasts; 17 | constructor() { 18 | this.id = 0; 19 | this.userId = ""; 20 | this.appeal = ""; 21 | this.cityName = ""; 22 | this.cityDescription = ""; 23 | this.logo = ""; 24 | this.regionId = ""; 25 | this.address = ""; 26 | this.level = 1; 27 | this.cityURL = ""; 28 | this.email = ""; 29 | this.phoneNumber = ""; 30 | this.oblast = UkraineOblasts.NotSpecified; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/AnnouncementsTable/Modals/AddAnnouncementModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer } from "antd"; 3 | import FormAddAnnouncement from "../Forms/FormAddAnnouncement"; 4 | 5 | interface Props { 6 | visibleModal: boolean; 7 | setVisibleModal: (visibleModal: boolean) => void; 8 | } 9 | 10 | const AddAnnouncementModal = ({ visibleModal, setVisibleModal }: Props) => { 11 | const handleClose = () => { 12 | setVisibleModal(false); 13 | }; 14 | 15 | return ( 16 | 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default AddAnnouncementModal; 31 | -------------------------------------------------------------------------------- /src/models/Region/RegionAdmin.tsx: -------------------------------------------------------------------------------- 1 | import AdminType from "../Admin/AdminType"; 2 | import CityUser from "../City/CityUser"; 3 | import RegionProfile from "./RegionProfile"; 4 | 5 | export default class RegionAdmin { 6 | id: number; 7 | userId: string; 8 | user: CityUser; 9 | cityId: number; 10 | adminTypeId: number; 11 | adminType: AdminType; 12 | startDate?: string; 13 | endDate?: string; 14 | regionId: number; 15 | region: RegionProfile; 16 | status: boolean; 17 | 18 | constructor() { 19 | this.id = 0; 20 | this.userId = ""; 21 | this.user = new CityUser(); 22 | this.cityId = 0; 23 | this.adminTypeId = 0; 24 | this.adminType = new AdminType(); 25 | this.startDate = undefined; 26 | this.endDate = undefined; 27 | this.regionId = 0; 28 | this.region = new RegionProfile(); 29 | this.status = false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/models/EventEdit/Event.tsx: -------------------------------------------------------------------------------- 1 | export default class Event { 2 | description: string; 3 | eventCategoryID: number; 4 | eventDateStart?: Date; 5 | eventDateEnd?: Date; 6 | eventName: string; 7 | eventStatusID: number; 8 | eventTypeID: number; 9 | eventlocation: string; 10 | forWhom: string; 11 | formOfHolding: string; 12 | id: number; 13 | numberOfPartisipants: number; 14 | questions: string; 15 | 16 | constructor() { 17 | this.description = ""; 18 | this.eventCategoryID = 0; 19 | this.eventDateStart = undefined; 20 | this.eventDateEnd = undefined; 21 | this.eventName = ""; 22 | this.eventStatusID = 0; 23 | this.eventTypeID = 0; 24 | this.eventlocation = ""; 25 | this.forWhom = ""; 26 | this.formOfHolding = ""; 27 | this.id = 0; 28 | this.numberOfPartisipants = 0; 29 | this.questions = ""; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/AnnouncementsTable/Modals/EditAnnouncementModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer } from "antd"; 3 | import FormEditAnnouncement from "../Forms/FormEditAnnouncement"; 4 | 5 | interface Props { 6 | visibleModal: boolean; 7 | setVisibleModal: (visibleModal: boolean) => void; 8 | } 9 | 10 | const EditAnnouncementModal = ({ visibleModal, setVisibleModal }: Props) => { 11 | const handleClose = () => { 12 | setVisibleModal(false); 13 | }; 14 | 15 | return ( 16 | 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default EditAnnouncementModal; 31 | -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/AddPrecautionModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer } from "antd"; 3 | import FormAddPrecaution from "./FormAddPrecaution"; 4 | import PrecautionStore from "../../../stores/StorePrecaution"; 5 | import { createHook } from "react-sweet-state"; 6 | 7 | const AddPrecautionModal = () => { 8 | const handleCancel = () => { 9 | actions.setVisibleAddModal(false); 10 | }; 11 | const useStore = createHook(PrecautionStore); 12 | const [state, actions] = useStore(); 13 | 14 | return ( 15 | 24 | 25 | 26 | ); 27 | }; 28 | 29 | export default AddPrecautionModal; 30 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/UserPrecautionStatus.ts: -------------------------------------------------------------------------------- 1 | enum UserPrecautionStatus 2 | { 3 | Accepted, 4 | Confirmed, 5 | Cancelled 6 | } 7 | 8 | export const userPrecautionStatusRecord: Record = { 9 | [UserPrecautionStatus.Accepted]: "Прийнято", 10 | [UserPrecautionStatus.Confirmed]: "Потверджено", 11 | [UserPrecautionStatus.Cancelled]: "Скасовано", 12 | }; 13 | 14 | export const userPrecautionStatuses: Readonly<[UserPrecautionStatus, string][]> = Object.entries(userPrecautionStatusRecord) 15 | .map(([key, value]) => { 16 | const tuple: [UserPrecautionStatus, string] = [Number(key), value]; 17 | return tuple; 18 | }); 19 | 20 | export const getUserPrecautionStatusStr = (status: UserPrecautionStatus) => { 21 | return userPrecautionStatuses.find(s => s[0] === status)?.[1] 22 | } 23 | 24 | export default UserPrecautionStatus; -------------------------------------------------------------------------------- /src/pages/Documents/AddDocumetsModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal, Drawer } from "antd"; 3 | import FormAddDocument from "./FormAddDocument"; 4 | 5 | interface AddDocumentsModalProps { 6 | visibleModal: boolean; 7 | setVisibleModal: (visibleModal: boolean) => void; 8 | onAdd: () => void; 9 | } 10 | 11 | const AddDocumentsModal: React.FC = ({ visibleModal, setVisibleModal, onAdd }) => { 12 | const handleCancel = () => setVisibleModal(false); 13 | 14 | return ( 15 | 24 | 25 | 26 | ); 27 | }; 28 | 29 | export default AddDocumentsModal; 30 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/Form.module.css: -------------------------------------------------------------------------------- 1 | .cardButton { 2 | display: flex; 3 | width: 100%; 4 | justify-content:flex-end; 5 | float: right; 6 | } 7 | .cardButton>* { 8 | margin-right: 8px; 9 | } 10 | .formField { 11 | max-width: 370px; 12 | min-width: 370px; 13 | } 14 | 15 | .selectField { 16 | max-width: 370px; 17 | min-width: 370px; 18 | } 19 | 20 | .selectTypeDistField { 21 | max-width: 320px; 22 | min-width: 320px; 23 | } 24 | 25 | .editTypeDistPosition{ 26 | padding: 35px 0 0 25%; 27 | } 28 | 29 | .buttons{ 30 | margin-right: 0px !important; 31 | margin-left: 7px; 32 | } 33 | 34 | @media(max-width: 400px) { 35 | .formField{ 36 | max-width: 100%; 37 | min-width: 100%; 38 | } 39 | .selectField { 40 | max-width: 100%; 41 | min-width: 100%; 42 | } 43 | .selectTypeDistField { 44 | max-width: 100%; 45 | min-width: 100%; 46 | } 47 | } -------------------------------------------------------------------------------- /src/pages/userPage/ActiveMembership/UserDates/columnsFormerUser.tsx: -------------------------------------------------------------------------------- 1 | import moment from "moment"; 2 | 3 | const minDate = "0001-01-01T00:00:00"; 4 | 5 | 6 | const columns = [ 7 | { 8 | title: "№", 9 | width: 60, 10 | key: "index", 11 | render: (text: string, record: any, index: number) => index + 1 12 | }, 13 | { 14 | title: "Дата початку", 15 | dataIndex: "entry", 16 | width: 120, 17 | render: (entry: string) => { 18 | return entry == minDate ? 19 | "Немає" 20 | : moment.utc(entry).local().format("DD.MM.YYYY"); 21 | }, 22 | }, 23 | { 24 | title: "Дата відновлення", 25 | dataIndex: "end", 26 | width: 120, 27 | render: (end: string) => { 28 | return end == minDate ? 29 | "Все ще не відновився" 30 | : moment.utc(end).local().format("DD.MM.YYYY"); 31 | }, 32 | } 33 | ]; 34 | 35 | export default columns; 36 | -------------------------------------------------------------------------------- /src/pages/Precaution/Interfaces/DropDownPrecautionTableProps.ts: -------------------------------------------------------------------------------- 1 | import Precaution from "./Precaution"; 2 | import PrecautionUser from "./PrecautionUser"; 3 | import UserPrecautionStatus from "./UserPrecautionStatus"; 4 | import UserPrecautionTableItem from "./UserPrecautionTableItem"; 5 | 6 | type DropDownProps = { 7 | recordId: number; 8 | userId: string; 9 | pageX: number; 10 | pageY: number; 11 | showDropdown: boolean; 12 | userAccess: { [key: string]: boolean }; 13 | isActive: boolean; 14 | onDelete: (id: number) => void; 15 | onEdit: ( 16 | id: number, 17 | Precaution: Precaution, 18 | date: Date, 19 | endDate: Date, 20 | isActive: boolean, 21 | reason: string, 22 | status: UserPrecautionStatus, 23 | reporter: string, 24 | number: number, 25 | userId: PrecautionUser, 26 | user: any 27 | ) => void; 28 | }; 29 | 30 | export default DropDownProps; 31 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/Announcement/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import { deleteAnnouncement } from "../../../api/governingBodiesApi"; 5 | import notificationLogic from "../../../components/Notifications/Notification"; 6 | 7 | const { confirm } = Modal; 8 | 9 | const DeleteConfirm = (id: number, onDelete: any) => { 10 | return confirm({ 11 | title: "Ви справді хочете видалити оголошення?", 12 | icon: , 13 | okText: "Так", 14 | cancelText: "Ні", 15 | onOk() { 16 | const remove = async () => { 17 | deleteAnnouncement(id); 18 | }; 19 | remove(); 20 | onDelete(id); 21 | notificationLogic("success", "Оголошення видалено"); 22 | }, 23 | }); 24 | }; 25 | export default DeleteConfirm; 26 | -------------------------------------------------------------------------------- /src/components/HistoryNavi/historyPseudo.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class PsevdonimCreator { 4 | static pseudonimLocation: { userId: string; psevdonim: string }[] = 5 | sessionStorage.getItem("pseudonimLocation") !== null 6 | ? JSON.parse(sessionStorage["pseudonimLocation"]) 7 | : []; 8 | 9 | static setPseudonimLocation = (adressPsevdo: string, userId: string) => { 10 | if ( 11 | PsevdonimCreator.pseudonimLocation.find( 12 | (x: { userId: string }) => x.userId === userId 13 | ) === undefined 14 | ) { 15 | let ps = { 16 | userId: `${userId}`, 17 | psevdonim: `${adressPsevdo}`, 18 | }; 19 | PsevdonimCreator.pseudonimLocation.push(ps); 20 | } 21 | sessionStorage.setItem( 22 | "pseudonimLocation", 23 | JSON.stringify(PsevdonimCreator.pseudonimLocation) 24 | ); 25 | }; 26 | } 27 | export default PsevdonimCreator; 28 | -------------------------------------------------------------------------------- /src/models/UserAccess/IUserAccess.ts: -------------------------------------------------------------------------------- 1 | export default interface IUserAnnualReportAccess { 2 | IsSuperAdmin: boolean; 3 | IsAdmin: boolean; 4 | CanViewReportsPage: boolean; 5 | CanViewCityReportsTable: boolean; 6 | CanViewClubReportsTable: boolean; 7 | CanViewRegionReportsTable: boolean; 8 | CanViewReportDetails: boolean; 9 | CanSubmitCityReport: boolean; 10 | CanSubmitClubReport: boolean; 11 | CanSubmitRegionReport: boolean; 12 | CanEditReport: boolean; 13 | CanChangeReportStatus: boolean; 14 | CanDeleteReport: boolean; 15 | CanCityStatisticsChooseCity: boolean; 16 | CanCityStatisticsChooseYears: boolean; 17 | CanCityStatisticsChooseIndicators: boolean; 18 | CanCityStatisticsFormReport: boolean; 19 | CanRegionStatisticsChooseRegion: boolean; 20 | CanRegionStatisticsСhooseYears: boolean; 21 | CanRegionStatisticsChooseIndicators: boolean; 22 | CanRegionStatisticsFormReport: boolean; 23 | } 24 | -------------------------------------------------------------------------------- /manifests/ingress-prod.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | namespace: eplast 5 | name: routing-for-eplast-client 6 | annotations: 7 | kubernetes.io/ingress.class: nginx 8 | cert-manager.io/cluster-issuer: letsencrypt-production 9 | nginx.ingress.kubernetes.io/proxy-body-size: "20m" 10 | spec: 11 | tls: 12 | - hosts: 13 | - ___SiteDnsName___ 14 | secretName: tls-secret-prd 15 | rules: 16 | - host: ___SiteDnsName___ 17 | http: 18 | paths: 19 | - backend: 20 | service: 21 | name: eplastweb 22 | port: 23 | number: 80 24 | path: / 25 | pathType: ImplementationSpecific 26 | - backend: 27 | service: 28 | name: prometheus-grafana 29 | port: 30 | number: 80 31 | path: /grafana 32 | pathType: ImplementationSpecific 33 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/AnnualReportMenu.less: -------------------------------------------------------------------------------- 1 | .report-menu { 2 | position: fixed; 3 | top: 64px; 4 | right: 0px; 5 | z-index: 1; 6 | vertical-align: center; 7 | top: 120px; 8 | float: right; 9 | } 10 | 11 | .report-menu-item { 12 | background: #3c5438; 13 | border-radius: 0 2px 2px 0; 14 | cursor: pointer; 15 | width: 36px; 16 | height: 42px; 17 | color: #fff; 18 | margin-top: 10px; 19 | font-size: x-large; 20 | line-height: 42px; 21 | text-align: center; 22 | } 23 | 24 | .report-menu-item:hover { 25 | background-color: hsla(111, 20%, 27%, 0.9); 26 | } 27 | 28 | .report-menu-item-clicked { 29 | background-color: hsla(91, 24%, 51%, 0.9); 30 | border-radius: 0 2px 2px 0; 31 | width: 36px; 32 | height: 42px; 33 | color: #fff; 34 | margin-top: 10px; 35 | font-size: x-large; 36 | line-height: 42px; 37 | text-align: center; 38 | } 39 | -------------------------------------------------------------------------------- /src/pages/userPage/ActiveMembership/PlastDegree/DeleteDegreeConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import activeMembershipApi from "../../../../api/activeMembershipApi"; 5 | const { confirm } = Modal; 6 | 7 | const DeleteDegreeConfirm = ( 8 | userId: string, 9 | plastDegreeId: number, 10 | handleDelete: any 11 | ) => { 12 | const remove = async () => { 13 | await activeMembershipApi.removeUserPlastDegree(userId, plastDegreeId); 14 | }; 15 | 16 | return confirm({ 17 | title: "Ви справді хочете видалити даний ступінь користувачу?", 18 | icon: , 19 | okText: "Так", 20 | cancelText: "Ні", 21 | onOk() { 22 | remove(); 23 | handleDelete(plastDegreeId); 24 | }, 25 | }); 26 | }; 27 | 28 | export default DeleteDegreeConfirm; 29 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/Sector/SectorAnnouncement/DeleteConfirm.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import { ExclamationCircleOutlined } from "@ant-design/icons"; 4 | import { deleteSectorAnnouncement } from "../../../../api/governingBodySectorsApi"; 5 | import notificationLogic from "../../../../components/Notifications/Notification"; 6 | 7 | const { confirm } = Modal; 8 | 9 | const DeleteConfirm = (id: number, onDelete: any) => { 10 | return confirm({ 11 | title: "Ви справді хочете видалити оголошення?", 12 | icon: , 13 | okText: "Так", 14 | cancelText: "Ні", 15 | onOk() { 16 | const remove = async () => { 17 | deleteSectorAnnouncement(id); 18 | }; 19 | remove(); 20 | onDelete(id); 21 | notificationLogic("success", "Оголошення видалено"); 22 | }, 23 | }); 24 | }; 25 | export default DeleteConfirm; 26 | -------------------------------------------------------------------------------- /manifests/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion : apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: eplastweb 5 | labels: 6 | app: eplastweb 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: eplastweb 11 | template: 12 | metadata: 13 | labels: 14 | app: eplastweb 15 | spec: 16 | containers: 17 | - name: eplastweb 18 | image: eplast.azurecr.io/eplastweb:___containerRegistry_version_frontend_test___ 19 | resources: 20 | limits: 21 | cpu: "100m" 22 | memory: "100Mi" 23 | ports: 24 | - containerPort: 80 25 | 26 | --- 27 | apiVersion: autoscaling/v1 28 | kind: HorizontalPodAutoscaler 29 | metadata: 30 | name: eplastweb-autoscaler 31 | spec: 32 | scaleTargetRef: 33 | apiVersion: apps/v1 34 | kind: Deployment 35 | name: eplastweb 36 | targetCPUUtilizationPercentage: 70 37 | minReplicas: 1 38 | maxReplicas: 2 39 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/ClubAnnualReport.ts: -------------------------------------------------------------------------------- 1 | import Club from "../../../models/Club/Club"; 2 | import ClubAdmin from "../../../models/Club/ClubAdmin"; 3 | import ClubMember from "../../../models/Club/ClubMember"; 4 | 5 | interface ClubAnnualReport { 6 | id: number; 7 | idView: any; 8 | name: string; 9 | status: number; 10 | date: Date; 11 | currentClubMembers: number; 12 | currentClubFollowers: number; 13 | clubEnteredMembersCount: number; 14 | clubLeftMembersCount: number; 15 | clubCenters: string; 16 | clubContacts: string; 17 | clubPage: string; 18 | kbUSPWishes: string; 19 | clubId: number; 20 | club: Club | null; 21 | clubMembersSummary: string; 22 | clubAdminContacts: string; 23 | clubName: string; 24 | email?: string; 25 | phoneNumber?: string; 26 | head?: ClubAdmin; 27 | members?: ClubMember[]; 28 | admins?: ClubAdmin[]; 29 | followers?: ClubMember[]; 30 | } 31 | 32 | export default ClubAnnualReport; 33 | -------------------------------------------------------------------------------- /src/pages/UserTable/AcceptUserToCityModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import AcceptUserToCityForm from "./AcceptUserToCityForm"; 4 | 5 | interface Props { 6 | onChange: (id: string, userRoles: string) => void; 7 | record: string; 8 | showModal: boolean; 9 | setShowModal: (showModal: any) => void; 10 | user: any; 11 | } 12 | const AcceptUserToCityModal = ({ 13 | record, 14 | showModal, 15 | setShowModal, 16 | onChange, 17 | }: Props) => { 18 | return ( 19 | setShowModal(false)} 25 | > 26 | 32 | 33 | ); 34 | }; 35 | 36 | export default AcceptUserToCityModal; 37 | -------------------------------------------------------------------------------- /src/models/City/CityProfile.tsx: -------------------------------------------------------------------------------- 1 | import UkraineOblasts from "../Oblast/UkraineOblasts"; 2 | import CityAdmin from "./CityAdmin"; 3 | 4 | export default class CityProfile { 5 | id: number; 6 | name: string; 7 | logo: string | null; 8 | description: string; 9 | cityURL: string; 10 | phoneNumber: string; 11 | email: string; 12 | region: string; 13 | address: string; 14 | level: number; 15 | head: CityAdmin; 16 | headDeputy: CityAdmin; 17 | isActive: boolean; 18 | oblast: UkraineOblasts; 19 | constructor() { 20 | this.id = 0; 21 | this.name = ""; 22 | this.logo = ""; 23 | this.description = ""; 24 | this.cityURL = ""; 25 | this.phoneNumber = ""; 26 | this.email = ""; 27 | this.region = ""; 28 | this.address = ""; 29 | this.level = 1; 30 | this.head = new CityAdmin(); 31 | this.headDeputy = new CityAdmin(); 32 | this.isActive = true; 33 | this.oblast = UkraineOblasts.NotSpecified; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/pages/AboutBase/AddSubsectionModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer } from "antd"; 3 | import FormAddSubsection from "./FormAddSubsection"; 4 | 5 | interface Props { 6 | visibleModal: boolean; 7 | setVisibleModal: (visibleModal: boolean) => void; 8 | sectId: number; 9 | fetchSubData: Function; 10 | } 11 | 12 | const AddSubsectionModal = ({ 13 | visibleModal, 14 | setVisibleModal, 15 | sectId, 16 | fetchSubData, 17 | }: Props) => { 18 | const handleCancel = () => { 19 | setVisibleModal(false); 20 | }; 21 | return ( 22 | 29 | 34 | 35 | ); 36 | }; 37 | 38 | export default AddSubsectionModal; 39 | -------------------------------------------------------------------------------- /src/pages/Regions/Form.module.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .formSelectAlignCenter{ 4 | align-Items: flex-start; 5 | } 6 | 7 | 8 | .inputField{ 9 | float: right; 10 | text-align: left; 11 | 12 | 13 | } 14 | 15 | .datePicker { 16 | width: 100%; 17 | } 18 | 19 | .submitRow{ 20 | flex-direction: row-reverse; 21 | } 22 | 23 | @media (max-width: 576px){ 24 | .inputField{ 25 | width: 100%; 26 | } 27 | } 28 | 29 | 30 | .selectField { 31 | float: right; 32 | text-align: left; 33 | width:320px; 34 | 35 | } 36 | 37 | .formOption { 38 | display: flex; 39 | justify-content: space-between; 40 | align-items: center; 41 | } 42 | 43 | .formField { 44 | width: 100%; 45 | } 46 | 47 | .cardButton{ 48 | float: right; 49 | inline-size: -webkit-fill-available; 50 | margin-top: 7px; 51 | color:#3c5438; 52 | border-color: #3c5438; 53 | max-width: 320px; 54 | min-width: 320px; 55 | } -------------------------------------------------------------------------------- /src/components/ImagePreview/ImagePreview.less: -------------------------------------------------------------------------------- 1 | .modal-wrapper { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | top: 0; 6 | width: auto !important; 7 | height: 100% !important; 8 | margin: 0 !important; 9 | padding: 0 !important; 10 | } 11 | 12 | .modal-wrapper .ant-modal-content .ant-modal-close .ant-modal-close-x { 13 | color: white; 14 | position: fixed; 15 | top: 0; 16 | right: 0; 17 | } 18 | 19 | .modal-wrapper .ant-modal-content { 20 | background: none; 21 | box-shadow: none; 22 | } 23 | 24 | .modal-wrapper .ant-modal-body { 25 | padding: 0; 26 | display: flex; 27 | justify-content: center; 28 | } 29 | 30 | .image { 31 | max-height: 90vh; 32 | max-width: 90%; 33 | margin: auto; 34 | } 35 | 36 | .file-name { 37 | padding-top: 15px; 38 | padding-left: 20px; 39 | position: fixed; 40 | 41 | top: 0; 42 | left: 0; 43 | 44 | font-size: 15px; 45 | color: white; 46 | text-shadow: 0 0 1px black; 47 | } 48 | -------------------------------------------------------------------------------- /src/pages/UserTable/DeleteGoverningBodyAdminModal.tsx: -------------------------------------------------------------------------------- 1 | import { Modal } from "antd"; 2 | import React from "react"; 3 | import DeleteGoverningBodyAdminForm from "./DeleteGoverningBodyAdminForm"; 4 | 5 | interface Props { 6 | onChange: (id: string, userRoles: string) => void; 7 | showModal: boolean; 8 | setShowModal: (showModal: any) => void; 9 | user: any; 10 | } 11 | 12 | const DeleteGoverningBodyAdminModal = ({ 13 | user, 14 | showModal, 15 | setShowModal, 16 | onChange, 17 | }: Props) => { 18 | return ( 19 | setShowModal(false)} 25 | destroyOnClose 26 | > 27 | 32 | 33 | ); 34 | }; 35 | 36 | export default DeleteGoverningBodyAdminModal; 37 | -------------------------------------------------------------------------------- /src/models/Region/RegionProfile.tsx: -------------------------------------------------------------------------------- 1 | import { UkraineOblasts } from "../Oblast/UkraineOblasts"; 2 | 3 | export default class RegionProfile { 4 | id: number; 5 | 6 | regionName: string; 7 | 8 | logo: string | null; 9 | 10 | description: string; 11 | 12 | link: string; 13 | 14 | phoneNumber: string; 15 | 16 | email: string; 17 | 18 | oblast: UkraineOblasts; 19 | 20 | city: string; 21 | 22 | street: string; 23 | 24 | houseNumber: string; 25 | 26 | officeNumber: string; 27 | 28 | postIndex: string; 29 | 30 | isActive: boolean; 31 | 32 | constructor() { 33 | this.id = 0; 34 | this.regionName = ""; 35 | this.logo = ""; 36 | this.description = ""; 37 | this.link = ""; 38 | this.phoneNumber = ""; 39 | this.email = ""; 40 | this.city = ""; 41 | this.street = ""; 42 | this.houseNumber = ""; 43 | this.officeNumber = ""; 44 | this.oblast = UkraineOblasts.NotSpecified; 45 | this.postIndex = ""; 46 | this.isActive = true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/pages/Actions/EventTypes/EventTypeCard.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Card } from "antd"; 3 | import EvenTypeLogo from "../../../assets/images/ActionLogo.png"; 4 | 5 | import { useHistory } from "react-router-dom"; 6 | 7 | const classes = require("./EventTypeCard.module.css"); 8 | 9 | interface CardProps { 10 | id: number; 11 | eventTypeName: string; 12 | } 13 | 14 | interface Props { 15 | item: CardProps; 16 | } 17 | 18 | const EventTypeCard = ({ item: { id, eventTypeName } }: Props) => { 19 | const { Meta } = Card; 20 | const history = useHistory(); 21 | 22 | return ( 23 |
24 | } 29 | onClick={() => history.push(`/events/${id}/categories`)} 30 | > 31 | 32 | 33 |
34 | ); 35 | }; 36 | export default EventTypeCard; 37 | -------------------------------------------------------------------------------- /src/pages/UserTable/ChangeUserGoverningBodyModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import ChangeUserGoverningBodyForm from "./ChangeUserGoverningBodyForm"; 4 | 5 | interface Props { 6 | onChange: (id: string, userRoles: string) => void; 7 | record: string; 8 | showModal: boolean; 9 | setShowModal: (showModal: any) => void; 10 | user: any; 11 | } 12 | const ChangeUserGoverningBodyModal = ({ 13 | record, 14 | showModal, 15 | setShowModal, 16 | onChange, 17 | user, 18 | }: Props) => { 19 | return ( 20 | setShowModal(false)} 26 | destroyOnClose 27 | > 28 | 34 | 35 | ); 36 | }; 37 | 38 | export default ChangeUserGoverningBodyModal; 39 | -------------------------------------------------------------------------------- /craco.config.js: -------------------------------------------------------------------------------- 1 | const CracoLessPlugin = require("craco-less"); 2 | 3 | module.exports = { 4 | plugins: [ 5 | { 6 | plugin: CracoLessPlugin, 7 | options: { 8 | lessLoaderOptions: { 9 | lessOptions: { 10 | modifyVars: { 11 | "@primary-color": "#3c5438", 12 | "@layout-header-background": "#3c5438", 13 | "@layout-footer-background": "#3c5438", 14 | "@layout-sider-background": "#3c5438", 15 | "@menu-dark-item-hover-bg": "transparent", 16 | "@menu-bg": "#3c5438", 17 | "@menu-item-active-border-width": "none", 18 | "@dropdown-menu-bg": "#3c5438", 19 | "@menu-dark-submenu-bg": "#3c5438", 20 | "@layout-trigger-background": "#3c5438", 21 | "@tooltip-bg": "#3c5438", 22 | "@item-hover-bg": "transparent", 23 | }, 24 | javascriptEnabled: true, 25 | }, 26 | }, 27 | }, 28 | }, 29 | ], 30 | }; 31 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/ClubMembersTable.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState, PropsWithRef } from "react"; 2 | import { Table, Spin, Input } from "antd"; 3 | import columns from "./columnsClubsMembers"; 4 | import { getUsersAdministrations } from "../../api/clubsApi"; 5 | 6 | interface props { 7 | UserId: string; 8 | } 9 | 10 | export const ClubMembersTable = ({ UserId }: props) => { 11 | const [data, setData] = useState([ 12 | { 13 | id: "", 14 | user: "", 15 | adminType: "", 16 | startDate: "", 17 | endDate: "", 18 | clubId: "", 19 | }, 20 | ]); 21 | 22 | const fetchData = async () => { 23 | await getUsersAdministrations(UserId).then((response: { data: any }) => { 24 | setData(response.data); 25 | }); 26 | }; 27 | 28 | useEffect(() => { 29 | fetchData(); 30 | }, []); 31 | 32 | return ( 33 |
34 |

Список членів куреня:

35 |
36 | 37 | 38 | ); 39 | }; 40 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventInfo/EventDetailsHeader.less: -------------------------------------------------------------------------------- 1 | .descriptions { 2 | width: 100%; 3 | padding: 10px 10px 0 10px; 4 | text-overflow: ellipsis; 5 | 6 | @media (max-width: 750px) { 7 | .ant-descriptions-view > table { 8 | table-layout: fixed; 9 | } 10 | } 11 | } 12 | 13 | .descriptions-item { 14 | background: none !important; 15 | //background-color: rgba(0, 0, 0, 0.05) !important; 16 | border: none !important; 17 | } 18 | 19 | .eventLabel { 20 | color: var(--antd-wave-shadow-color); 21 | font-weight: bold; 22 | } 23 | 24 | .url { 25 | font-weight: bold; 26 | width: 190px; 27 | font-size: 14px; 28 | } 29 | 30 | /* unvisited link */ 31 | .ant-typography a:link { 32 | color: rgba(0, 0, 0, 0.65); 33 | } 34 | 35 | /* visited link */ 36 | .ant-typography a:visited { 37 | color: rgb(24, 68, 24); 38 | } 39 | 40 | /* mouse over link */ 41 | .ant-typography a:hover { 42 | color: rgba(206, 50, 50, 0.65); 43 | } 44 | 45 | /* selected link */ 46 | .ant-typography a:active { 47 | color: grey; 48 | } 49 | -------------------------------------------------------------------------------- /src/components/PrivateLayout/useOneClickOutside.tsx: -------------------------------------------------------------------------------- 1 | import { RefObject, useEffect } from "react"; 2 | 3 | type AnyEvent = MouseEvent | TouchEvent; 4 | 5 | function useOnClickOutside( 6 | ref: RefObject, 7 | handler: (event: AnyEvent) => void 8 | ) { 9 | useEffect(() => { 10 | const listener = (event: AnyEvent) => { 11 | const el = ref?.current; 12 | 13 | // Do nothing if clicking ref's element or descendent elements 14 | if (!ref?.current || ref?.current.contains(event.target as Node)) { 15 | return; 16 | } 17 | 18 | handler(event); 19 | }; 20 | 21 | document.addEventListener(`mousedown`, listener); 22 | document.addEventListener(`touchstart`, listener); 23 | 24 | return () => { 25 | document.removeEventListener(`mousedown`, listener); 26 | document.removeEventListener(`touchstart`, listener); 27 | }; 28 | 29 | // Reload only if ref or handler changes 30 | }, [ref, handler]); 31 | } 32 | 33 | export default useOnClickOutside; 34 | -------------------------------------------------------------------------------- /src/models/Club/ClubUser.tsx: -------------------------------------------------------------------------------- 1 | import { PlastDegree } from "../../api/activeMembershipApi"; 2 | 3 | export default class ClubUser { 4 | id: string; 5 | firstName: string; 6 | lastName: string; 7 | imagePath: string; 8 | email: string; 9 | phoneNumber: string; 10 | userRole: string; 11 | cityName: string; 12 | userPlastDegrees: any; 13 | cityMembers: any; 14 | clubReportCities: any; 15 | clubReportPlastDegrees: any; 16 | 17 | constructor() { 18 | this.id = ""; 19 | this.firstName = ""; 20 | this.lastName = ""; 21 | this.imagePath = ""; 22 | this.email = ""; 23 | this.phoneNumber = ""; 24 | this.userRole = ""; 25 | this.cityName = ""; 26 | this.userPlastDegrees = { 27 | plastDegree: { id: -1, name: "" }, 28 | }; 29 | this.cityMembers = { 30 | city: { id: -1, name: "" }, 31 | }; 32 | this.userPlastDegrees = { 33 | plastDegree: { id: -1, name: "" }, 34 | }; 35 | this.userPlastDegrees = { 36 | plastDegree: { id: -1, name: "" }, 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/models/Roles/AdminRole.tsx: -------------------------------------------------------------------------------- 1 | export enum AdminRole { 2 | Admin = 0, // Admin 3 | GoverningBodyAdmin = 1, // Крайовий адмін 4 | GoverningBodyHead = 2, // Голова керівного органу 5 | OkrugaHead = 3, // Голова округи 6 | OkrugaHeadDeputy = 4, // Заступник голови округи 7 | CityHead = 5, // Голова станиці 8 | CityHeadDeputy = 6, // Заступник голови станиці 9 | KurinHead = 7, // Голова куреня 10 | KurinHeadDeputy = 8, // Заступник голови куреня 11 | OkrugaReferentUPS = 9, // Референт/-ка УПС Округи 12 | OkrugaReferentUSP = 10, // Референт/-ка УСП Округи 13 | OkrugaReferentOfActiveMembership = 11, // Референт дійсного членства Округи 14 | CityReferentUPS = 12, // Референт/-ка УПС Станиці 15 | CityReferentUSP = 13, // Референт/-ка УСП Станиці 16 | CityReferentOfActiveMembership = 14, // Референт дійсного членства Станиці 17 | } 18 | 19 | // This enum is used to compare which one of two admins has more rights (user table) 20 | // Roles in enum must be written strictly in descending order, starting with 21 | // role with most rights ('Admin') 22 | -------------------------------------------------------------------------------- /src/pages/SignIn/FacebookLoginWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import facebookImg from "../../assets/images/facebook.png"; 3 | import FacebookLogin from "react-facebook-login"; 4 | import styles from "./SignIn.module.css"; 5 | 6 | const FacebookLoginWrapper = (props: any) => { 7 | const responseFacebook = (response: any) => { 8 | if (response.status !== "unknown") { 9 | props.handleFacebookResponse(response); 10 | } 11 | }; 12 | return ( 13 | 21 | Facebook icon 26 | 27 | } 28 | textButton=" Facebook" 29 | /> 30 | ); 31 | }; 32 | export default FacebookLoginWrapper; 33 | -------------------------------------------------------------------------------- /src/pages/UserTable/ChangeUserRoleModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import ChangeUserRoleForm from "./ChangeUserRoleForm"; 4 | import "./ChangeUserRoleModal.less"; 5 | import Form from "antd/lib/form/Form"; 6 | 7 | interface Props { 8 | record: string; 9 | showModal: boolean; 10 | setShowModal: (showModal: any) => void; 11 | onChange: (id: string, userRoles: string) => void; 12 | user: any; 13 | } 14 | const ChangeUserRoleModal = ({ 15 | record, 16 | showModal, 17 | setShowModal, 18 | onChange, 19 | user, 20 | }: Props) => { 21 | return ( 22 | setShowModal(false)} 28 | destroyOnClose={true} 29 | > 30 | 36 | 37 | ); 38 | }; 39 | 40 | export default ChangeUserRoleModal; 41 | -------------------------------------------------------------------------------- /src/pages/RegionsBoard/AddMainAdministratorModal/AddRegionBoardMainAdminModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal } from "antd"; 3 | import AddRegionBoardMainAdminForm from "./AddRegionBoardMainAdminForm"; 4 | 5 | interface Props { 6 | visibleModal: boolean; 7 | setVisibleModal: (visibleModal: boolean) => void; 8 | handleAddGoverningBodyAdmin: (values: any) => void; 9 | } 10 | 11 | const AddRegionBoardMainAdminModal = ({ 12 | visibleModal, 13 | setVisibleModal, 14 | handleAddGoverningBodyAdmin, 15 | }: Props) => { 16 | const handleCancel = () => setVisibleModal(false); 17 | 18 | return ( 19 | 25 | 30 | 31 | ); 32 | }; 33 | 34 | export default AddRegionBoardMainAdminModal; 35 | -------------------------------------------------------------------------------- /src/pages/Contacts/Contacts.module.css: -------------------------------------------------------------------------------- 1 | #environmentOutlined{ 2 | font-size: 24px; 3 | margin-right: 20px; 4 | } 5 | 6 | #InfoOut{ 7 | font-size: 24px; 8 | margin: 5px 20px 0 0; 9 | } 10 | 11 | #addonElement{ 12 | width: 100%; 13 | } 14 | 15 | .contacts { 16 | display: flex; 17 | justify-content: space-evenly; 18 | margin-top: 50px; 19 | } 20 | 21 | .contactsList { 22 | width: 20%; 23 | } 24 | 25 | .contactsForm { 26 | width: 30%; 27 | } 28 | 29 | .contactsForm button { 30 | height: 40px; 31 | width: 100%; 32 | } 33 | 34 | @media (max-width: 576px) { 35 | .contacts { 36 | display: flex; 37 | flex-direction: column; 38 | padding: 0 30px; 39 | } 40 | 41 | .contactsList, 42 | .contactsForm { 43 | width: 100%; 44 | } 45 | 46 | .contactsList h1 { 47 | margin-left: 25px; 48 | } 49 | 50 | .contactsForm { 51 | margin-top: 40px; 52 | } 53 | } 54 | 55 | @media (min-width: 576px)and(max-width: 768px) { 56 | .contacts { 57 | justify-content: space-around; 58 | } 59 | 60 | .contactsList { 61 | width: 30%; 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/components/Footer/FooterContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Layout } from "antd"; 3 | import Facebook from "../../assets/images/facebook.svg"; 4 | import Twitter from "../../assets/images/bird.svg"; 5 | import Instagram from "../../assets/images/instagram.svg"; 6 | import classes from "./Footer.module.css"; 7 | import moment from "moment"; 8 | 9 | const FooterContainer = () => { 10 | return ( 11 | 12 | 23 |

24 | ePlast © {moment().format("YYYY")} 25 |

26 |
27 | ); 28 | }; 29 | export default FooterContainer; 30 | -------------------------------------------------------------------------------- /src/pages/Distinction/DistinctionTable/FormEdit.module.css: -------------------------------------------------------------------------------- 1 | .editIcon { 2 | font-size: 24px; 3 | color: #3c5438; 4 | } 5 | .editIcon :hover { 6 | color: #536150; 7 | cursor: pointer; 8 | } 9 | .deleteIcon { 10 | font-size: 24px; 11 | color: #910202; 12 | } 13 | .deleteIcon :hover { 14 | color: #690606; 15 | cursor: pointer; 16 | } 17 | .editDiv { 18 | display: flex; 19 | justify-content: space-between; 20 | align-items: center; 21 | } 22 | .list { 23 | max-height: 400px; 24 | overflow: auto; 25 | max-width: 520px; 26 | font-size: 16px; 27 | display: flex; 28 | } 29 | .inputField { 30 | size: 50px; 31 | margin-right: auto; 32 | float: right; 33 | text-align: left; 34 | } 35 | 36 | .list > * { 37 | width: 100%; 38 | } 39 | 40 | .buttons { 41 | margin-right: 0px !important; 42 | margin-left: 7px; 43 | } 44 | 45 | @media (max-width: 490px) { 46 | .list { 47 | max-width: 400px; 48 | font-size: 16px; 49 | } 50 | .editIcon { 51 | font-size: 18px; 52 | color: #3c5438; 53 | } 54 | .deleteIcon { 55 | font-size: 18px; 56 | color: #910202; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/AnnualReport.ts: -------------------------------------------------------------------------------- 1 | import MembersStatistic from "./MembersStatistic"; 2 | import User from "./User"; 3 | import City from "./City"; 4 | 5 | interface AnnualReport { 6 | id: number; 7 | idView: any; 8 | date: Date; 9 | status: number; 10 | numberOfSeatsPtashat: number; 11 | numberOfIndependentRiy: number; 12 | numberOfClubs: number; 13 | numberOfIndependentGroups: number; 14 | numberOfTeachers: number; 15 | numberOfAdministrators: number; 16 | numberOfTeacherAdministrators: number; 17 | numberOfBeneficiaries: number; 18 | numberOfPlastpryiatMembers: number; 19 | numberOfHonoraryMembers: number; 20 | publicFunds: number; 21 | contributionFunds: number; 22 | plastSalary: number; 23 | sponsorshipFunds: number; 24 | listProperty: string | null; 25 | improvementNeeds: string | null; 26 | membersStatistic: MembersStatistic; 27 | creatorId: string; 28 | creator: User | null; 29 | newCityAdminId: string; 30 | newCityAdmin: User | null; 31 | newCityLegalStatusType: number; 32 | cityId: number; 33 | city: City | null; 34 | } 35 | 36 | export default AnnualReport; 37 | -------------------------------------------------------------------------------- /src/pages/SignUp/CheckboxsItem.tsx: -------------------------------------------------------------------------------- 1 | import { Checkbox, Form, Space } from "antd"; 2 | import React from "react"; 3 | import { emptyInput } from "../../components/Notifications/Messages"; 4 | 5 | interface RadioOrInputProps { 6 | checkboxList: string[] 7 | title: string 8 | name: string 9 | } 10 | 11 | const CheckboxsItem: React.FC = ({ checkboxList, title, name }) => { 12 | return ( 13 | {title}} 20 | name={name} 21 | rules={[{ required: true, message: emptyInput() }]} 22 | > 23 | 24 | 25 | {checkboxList.map(c => 26 | {c} 27 | )} 28 | 29 | 30 | 31 | ); 32 | } 33 | 34 | export default CheckboxsItem; -------------------------------------------------------------------------------- /src/pages/Precaution/PrecautionTable/FormEdit.module.css: -------------------------------------------------------------------------------- 1 | .editIcon { 2 | font-size: 24px; 3 | color:#3c5438; 4 | } 5 | .editIcon :hover { 6 | color: #536150; 7 | cursor: pointer; 8 | } 9 | .deleteIcon { 10 | font-size: 24px; 11 | color: #910202; 12 | } 13 | .deleteIcon :hover{ 14 | color: #690606; 15 | cursor: pointer; 16 | } 17 | .editDiv{ 18 | display: flex; 19 | justify-content: space-between; 20 | align-items: center; 21 | } 22 | .list { 23 | max-width: 520px; 24 | font-size: 18px; 25 | display: flex; 26 | } 27 | .inputField { 28 | size: 50px; 29 | margin-right: auto; 30 | float: right; 31 | text-align: left; 32 | } 33 | .list>* { 34 | width: 100% 35 | } 36 | 37 | @media (max-width: 490px){ 38 | .list{ 39 | max-width: 400px; 40 | font-size: 12px; 41 | } 42 | .editIcon { 43 | font-size: 18px; 44 | color:#3c5438; 45 | } 46 | .deleteIcon { 47 | font-size: 18px; 48 | color: #910202; 49 | } 50 | 51 | } 52 | .buttons{ 53 | margin-right: 0px !important; 54 | margin-left: 7px; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 SoftServe IT Academy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/pages/AnnualReport/Interfaces/RegionMembersInfo.tsx: -------------------------------------------------------------------------------- 1 | interface RegionMembersInfo { 2 | total: number; 3 | cityAnnualReportId: number; 4 | cityId: number; 5 | reportStatus: number; 6 | cityName: string; 7 | numberOfSeatsPtashat: number; 8 | numberOfIndependentRiy: number; 9 | numberOfClubs: number; 10 | numberOfIndependentGroups: number; 11 | numberOfTeachers: number; 12 | numberOfAdministrators: number; 13 | numberOfTeacherAdministrators: number; 14 | numberOfBeneficiaries: number; 15 | numberOfPlastpryiatMembers: number; 16 | numberOfHonoraryMembers: number; 17 | numberOfPtashata: number; 18 | numberOfNovatstva: number; 19 | numberOfUnatstva: number; 20 | numberOfUnatstvaNoname: number; 21 | numberOfUnatstvaSupporters: number; 22 | numberOfUnatstvaMembers: number; 23 | numberOfUnatstvaProspectors: number; 24 | numberOfUnatstvaSkobVirlyts: number; 25 | numberOfSenior: number; 26 | numberOfSeniorPlastynSupporters: number; 27 | numberOfSeniorPlastynMembers: number; 28 | numberOfSeigneur: number; 29 | numberOfSeigneurSupporters: number; 30 | numberOfSeigneurMembers: number; 31 | } 32 | 33 | export default RegionMembersInfo; 34 | -------------------------------------------------------------------------------- /src/pages/DecisionTable/EditDecisionModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Modal, Drawer } from "antd"; 3 | import FormEditDecision from "./FormEditDecision"; 4 | import { DecisionPost } from "../../api/decisionsApi"; 5 | 6 | interface Props { 7 | record: number; 8 | decision: DecisionPost; 9 | showModal: boolean; 10 | setShowModal: (showModal: boolean) => void; 11 | onEdit: ( 12 | id: number, 13 | name: string, 14 | description: string, 15 | statusType: string 16 | ) => void; 17 | } 18 | const EditDecisionModal = ({ 19 | record, 20 | showModal, 21 | setShowModal, 22 | onEdit, 23 | decision, 24 | }: Props) => { 25 | const handleCancel = () => setShowModal(false); 26 | 27 | return ( 28 | 35 | 41 | 42 | ); 43 | }; 44 | 45 | export default EditDecisionModal; 46 | -------------------------------------------------------------------------------- /src/pages/SignIn/GoogleLoginWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button } from "antd"; 3 | import googleImg from "../../assets/images/google.png"; 4 | import { GoogleLogin } from "react-google-login"; 5 | import styles from "./SignIn.module.css"; 6 | 7 | const GoogleLoginWrapper = (props: any) => { 8 | return ( 9 | ( 12 | 27 | )} 28 | buttonText="Login" 29 | onSuccess={props.handleGoogleResponse} 30 | onFailure={props.getIdprop} 31 | cookiePolicy={"single_host_origin"} 32 | /> 33 | ); 34 | }; 35 | export default GoogleLoginWrapper; 36 | -------------------------------------------------------------------------------- /src/pages/SignUp/TabList.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import styles from "./SignUp.module.css"; 3 | 4 | import { Tabs } from "antd"; 5 | const { TabPane } = Tabs; 6 | 7 | export enum TabRenderMode { 8 | Default, 9 | UnmountOther, 10 | } 11 | 12 | interface TabInputsProps { 13 | renderMode: TabRenderMode 14 | pairs: { 15 | title: string 16 | content: JSX.Element 17 | disabled?: boolean 18 | }[] 19 | } 20 | 21 | const TabList: React.FC = ({ pairs, renderMode }) => { 22 | const [activeTab, setActiveTab] = useState(0); 23 | 24 | const handleChange = (key: number) => { 25 | setActiveTab(key) 26 | } 27 | 28 | return ( 29 | handleChange(Number(e))} defaultActiveKey={activeTab.toString()}> 30 | {pairs.map((p, i) => 31 | 32 | {renderMode === TabRenderMode.UnmountOther && 33 | activeTab !== i ? <> : p.content} 34 | 35 | )} 36 | 37 | ); 38 | } 39 | 40 | export default TabList; -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventEdit/EventEditDrawer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer, Button } from "antd"; 3 | import EventEdit from "./EventEdit"; 4 | import ButtonCollapse from "../../../../components/ButtonCollapse/ButtonCollapse"; 5 | 6 | interface Props { 7 | visibleEventEditDrawer: boolean; 8 | setShowEventEditDrawer: (visibleEventEditDrawer: boolean) => void; 9 | id: number; 10 | statusId: number; 11 | onEdit: () => void; 12 | } 13 | 14 | const EventEditDrawer = ({ 15 | visibleEventEditDrawer, 16 | setShowEventEditDrawer, 17 | id, 18 | statusId, 19 | onEdit, 20 | }: Props) => { 21 | const handleCancel = () => setShowEventEditDrawer(false); 22 | return ( 23 | 32 | 38 | 39 | ); 40 | }; 41 | 42 | export default EventEditDrawer; 43 | -------------------------------------------------------------------------------- /src/pages/Actions/ActionEvent/EventInfo/GalleryPictureAdd.tsx: -------------------------------------------------------------------------------- 1 | import { PlusOutlined } from "@ant-design/icons"; 2 | import { Modal } from "antd"; 3 | import React, { useState } from "react"; 4 | import FormAddPictures from "./FormAddPictures"; 5 | import "./GalleryPicture.less"; 6 | 7 | interface AddPictureProps { 8 | eventId: number; 9 | pictureList: number[]; 10 | addPicturesHook: (pictures: number[]) => void; 11 | } 12 | 13 | const GalleryPictureAdd: React.FC = (p: AddPictureProps) => { 14 | const [isModalVisible, setModalVisible] = useState(false); 15 | 16 | return ( 17 |
18 | setModalVisible(true)} 21 | /> 22 | setModalVisible(false)} 27 | > 28 | 33 | 34 |
35 | ); 36 | }; 37 | 38 | export default GalleryPictureAdd; 39 | -------------------------------------------------------------------------------- /src/pages/GoverningBody/Announcement/AddAnnouncementModal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Drawer } from "antd"; 3 | import FormAddAnnouncement from "./FormAddAnnouncement"; 4 | 5 | interface Props { 6 | governingBodyId?: number; 7 | visibleModal: boolean; 8 | setVisibleModal: (visibleModal: boolean) => void; 9 | onAdd: ( 10 | title: string, 11 | text: string, 12 | images: string[], 13 | isPined: boolean, 14 | gvbId: number, 15 | sectorId: number 16 | ) => void; 17 | } 18 | 19 | const AddAnnouncementModal = ({ 20 | governingBodyId, 21 | visibleModal, 22 | setVisibleModal, 23 | onAdd, 24 | }: Props) => { 25 | const handleCancel = () => { 26 | setVisibleModal(false); 27 | }; 28 | return ( 29 | 38 | 43 | 44 | ); 45 | }; 46 | 47 | export default AddAnnouncementModal; 48 | -------------------------------------------------------------------------------- /src/pages/userPage/Secretaries/columnsSectors.tsx: -------------------------------------------------------------------------------- 1 | import moment from "moment"; 2 | 3 | const minDate = "01.01.0001"; 4 | 5 | const columns = [ 6 | { 7 | title: "ID", 8 | dataIndex: "id", 9 | }, 10 | { 11 | title: "Користувач", 12 | dataIndex: "userName", 13 | render: (userName: string) => { 14 | return userName; 15 | }, 16 | }, 17 | { 18 | title: "Тип адміністрування", 19 | dataIndex: "adminType", 20 | render: (adminType: string) => { 21 | return adminType; 22 | }, 23 | }, 24 | { 25 | title: "Початок каденції", 26 | dataIndex: "startDate", 27 | render: (startDate: Date) => { 28 | return moment.utc(startDate).local().format("DD.MM.YYYY"); 29 | }, 30 | }, 31 | { 32 | title: "Кінець каденції", 33 | dataIndex: "endDate", 34 | render: (endDate: Date) => { 35 | const instanceDate = moment.utc(endDate).local().format("DD.MM.YYYY"); 36 | return instanceDate === minDate ? " Не закінчена " : instanceDate; 37 | }, 38 | }, 39 | { 40 | title: "Напрям", 41 | dataIndex: "sectorName", 42 | render: (sectorName: string) => { 43 | return sectorName; 44 | }, 45 | }, 46 | ]; 47 | 48 | export default columns; 49 | -------------------------------------------------------------------------------- /src/pages/WebChat/Demo.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Launcher } from "react-chat-window"; 3 | 4 | export class Demo extends Component { 5 | constructor() { 6 | super(); 7 | this.state = { 8 | messageList: [], 9 | }; 10 | } 11 | 12 | _onMessageWasSent(message) { 13 | this.setState({ 14 | messageList: [...this.state.messageList, message], 15 | }); 16 | } 17 | 18 | _sendMessage(text) { 19 | if (text.length > 0) { 20 | this.setState({ 21 | messageList: [ 22 | ...this.state.messageList, 23 | { 24 | author: "them", 25 | type: "text", 26 | data: { text }, 27 | }, 28 | ], 29 | }); 30 | } 31 | } 32 | 33 | render() { 34 | return ( 35 |
36 | 46 |
47 | ); 48 | } 49 | } 50 | --------------------------------------------------------------------------------