{"version":3,"sources":["shared/constants/deviceSizes.ts","routes/main-routes/styles.ts","shared/types/index.ts","pages/login-page/styles.ts","services/validation/index.ts","services/store/reducers/authReducer.ts","services/store/reducers/sidebarReducer.ts","services/store/reducers/modalReducer.ts","services/store/index.ts","services/api/api.ts","shared/hooks/store-hooks/index.ts","shared/hooks/helper-hooks/notifications/useNotifications.ts","shared/constants/errors.ts","shared/hooks/helper-hooks/copy-to-clipboard/useCopyToClipboard.tsx","shared/hooks/helper-hooks/debounce/useDebounce.tsx","utils/query-utils.ts","services/api/firmwareService.ts","shared/constants/pagination.ts","shared/hooks/data-hooks/firmware-versions/useFirmwareVersions.tsx","services/api/usersService.ts","shared/hooks/data-hooks/user/useUser.tsx","shared/hooks/data-hooks/users/useUsers.ts","services/api/devicesService.ts","shared/hooks/data-hooks/devices/useDevices.tsx","shared/hooks/data-hooks/shots/useShotsData.tsx","shared/hooks/data-hooks/shots/useUserShots.ts","services/api/shotsService.ts","shared/hooks/data-hooks/events/useEventsData.tsx","services/api/logService.ts","shared/hooks/data-hooks/logs/useLogs.tsx","shared/hooks/data-hooks/log/useLog.tsx","services/api/sessionsService.ts","shared/hooks/data-hooks/sessions/useSessions.ts","shared/hooks/data-hooks/session-comments/useSessionComments.ts","services/api/groupsService.ts","shared/hooks/data-hooks/groups/useGroups.ts","shared/hooks/data-hooks/group/useGroup.ts","shared/hooks/data-hooks/support-messages/useSupportMessages.ts","services/api/supportMessagesService.ts","services/api/bowsService.ts","shared/hooks/data-hooks/bow/useBow.tsx","shared/hooks/data-hooks/bows/useBows.ts","services/api/reportsService.ts","shared/hooks/data-hooks/reports/useReports.ts","shared/hooks/data-hooks/report/useReport.ts","services/api/publicGroupsService.ts","shared/hooks/data-hooks/public-groups/usePublicGroups.ts","shared/hooks/data-hooks/public-group/usePublicGroup.ts","shared/styles/index.ts","utils/error-utils.tsx","pages/login-page/LoginPage.tsx","services/api/authService.ts","pages/not-found-page/styles.ts","pages/not-found-page/NotFoundPage.tsx","shared/components/sidebar/constants.ts","shared/components/sidebar/styles.ts","assets/images/logo.svg","shared/components/sidebar/Sidebar.tsx","shared/components/content-container/styles.ts","shared/components/content-container/ContentContainer.tsx","shared/components/firmware-list/styles.ts","utils/sorting-utils.ts","shared/components/firmware-list/constants.ts","shared/components/firmware-list/FirmwareList.tsx","shared/components/modals/change-password-modal/styles.ts","shared/components/modals/change-password-modal/ChangePasswordModal.tsx","shared/components/modals/confirm-modal/ConfirmModal.tsx","shared/components/modals/firmware-actions-modal/styles.ts","shared/components/modals/firmware-actions-modal/FirmwareActionsModal.tsx","shared/components/modals/support-message-modal/styles.ts","shared/components/modals/support-message-modal/SupportMessageModal.tsx","shared/components/circle-diagram/styles.ts","shared/components/circle-diagram/CircleDiagram.tsx","shared/components/session-details/styles.ts","assets/images/bow-ava.png","utils/report-utils.ts","shared/components/session-details/SessionDetails.tsx","shared/components/shot-details/styles.ts","shared/components/shot-details/ShotDetails.tsx","shared/components/title/styles.ts","shared/components/title/Title.tsx","shared/components/charts/helpers.ts","shared/components/charts/styles.ts","shared/components/charts/Level.tsx","shared/components/charts/Steadiness.tsx","shared/components/charts/Torque.tsx","shared/components/charts/Duration.tsx","shared/components/charts/SmallTarget.tsx","shared/components/charts/FloatGraph.tsx","shared/components/target/styles.ts","shared/components/target/Target.tsx","shared/components/comment/styles.ts","shared/components/comment/Comment.tsx","shared/components/icon/Icon.tsx","shared/components/icon/TrainingIcon.tsx","shared/components/icon/HuntIcon.tsx","pages/check-a-bow-page/styles.ts","utils/date-utils.ts","pages/check-a-bow-page/constants.ts","pages/check-a-bow-page/CheckBowPage.tsx","pages/main-page/styles.ts","pages/main-page/MainPage.tsx","pages/add-user-page/styles.ts","shared/constants/roles.ts","utils/role-utils.ts","pages/add-user-page/AddUserPage.tsx","shared/providers/socket-provider/SocketProvider.tsx","pages/firmware-page/firmware-release/FirmwareRelease.tsx","pages/firmware-page/firmware-testing/FirmwareTesting.tsx","pages/users-page/styles.ts","pages/users-page/constants.ts","pages/users-page/UsersPage.tsx","pages/bow-users-page/styles.ts","pages/bow-users-page/constants.tsx","pages/bow-users-page/BowUsersPage.tsx","pages/bow-user-sessions-page/styles.ts","pages/bow-user-sessions-page/constants.tsx","pages/user-shots-page/constants.ts","pages/bow-user-sessions-page/BowUserSessionsPage.tsx","pages/sessions-page/styles.ts","pages/sessions-page/constants.tsx","pages/sessions-page/SessionsPage.tsx","pages/edit-user-page/styles.ts","pages/edit-user-page/EditUserPage.tsx","pages/edit-bow-user-page/styles.ts","pages/edit-bow-user-page/EditBowUserPage.tsx","pages/bow-details-page/styles.ts","pages/bow-details-page/constants.ts","utils/string-modifier-utils.ts","pages/bow-details-page/BowDetailsPage.tsx","pages/activity-log-page/styles.ts","utils/log-utils.ts","pages/activity-log-page/constants.tsx","pages/activity-log-page/ActivityLogPage.tsx","pages/ex-activity-log-page/styles.ts","pages/ex-activity-log-page/constants.tsx","pages/ex-activity-log-page/ExActivityLogPage.tsx","pages/log-details-page/styles.ts","pages/log-details-page/constants.ts","pages/log-details-page/LogDetailsPage.tsx","pages/ex-log-details-page/styles.ts","pages/ex-log-details-page/constants.ts","pages/ex-log-details-page/ExLogDetailsPage.tsx","pages/session-comments-page/styles.ts","pages/session-comments-page/constants.ts","pages/session-comments-page/SessionCommentsPage.tsx","pages/sessions-community-page/styles.ts","pages/sessions-community-page/constants.tsx","pages/sessions-community-page/SessionsCommunityPage.tsx","pages/user-groups-page/styles.ts","pages/user-groups-page/constants.ts","pages/user-groups-page/UserGroupsPage.tsx","pages/user-group-page/styles.ts","pages/user-group-page/UserGroupPage.tsx","pages/support-messages-page/styles.ts","pages/support-messages-page/constants.ts","pages/support-messages-page/SupportMessagesPage.tsx","pages/user-shots-page/styles.ts","pages/user-shots-page/UserShotsPage.tsx","pages/bows-page/styles.ts","pages/bows-page/constants.tsx","pages/bows-page/BowsPage.tsx","pages/add-bow-page/styles.ts","pages/add-bow-page/AddBowPage.tsx","pages/edit-bow-page/styles.ts","pages/edit-bow-page/EditBowPage.tsx","pages/reports-page/styles.ts","shared/constants/reports.ts","pages/reports-page/constants.tsx","pages/reports-page/ReportsPage.tsx","pages/report-page/styles.ts","pages/report-page/constants.ts","pages/report-page/ReportPage.tsx","services/api/statisticsService.ts","shared/hooks/data-hooks/statistics/useStatistics.tsx","shared/hooks/data-hooks/statistics/useUserDeviceStatistics.tsx","pages/statistics-page/helper.ts","pages/statistics-page/constants.tsx","pages/statistics-page/StatisticsPage.tsx","pages/group-requests-page/styles.ts","pages/group-requests-page/GroupRequests.tsx","pages/public-groups-page/styles.ts","shared/constants/publicGroups.ts","utils/public-groups.ts","pages/public-groups-page/constants.tsx","pages/public-groups-page/PublicGroupsPage.tsx","pages/public-group-page/styles.ts","pages/public-group-page/constants.ts","assets/images/group-ava.jpg","pages/public-group-page/PublicGroupPage.tsx","services/api/eventsService.ts","pages/events-page/constants.tsx","pages/events-page/styles.ts","pages/events-page/EventsPage.tsx","pages/group-events-page/constants.tsx","pages/group-events-page/styles.ts","pages/group-events-page/GroupEventsPage.tsx","pages/group-event-page/constants.tsx","pages/group-event-page/styles.ts","pages/group-event-page/GroupEventPage.tsx","pages/user-device-statistics-page/helper.ts","pages/user-device-statistics-page/constants.tsx","pages/user-device-statistics-page/UserDeviceStatisticsPage.tsx","routes/main-routes/routes.ts","routes/main-routes/MainRoutes.tsx","routes/guarded-route/GuardedRoute.tsx","routes/not-guarded-route/NotGuardedRoute.tsx","App.tsx","reportWebVitals.ts","index.tsx"],"names":["SIZE","DEVICE","tablet","concat","tabletLarge","desktop","RootContainer","styled","div","_templateObject","_taggedTemplateLiteral","_ref","isAuth","MenuButton","button","_templateObject2","ERouteType","EUserRole","EUserStatus","ESnackbarStyle","EFirmwareUpdateChannel","EFirmwareStatus","ESortType","LoginPageContainer","LoginForm","form","LoginFormTitle","_templateObject3","LoginFormInputContainer","_templateObject4","validation","LOG_IN","Yup","shape","email","required","password","min","max","ADD_USER","firstName","lastName","role","confirmPassword","oneOf","CREATE_BOW","image","modelName","drawLengthFrom","drawLengthTo","drawWeight","of","letOff","EDIT_BOW","EDIT_USER","EDIT_GROUP","name","CHANGE_PASSWORD","updatedPassword","UPLOAD_FIRMWARE","version","trim","test","value","ADD_SUPPORT_MESSAGE","message","CHECK_A_BOW","searchValue","loginUserSuccess","createAction","loginUserFail","logoutUser","authReducer","createReducer","user","builder","addCase","state","action","payload","localStorage","removeItem","openSidebar","closeSidebar","sidebarReducer","isSidebarOpened","showModal","closeModal","setIsDataLoadingParameter","modalReducer","isModalOpened","isModalDataLoading","modalWindow","store","configureStore","reducer","auth","sidebar","modal","middleware","getDefaultMiddleware","serializableCheck","ApiService","constructor","v","arguments","length","undefined","instance","this","axios","create","baseURL","process","interceptors","request","use","config","headers","Authorization","token","getItem","error","Promise","reject","response","async","status","__isRetryRequest","dispatch","data","Error","get","path","post","put","patch","delete","apiService","ApiServiceV2","useAppDispatch","useDispatch","useAppSelector","useSelector","useNotifications","openNotification","useCallback","type","text","notification","charAt","toUpperCase","slice","toLowerCase","description","useCopyToClipboard","copyToClipboard","navigator","clipboard","window","isSecureContext","writeText","textArea","document","createElement","style","position","left","top","body","appendChild","focus","select","resolve","execCommand","remove","processCopyAction","SUCCESS","e","ERROR","useDebounce","delay","debouncedValue","setDebouncedValue","useState","useEffect","handler","setTimeout","clearTimeout","getSortQueryParams","sortParams","map","item","join","getQueryParams","params","Object","entries","filter","encodeURIComponent","getURL","channelId","mainUrl","_len","rest","Array","_key","reduce","resultUrl","addFirmwareVersion","file","updateFirmwareVersion","versionId","firmware","PAGE_SIZE","LOGS_PAGE_SIZE","useFirmwareVersions","firmwareVersions","setFirmwareVersions","activeFirmware","setActiveFirmware","scheduledFirmware","setScheduledFirmware","isFirmwareVersionsLoading","setIsFirmwareVersionsLoading","currentPage","setCurrentPage","totalPages","setTotalPages","totalFirmwares","setTotalFirmwares","setSortParams","setSearchValue","debouncedSearchValue","fetchFirmwareVersions","page","limit","search","urlSortParams","getFirmwareVersions","totalPagesCount","totalItemsCount","pagination","items","fetchFirmwareByStatus","getFirmwareByStatus","semver","active","updateBowUser","userId","formData","useUser","setUser","isUserLoading","setIsUserLoading","fetchUser","getUser","removeUser","deleteUser","useUsers","users","setUsers","isUsersLoading","setIsUsersLoading","setPagination","pageSize","fetchUsers","showAll","getUsers","prevState","onChangePagination","getDeviceBySerialNumber","serialNumber","useDevices","devices","setDevices","isDevicesLoading","setIsDevicesLoading","totalDevices","setTotalDevices","fetchDevices","getDevices","useShotsData","bowSerialNumber","shots","setShots","requestShotsParams","setRequestShotsParams","dateRange","start","end","totalShots","setTotalShots","isShotsLoading","setIsShotsLoading","shotSortParams","setShotsSortParams","fetchDeviceShots","startDate","endDate","getDeviceShots","useUserShots","fetchShots","getShots","fetchCsvShot","shotId","shotName","timestamp","getCsvShot","link","href","URL","createObjectURL","Blob","setAttribute","parseISO","getTime","click","useEventsData","events","setEvents","requestEventsParams","setRequestEventsParams","totalEvents","setTotalEvents","isEventsLoading","setIsEventsLoading","eventsSortParams","setEventsSortParams","fetchDeviceEvents","getDeviceEvents","getLogs","query","logsType","initialLogs","useLogs","logs","setLogs","isLogsLoading","setIsLogsLoading","setSearch","inputSearch","setInputSearch","setType","isAutoUpdate","setIsAutoUpdate","fetchLogs","all","qwpnr","handleChangeSearch","useMemo","debounce","useLog","logId","logType","log","setLog","isLogLoading","setIsLogLoading","fetchLog","getLogById","useSessions","sessions","setSessions","isSessionsLoading","setIsSessionsLoading","fetchSessions","withoutShots","queryParams","getSessions","removeSession","sessionId","deleteSession","useSessionComments","sessionComments","setSessionComments","isSessionLoading","setIsSessionLoading","totalComments","setTotalComments","fetchSessionComments","getSessionComments","removeSessionComment","commentId","deleteSessionComment","getGroup","groupId","useGroups","groups","setGroups","isGroupsLoading","setIsGroupsLoading","fetchGroups","getGroups","useGroup","group","setGroup","isGroupLoading","setIsGroupLoading","fetchGroup","removeGroup","deleteGroup","useSupportMessages","messages","setMessages","totalMessages","setTotalMessages","isMessagesLoading","setIsMessagesLoading","fetchMessages","getMessages","useBow","bow","setBow","isBowLoading","setIsBowLoading","fetchBow","bowId","getBow","createBow","newBow","addBow","editBow","updatedBow","updateBow","removeBow","deleteBow","useBows","bows","setBows","totalBows","setTotalBows","isBowsLoading","setIsBowsLoading","fetchBows","getBows","deleteReport","reportId","updateReport","useReports","reports","setReports","isReportsLoading","setIsReportsLoading","setStatus","fetchReports","getReports","useReport","report","setReport","reportedObject","setReportedObject","isReportLoading","setIsReportLoading","isReportedObjectLoading","setIsReportedObjectLoading","fetchParentObject","parentId","reportType","includes","getReportedObject","fetchReport","fetchReportedObject","getReportById","reportObjectType","removeReport","changeReportStatus","usePublicGroups","publicGroups","setPublicGroups","isPublicGroupsLoading","setIsPublicGroupsLoading","fetchPublicGroups","getPublicGroups","usePublicGroup","publicGroup","setPublicGroup","isPublicGroupLoading","setIsPublicGroupLoading","fetchPublicGroup","publicGroupId","getPublicGroupById","acceptPublicGroup","acceptGroup","rejectPublicGroup","rejectGroup","ErrorMessage","PaginationContainer","getFieldError","formik","fieldName","meta","getFieldMeta","errorText","touched","_jsx","children","LoginPage","useFormik","initialValues","onSubmit","login","values","setItem","validationSchema","Styled","_jsxs","handleSubmit","Input","placeholder","size","onChange","handleChange","onBlur","handleBlur","disabled","isSubmitting","Password","iconRender","visible","EyeTwoTone","EyeInvisibleOutlined","Button","htmlType","block","loading","NotFoundPageContainer","NotFoundPage","history","useHistory","Result","background","subTitle","extra","onClick","navigateBack","goBack","SIDEBAR_ITEMS","title","icon","CodepenOutlined","subItems","FileDoneOutlined","roles","admin_user","master_admin","IssuesCloseOutlined","UserOutlined","moderator","TeamOutlined","ShoppingOutlined","GlobalOutlined","StockOutlined","AuditOutlined","PieChartOutlined","ShareAltOutlined","BarChartOutlined","SidebarContainer","CloseButton","SidebarContent","SidebarLogo","SidebarItems","_templateObject5","SidebarFooter","_templateObject6","SidebarUserInfo","_templateObject7","SidebarUserActions","_templateObject8","Overlay","_templateObject9","_ref2","Sidebar","location","useLocation","allowedSidebarItems","some","permissibleRole","handleMenuItemClick","subItemLink","push","handleCloseButtonClick","_Fragment","CloseOutlined","fontSize","NavLink","to","src","LogoIcon","alt","Menu","mode","theme","defaultSelectedKeys","selectedKeys","pathname","Icon","SubMenu","subItemTitle","SubItemIcon","Item","logOut","Container","ContentContainer","containerStyle","PageContainer","VersionsGroup","ScheduledVersion","SearchInput","TableContainer","getSortByValue","field","order","ASC","handleSortAction","filters","sorter","isArray","acc","column","sortByValue","sortKey","FIRMWARE_COLUMNS","dataIndex","key","multiple","FirmwareList","firmwareUpdateChannel","fetchFirmwareData","isDataLoading","showFirmwareActionsModal","record","FirmwareActionsModal","changelog","setSubmitting","FormData","append","setValues","PageHeader","width","moment","scheduledAt","format","event","target","allowClear","Table","columns","dataSource","onRow","Pagination","current","total","FormInputContainer","FormCheckboxContainer","FormInputInner","ChangePasswordModal","sendEmail","passwords","changeUserPassword","handleCancel","Modal","onOk","onCancel","okButtonProps","cancelButtonProps","handleCopyButtonClick","CopyOutlined","handleGeneratePasswordClick","Math","random","toString","Checkbox","checked","setFieldValue","ConfirmModal","confirmAction","modalTitle","UploadForm","UploadFormFieldContainer","UploadArea","FormatText","span","RadioGroupContainer","ScheduledButtonContainer","DatePickerContainer","RemoveButton","DownloadButton","EApplyStatus","applyStatus","ACTIVE","Date","toISOString","checkIsCorrectDate","SCHEDULED","isDateCorrect","archived","updateData","scheduled","getDataForUpdate","removeFirmware","deleteFirmwareVersion","Upload","fileList","regexp","originFileObj","beforeUpload","UploadOutlined","className","TextArea","autoSize","Radio","Group","Space","direction","DatePicker","handleDateChange","date","dateString","disabledDate","add","showTime","inputReadOnly","showNow","DRAFT","DeleteOutlined","showRemoveFirmwareModal","DownloadOutlined","fileId","responseType","downloadFirmware","fileName","split","url","a","download","SupportMessageFieldContainer","SupportMessageModal","content","addMessage","Number","isValid","okText","rows","color","isActiveSection","_ref3","CircleDiagram","Session","ChartGroup","UserInfo","AvatarContainer","Avatar","img","Summary","Stats","StatItem","Target","_templateObject10","PictureSection","_templateObject11","withBorder","PictureContainer","_templateObject12","Picture","_templateObject13","Separator","_templateObject14","getReportColor","invalid","valid","pending","formatNumber","num","_num","absoluteValue","toPrecision","abs","round","roundNearest5","replace","formatTimeValue","formatSessionDuration","hours","minutes","seconds","getStatisticsItems","score","duration","formatTimestamp","sessionDate","_","isString","isNumber","getDate","currDate","diffInDays","diffInHours","diffInMinutes","diffInSeconds","differenceInDays","differenceInHours","differenceInMinutes","differenceInSeconds","truncateName","maxLength","getShotTime","shotTime","time","period","fullTime","getFullName","username","SessionDetails","props","session","shotLevel","shotDuration","shotSteadinessScore","shotSteadiness","shotTorque","bowLevelDegrees","aimTime","bowTorque","targetHitsStat","targetHits","stats","isOneDetail","details","Boolean","sessionPictureS3Url","profilePictureS3Url","AvatarPlaceholder","Title","containerStyles","marginLeft","createdAt","uppercase","summary","index","variant","titleStyles","marginRight","paddingTop","stat","Level","Steadiness","aimSteadinessValueDps","Torque","Duration","shoots","Shot","Logo","ShotContent","Statistic","StatisticTime","StatisticDistance","StatisticScore","_templateObject15","_templateObject16","sessionTypeToTitle","hunting","training","tournament","ShotDetails","shot","sessionType","shouldDisplayCharts","pick","configuration","publishedAt","toLocaleDateString","distance","flex","display","justifyContent","String","shotScoreTotal","backgroundColor","padding","level","shotScoreBowAngle","steadiness","shotScoreAimSteadiness","torque","shotScoreBowTorque","shotScoreAimTime","imageType","FloatGraph","radius","preShotAimGraphData","aimGraphDataPre","postShotAimGraphData","fov","marginBottom","shotPictureS3Url","STYLES","default","fontFamily","light","dark","TYPES","defaultRegular","bold","regular","SIZES","xxs","xs","sm","md","lg","xl","xxl","TitleContainer","centered","capitalize","underline","textTransform","textAlign","textDecoration","getActiveColorTorqueAndLevel","currentPercentage","currentColor","Chart","activeColor","formattedValue","translateXForIndicator","height","viewBox","ry","y","x","fill","transform","d","strokeDashR1","r1","PI","strokeDashR2","r2","strokeDashR3","r3","defaultColor","getActiveColorSteadiness","centerColor","r1Color","r2Color","r3Color","cx","cy","r","stroke","strokeWidth","strokeDasharray","strokeDashoffset","y1","x1","y2","x2","isNil","showFirstSegment","showSecondSegment","showThirdSegment","getActiveColorDuration","SmallTarget","maxRadius","FloatGraphComponent","resultRadius","diameter","preShotAimGraphDataPoints","postShotAimGraphDataPoints","preShotAimGraphDataCurvedLine","line","curve","curveBasis","postShotAimGraphDataCurvedLine","circles","circlesStep","id","clipPath","Row","RowValue","TargetStats","TargetChart","TargetRow","unit","targetRowStyles","overall","result","curr","floor","getAverageScore","keys","marginTop","Comment","CommentDetails","comment","flexShrink","ICONS","xmlns","IconComponent","SearchForm","SearchFormInputContainer","parseISODateFormat","dateFormat","BOW_COLUMNS","ellipsis","CheckBowPage","tableDevices","setTableDevices","modifiedDevices","device","_device$deviceUser","productSerialNumber","deviceUser","WARNING","handleRowClick","MainPageContainer","MainPage","getCurrentUser","from","Redirect","Spin","Form","ButtonGroup","CheckboxContainer","ROLES","label","support_user","checkRolePermission","permissibleRoles","currentUserRole","AddUserPage","isNewUserLoading","setIsNewUserLoading","newUser","addUser","onBack","Select","Option","handleCheckboxChange","initialContextState","socket","SocketContext","React","createContext","useSocketContext","useContext","SocketProvider","setSocket","io","transports","on","err","opts","console","disconnect","Provider","FirmwareRelease","release","TABLE_DATA","uploaded","activatedDate","author","uploadedBy","FirmwareTesting","testing","NewUserButton","USER_COLUMNS","UsersPage","tableUsers","setTableUsers","modifiedUsers","_ROLES$find","find","PlusCircleOutlined","TableActionRow","TableAction","render","renderStatusTag","Active","Tag","Disabled","Created","Deleted","BowUsersPage","application_user","lastShot","generateActions","subLabel","obj","onCell","Typography","Link","SESSIONS_COLUMNS","commentsCount","Tooltip","SHOTS_COLUMNS","ADVANCED_SHOTS_COLUMN","BowUserSessionsPage","useParams","tableSessions","_session$stats","_session$stats2","_session$stats3","_session$stats4","_session$stats5","_session$stats6","_session$shots","sessionName","comments","likes","isShotDetected","maxWidth","handleRemoveSession","expandable","expandedRowRender","SessionsPage","setTableSessions","i","modifiedSessions","FormActions","EditUserPage","updateUser","enableReinitialize","showChangePasswordModal","dirty","showRemoveUserModal","Img","handleActivateUserAccount","res","activateUserAccount","_currentLocation$stat","prevLocation","useLastSearchState","handleChangeUserStatus","HeaderDateForm","DatePickersContainer","ShotTableContainer","ExportButtonContainer","SHOT_COLUMNS","EVENT_COLUMNS","modifyKeyToString","BowDetailsPage","Panel","Collapse","tableShots","setTableShots","tableEvents","setTableEvents","modifiedShots","_shot$location","_shot$location2","shotNumber","deviceMode","gpsLocation","lat","lon","shotQuality","registered","shotScore","modifiedEvents","eventType","isStartDate","defaultActiveKey","ghost","header","ExportOutlined","downloadDeviceData","TypeRow","LogActions","LogSelect","LogAction","getLogColor","warning","debug","info","ACTIVITY_LOG_COLUMNS","ActivityLogPage","interval","setInterval","clearInterval","tableLogs","maxHeight","defaultValue","options","showRemoveUserLogsModal","deleteUserLogs","ExActivityLogPage","DataRow","LOG_COLUMNS","LogDetailsPage","deviceBrand","deviceModel","deviceSystemName","deviceSystemVersion","minHeight","ExLogDetailsPage","COMMENTS_COLUMNS","SessionCommentsPage","tableComments","setTableComments","modifiedComments","updatedAt","handleRemoveComment","SessionsCommunityPage","GROUPS_COLUMNS","UserGroupsPage","tableGroups","setTableGroups","modifiedGroups","ownerName","ownerEmail","members","forEach","member","isGroupOwner","membersCount","UserGroupPage","updateGroup","groupPictureS3Url","showRemoveGroupModal","MESSAGES_COLUMNS","SupportMessagesPage","tableMessages","setTableMessages","modifiedMessages","authorEmail","authorUsername","UserShotsPage","userMetadata","NewBowButton","BowsPage","tableBows","setTableBows","modifiedBows","drawLength","FormValuesContainer","FormRow","FormTags","FormInput","FormSelect","FormRange","FormAddButton","getFieldName","arr","AddBowPage","inputDrawWeight","inputLetOff","toNumber","minLength","range","addBowValue","property","val","sort","b","removeBowValue","difference","accept","closable","onClose","FormImg","EditBowPage","bowPictureS3Url","showRemoveBowModal","ReportSelect","ReportAction","REPORT_TITLES","harassment_or_bullying","commercial_content_or_spam","hate_speech","offensive_language","personal_information","harmful_or_dangerous","offensive_imagery","copyright_violation","pornography","violent_or_repulsive","other","REPORT_TYPES","picture_session","picture_shot","REPORT_STATUSES","REPORT_COLUMNS","category","ReportsPage","tableReports","handleOpenUser","accusedId","reporterId","ReportDetails","StatusRow","ReportLink","ReportActions","_ref4","_ref5","MobileContainer","MobileView","REPORT_BUTTONS","ReportPage","tableRows","buttons","showChangeStatusModal","showHeader","isLastComment","isReportedComment","reportedShotCommentId","reportedSessionCommentId","margin","borderBottom","border","useStatistics","statistics","setStatistics","isStatisticsLoading","setIsStatisticsLoading","fetchStatistics","getUserStatistics","useUserDeviceStatistics","getUserDeviceStatistics","defaultModalState","defaultDeviceStatistics","iOS","Android","Unknown","__","first_name","last_name","onFilter","isActive","isActiveUser","hasShots","expandedRowColumns","StatisticsPage","modalState","setModalState","searchInputRef","useRef","deviceStatistics","categorizedUsers","_user$deviceInfo","_user$deviceInfo$devi","deviceInfo","categorizeUsersByDevice","appVersionStatistics","Set","_user$deviceInfo2","appVersion","_user$deviceInfo3","hasOwnProperty","unknown","categorizeUsersByAppVersion","defaultExpandedRowKeys","handleDeviceCardClick","handleModalCancel","setValue","filteredData","isUndefined","renderTooltipIcon","QuestionCircleOutlined","right","spinning","tip","gutter","Col","Card","appUserCount","activeUsersCount","notActiveUsersCount","userWithShotsCount","userWithoutShotsCount","cursor","iosCount","androidCount","unknownCount","handleAppVersionCardClick","hidden","Search","ref","onSearch","handleSearch","rowExpandable","rowKey","scroll","GroupRequestsPage","PUBLIC_GROUPS_STATUSES","accepted","rejected","getPublicGroupColor","PUBLIC_GROUPS_COLUMNS","isNew","PublicGroupsPage","tablePublicGroups","PublicGroupDetails","PublicGroupActions","PublicGroupAction","GroupImg","GroupName","RadioTitle","PublicGroupPage","rejectModal","setRejectModal","moderationDate","showApproveModal","imageUrl","lineHeight","optionType","COLUMNS","eventCountByStatus","created","_renderStatusTag","finished","_renderStatusTag2","_renderStatusTag3","count","minWidth","EventsPage","setLoading","fetchGroupsWithEvents","filteredGroups","getGroupsWithEvents","statusTitleMap","getStatusTitle","GroupEventsPage","_group$name","filteredEvents","initialize","fetchGroupEvents","getGroupEvents","leaderboard","_leaderboard$totalSco","totalScore","defaultSortOrder","_a$leaderboard$totalS","_a$leaderboard","_b$leaderboard$totalS","_b$leaderboard","_record$shots$length","_record$shots","_a$shots$length","_a$shots","_b$shots$length","_b$shots","_leaderboard$averageS","averageScore","_a$leaderboard$averag","_a$leaderboard2","_b$leaderboard$averag","_b$leaderboard2","EXPANDED_ROW_COLUMNS","ordinalNumber","GroupEventPage","_event$name","setEvent","eventId","filteredUsers","fetchEvent","fetchEventUsers","getEventById","getEventUsers","showRemoveEventModal","deleteEvent","UserDeviceStatisticsPage","categorizedDevices","_device$deviceSystemN","UNKNOWN_VERSION_KEY","categorizedDevicesByAppVersion","u","ROUTES","DEFAULT","component","NOT_GUARDED","GUARDED","EditBowUserPage","MainRoutes","handleMenuButtonClick","MenuOutlined","Switch","route","GuardedRoute","exact","NotGuardedRoute","Route","getRoute","routeProps","App","BrowserRouter","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.5a54422d.chunk.js","sourcesContent":["const SIZE = {\n tablet: '768px',\n tabletLarge: '992px',\n desktop: '1200px'\n};\n\nexport const DEVICE = {\n tablet: `(max-width: ${SIZE.tablet})`,\n tabletLarge: `(max-width: ${SIZE.tabletLarge})`,\n desktop: `(max-width: ${SIZE.desktop})`\n};\n","import { DEVICE } from 'shared/constants/deviceSizes';\nimport styled from 'styled-components';\n\nexport const RootContainer = styled.div<{ isAuth: boolean }>`\n display: flex;\n flex-direction: column;\n width: 100%;\n min-height: 100vh;\n padding-left: ${({ isAuth }): string => (isAuth ? '256px' : '0')};\n @media ${DEVICE.tabletLarge} {\n padding-left: 0;\n }\n`;\n\nexport const MenuButton = styled.button`\n width: 30px;\n position: absolute;\n top: 20px;\n left: 15px;\n display: none;\n\n @media ${DEVICE.tabletLarge} {\n display: block;\n }\n`;\n","import { ReactNode } from 'react';\n\nexport enum ERouteType {\n GUARDED = 'GUARDED',\n NOT_GUARDED = 'NOT_GUARDED',\n DEFAULT = 'DEFAULT'\n}\n\nexport type RouteItem = {\n type: ERouteType;\n path: string;\n component: () => JSX.Element;\n};\n\nexport type User = {\n email: string;\n id: number;\n username: string;\n firstName: string;\n lastName: string;\n birthday: string;\n role: EUserRole;\n status: EUserStatus;\n createdAt: string;\n updatedAt: string;\n token: string;\n profilePictureS3Url: string | null;\n totalShots: number;\n isGroupOwner?: boolean;\n lastShot: string;\n};\n\nexport type SupportMessage = {\n id: number;\n userId: number;\n content: string;\n authorId: number;\n createdAt: string;\n author: User;\n};\n\nexport type PostedShot = {\n id: string;\n shotId: string;\n userId: number;\n isShotDetected: boolean;\n isDryFire: boolean;\n isDerail: boolean;\n shotIndex: number;\n shotScoreTotal: number;\n shotScoreAimSteadiness: number;\n shotScoreBowAngle: number;\n shotScoreAimTime: number;\n shotScoreBowTorque: number;\n bowTorque: number;\n aimSteadinessValueDps: number;\n releaseTime: number;\n aimTime: number;\n setUpTime: number;\n vibrationEnergy: number;\n bowInclineDegrees: number;\n bowLevelDegrees: number;\n dryFireAmplitude: number;\n derailAmplitude: number;\n aimGraphDataPre: AimGraphItem[];\n aimGraphDataPost: AimGraphItem[];\n levelGraphDataZ: number[];\n torqueResult: TorqueResult;\n targetHit: TargetHit;\n distance: number;\n timestamp: string;\n deviceId: string;\n shotPictureS3Path: string;\n shotPictureS3Url: string;\n shotPictureS3ExpireDate: string;\n endAt: string;\n publishedAt: string | null;\n sessionType: SessionType;\n configuration: ShotConfiguration;\n user: Omit;\n likes: ShotLike[];\n comments: ShotComment[];\n};\n\nexport type ShotComment = Comment & {\n postedShotId: string;\n};\n\nexport type ShotLike = Like & {\n postedShotId: string;\n};\n\nexport type ShotConfiguration = {\n duration: boolean;\n imageType: 'TARGET' | 'PHOTO';\n level: boolean;\n steadiness: boolean;\n torque: boolean;\n};\n\nexport type TorqueResult = {\n data: {\n factor: number;\n length: number;\n max: number;\n maxIndex: number;\n min: number;\n minIndex: number;\n };\n hiGScore: number;\n score: number;\n};\n\nexport type TargetHit = {\n x: number;\n y: number;\n};\n\nexport type AimGraphItem = {\n x: number;\n y: number;\n};\n\nexport type SessionType = 'training' | 'hunting' | 'tournament';\n\nexport type Session = {\n id: string;\n userId: number;\n sessionName: string;\n createdAt: string;\n isCompleted: boolean;\n details: SessionDetails;\n user: User;\n stats: SessionStats;\n shots?: SessionShot[];\n publishedAt?: string | null;\n comments: SessionComment[];\n likes: SessionLike[];\n sessionPictureS3Url?: string;\n};\n\nexport type SessionDetails = {\n stat: boolean;\n summary: boolean;\n target: boolean;\n};\n\nexport type SessionLike = Like & {\n sessionId: string;\n};\n\nexport type SessionComment = Comment & {\n sessionId: string;\n};\n\nexport type SessionStats = {\n id: string;\n sessionId: string;\n duration: {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n };\n score: number;\n shotDuration: number;\n shotSteadiness: number;\n shotSteadinessScore: number;\n bowLevelDegrees: number;\n aimTime: number;\n bowTorque: number;\n shotLevel: number;\n shotTorque: number;\n shots: number;\n userId: number;\n targetHits: TargetHit[];\n targetHitsStat: { [key: string]: { total: number; result: number; distance: string } };\n};\n\nexport type SessionShot = {\n id: string;\n userId: number;\n groupId: string;\n isShotDetected: boolean;\n isDryFire: boolean;\n isDerail: boolean;\n shotIndex: number;\n shotScoreTotal: number;\n shotScoreAimSteadiness: number;\n shotScoreBowAngle: number;\n shotScoreAimTime: number;\n shotScoreBowTorque: number;\n bowTorque: number;\n releaseTime: number;\n aimTime: number;\n setUpTime: number;\n vibrationEnergy: number;\n bowInclineDegrees: number;\n bowLevelDegrees: number;\n dryFireAmplitude: number;\n distance: number;\n timestamp: string;\n name: string;\n userMetadata?: DeviceInformation & { appVersion: string };\n};\n\nexport type Comment = {\n id: number;\n userId: number;\n content: string;\n createdAt: string;\n updatedAt: string;\n user: User;\n};\n\nexport type Like = {\n id: number;\n userId: number;\n};\n\nexport type CsvShot = {\n id: number;\n shotId: string;\n data: string;\n timestamp: string;\n};\n\nexport type UserGroup = {\n id: number;\n ownerId: number;\n name: string;\n groupPictureS3Url: string;\n members: User[];\n};\n\nexport enum EUserRole {\n support_user = 'support_user',\n admin_user = 'admin_user',\n master_admin = 'master_admin',\n application_user = 'application_user',\n moderator = 'moderator'\n}\n\nexport enum EUserStatus {\n Created = 'new',\n Active = 'active',\n Disabled = 'disabled',\n Deleted = 'deleted'\n}\n\nexport type AuthState = {\n isAuth: boolean;\n user: User | null;\n};\n\nexport enum ESnackbarStyle {\n ERROR = 'error',\n WARNING = 'warning',\n INFO = 'info',\n SUCCESS = 'success'\n}\n\nexport type SidebarState = {\n isSidebarOpened: boolean;\n};\n\nexport type ModalState = {\n isModalOpened: boolean;\n isModalDataLoading: boolean;\n modalWindow: ReactNode | null;\n};\n\nexport enum EFirmwareUpdateChannel {\n release = 'release',\n beta = 'beta',\n testing = 'testing'\n}\n\nexport enum EFirmwareStatus {\n active = 'active',\n archived = 'archived',\n scheduled = 'scheduled',\n uploaded = 'uploaded'\n}\n\nexport type FirmwareVersion = {\n id: string;\n brand: string;\n product: string;\n modelName: string;\n semver: string;\n version: string;\n channel: string;\n fileId: string;\n file: {};\n uploadedBy: string;\n createdAt: string;\n status: EFirmwareStatus;\n changelog: string;\n scheduledAt: string | null;\n};\n\nexport type FirmwareTableRow = {\n key: string;\n version: string;\n createdAt: string;\n status: string;\n activatedDate: string;\n scheduledAt: string | null;\n changelog: string;\n author: string;\n fileId: string;\n};\n\nexport type UploadedFirmware = {\n file: File;\n version: string;\n changeLog: string;\n};\n\nexport type UpdatedUser = {\n email: string;\n role: EUserRole;\n firstName: string;\n lastName: string;\n};\n\nexport type Pagination = {\n currentPage: number;\n pageSize: number;\n totalItemsCount: number;\n totalPagesCount: number;\n};\n\nexport type NewUser = {\n firstName: string;\n lastName: string;\n role: string;\n email: string;\n password: string;\n sendEmail: boolean;\n};\n\nexport enum ESortType {\n DESC = 'descend',\n ASC = 'ascend'\n}\n\nexport type Device = {\n bowDropCount: number;\n createdAt: string;\n derailCount: number;\n deviceUser: {\n createdAt: string;\n email: string;\n firstName: string | null;\n lastName: string | null;\n updatedAt: string;\n };\n dryFireCount: number;\n id: number;\n lastBowDropAt: string | null;\n lastDerailAt: string | null;\n lastDryFireAt: string | null;\n productSerialNumber: string;\n shotCount: number;\n updatedAt: string;\n userId: number;\n};\n\nexport enum EDiagramSections {\n SHOTS = 'shotCount',\n DERAIL = 'derailCount',\n DRY_FIRE = 'dryFireCount',\n BOW_DROP = 'bowDropCount'\n}\n\nexport type Shot = {\n deviceMode: string;\n deviceSerialNumber: string;\n id: number;\n location: { lat: number; lon: number };\n productSerialNumber: string;\n shotNumber: number;\n shotQuality: string;\n timestamp: string;\n userId: number;\n archived: string;\n shotScore: string;\n};\n\nexport type ShotEvent = {\n deviceSerialNumber: string;\n eventType: string;\n id: number;\n productSerialNumber: string;\n timestamp: string;\n userId: number;\n};\n\ntype DateRange = {\n start: string | null;\n end: string | null;\n};\n\nexport type RequestParams = {\n dateRange: DateRange;\n currentPage: number;\n};\n\nexport type LogType = 'warning' | 'error' | 'debug' | 'info';\n\nexport type Log = DeviceInformation & {\n id: number;\n type: LogType;\n timestamp: string;\n data: string;\n title: string;\n user: User;\n username?: string;\n};\n\nexport type DeviceInformation = {\n deviceBrand: string;\n deviceModel: string;\n deviceSystemName: string;\n deviceSystemVersion: string;\n};\n\nexport type Bow = {\n id: number;\n bowPictureS3Path: string;\n bowPictureS3Url: string;\n bowPictureS3ExpireDate: string;\n bowPictureId: string;\n modelName: string;\n drawWeight: number[];\n drawLength: number[];\n letOff: number[];\n 'lr/hr': string[];\n timestamp: string;\n};\n\nexport type ImageReportType =\n | 'harmful_or_dangerous'\n | 'offensive_imagery'\n | 'commercial_content_or_spam'\n | 'copyright_violation'\n | 'pornography'\n | 'violent_or_repulsive'\n | 'other';\n\nexport type CommentReportType =\n | 'harassment_or_bullying'\n | 'commercial_content_or_spam'\n | 'hate_speech'\n | 'offensive_language'\n | 'personal_information'\n | 'other';\n\nexport type ReportCategory = ImageReportType | CommentReportType;\n\nexport type ReportObjectType = 'picture_session' | 'picture_shot' | 'session' | 'shot';\n\nexport type ReportStatus = 'pending' | 'valid' | 'invalid';\n\nexport type Report = {\n id: number;\n accusedId: number;\n reportObjectType: ReportObjectType;\n parentId: string;\n reportedObjectId: string;\n category: ReportCategory;\n status: ReportStatus;\n reporterId: number;\n createdAt: string;\n updatedAt: string;\n reportedPictureS3Path: string | null;\n reportedSessionCommentId: number | null;\n reportedShotCommentId: number | null;\n description?: string;\n};\n\nexport type PublicGroupStatus = 'rejected' | 'accepted' | 'pending';\n\nexport type PublicGroup = {\n id: number;\n groupId: number;\n isNew: boolean;\n name: string;\n status: PublicGroupStatus;\n imageUrl: string | null;\n pictureId: string | null;\n picturePath: string | null;\n moderationDate: string;\n};\n\nexport interface DebouncedFunc any> {\n (...args: Parameters): ReturnType | undefined;\n cancel(): void;\n flush(): ReturnType | undefined;\n}\n\n// Statistics\nexport interface Statistics {\n users: StatisticsUser[];\n statistics: AppUsersStatistics;\n}\n\nexport interface UserInfo {\n id: number;\n username: any;\n email: string;\n first_name: string;\n last_name: string;\n status: string;\n total_shots: number;\n isActiveUser: boolean;\n hasShots: boolean;\n}\n\nexport interface StatisticsUser extends UserInfo {\n deviceInfo?: DeviceInfo;\n}\n\nexport interface DeviceInfo {\n appVersion: string;\n deviceBrand: string;\n deviceModel: string;\n deviceSystemName: string;\n deviceSystemVersion: string;\n}\n\nexport interface AppUsersStatistics {\n appUserCount: number;\n activeUsersCount: number;\n notActiveUsersCount: number;\n userWithShotsCount: number;\n userWithoutShotsCount: number;\n iosCount: number;\n androidCount: number;\n unknownCount: number;\n}\n\nexport interface UserDeviceStatistics {\n users: UserDeviceStatisticsUser[];\n statistics: AppUsersStatistics;\n}\n\nexport interface UserDeviceInfo extends DeviceInfo {\n id: number;\n userId: number;\n uniqueDeviceId: string;\n}\n\nexport interface UserDeviceStatisticsUser extends UserInfo {\n devices: UserDeviceInfo[];\n}\n\nexport interface EventGroup extends Omit {\n eventCountByStatus: Record;\n}\n\nexport type EventStatus = 'created' | 'finished' | 'active';\n\nexport interface Event {\n id: number;\n name: string;\n startDate: number;\n endDate: number;\n shotsPerDay: number;\n description: string;\n status: EventStatus;\n groupId: number;\n createdAt: string;\n updatedAt: string;\n ownerId?: number;\n eventPictureS3Path?: string;\n eventPictureS3ExpireDate?: string;\n eventPictureS3Url?: string;\n}\n\nexport interface EventShot {\n id: number;\n shotId: string;\n timestamp: number;\n score: number;\n ordinalNumber: number;\n}\n\nexport interface EventUser extends Omit {\n leaderboard: { averageScore: number; totalScore: number };\n shots: EventShot[];\n}\n","import styled from 'styled-components';\n\nexport const LoginPageContainer = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n`;\n\nexport const LoginForm = styled.form`\n position: relative;\n max-width: 328px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nexport const LoginFormTitle = styled.div`\n line-height: 44px;\n color: rgba(0, 0, 0, 0.85);\n font-weight: 600;\n font-size: 33px;\n text-align: center;\n margin-bottom: 24px;\n`;\n\nexport const LoginFormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n","import * as Yup from 'yup';\n\nexport const validation = {\n LOG_IN: Yup.object().shape({\n email: Yup.string().email('Please enter a valid e-mail address').required('Required field'),\n password: Yup.string()\n .min(8, 'Use 8 or more characters')\n .max(50, 'Only 50 symbols allowed')\n .required('Required field')\n }),\n ADD_USER: Yup.object().shape({\n firstName: Yup.string().required('Required field'),\n lastName: Yup.string().required('Required field'),\n role: Yup.string().required('Required field'),\n email: Yup.string().email('Please enter a valid e-mail address').required('Required field'),\n password: Yup.string()\n .min(8, 'Use 8 or more characters')\n .max(50, 'Only 50 symbols allowed')\n .required('Required field'),\n confirmPassword: Yup.string()\n .min(8, 'Use 8 or more characters')\n .max(50, 'Only 50 symbols allowed')\n .oneOf([Yup.ref('password')], 'Passwords must match')\n .required('Passwords must match')\n }),\n CREATE_BOW: Yup.object().shape({\n image: Yup.mixed().required('Required field'),\n modelName: Yup.string().required('Required field'),\n drawLengthFrom: Yup.string().required('Required field'),\n drawLengthTo: Yup.string().required('Required field'),\n drawWeight: Yup.array().of(Yup.number()).min(1, 'Min 1 value required').required('Required field'),\n letOff: Yup.array().of(Yup.number()).min(1, 'Min 1 value required').required('Required field'),\n 'lr/hr': Yup.array().of(Yup.string()).min(1, 'Min 1 value required').required('Required field'),\n }),\n EDIT_BOW: Yup.object().shape({\n modelName: Yup.string().required('Required field'),\n drawLengthFrom: Yup.string().required('Required field'),\n drawLengthTo: Yup.string().required('Required field'),\n drawWeight: Yup.array().of(Yup.number()).min(1, 'Min 1 value required').required('Required field'),\n letOff: Yup.array().of(Yup.number()).min(1, 'Min 1 value required').required('Required field'),\n 'lr/hr': Yup.array().of(Yup.string()).min(1, 'Min 1 value required').required('Required field'),\n }),\n EDIT_USER: Yup.object().shape({\n firstName: Yup.string().required('Required field'),\n lastName: Yup.string().required('Required field'),\n role: Yup.string().required('Required field'),\n email: Yup.string().email('Please enter a valid e-mail address').required('Required field')\n }),\n EDIT_GROUP: Yup.object().shape({\n name: Yup.string().required('Required field')\n }),\n CHANGE_PASSWORD: Yup.object().shape({\n updatedPassword: Yup.string()\n .min(8, 'Use 8 or more characters')\n .max(50, 'Only 50 symbols allowed')\n .required('The password is too short'),\n confirmPassword: Yup.string()\n .min(8, 'Use 8 or more characters')\n .max(50, 'Only 50 symbols allowed')\n .oneOf([Yup.ref('updatedPassword')], 'Passwords must match')\n .required('Passwords must match')\n }),\n UPLOAD_FIRMWARE: Yup.object().shape({\n version: Yup.string()\n .trim()\n .required('Required field')\n .test('version', 'Invalid format, use: x.x.x', (value): boolean =>\n value ? /\\d\\.\\d\\.\\d/.test(value) : false\n )\n }),\n ADD_SUPPORT_MESSAGE: Yup.object().shape({\n message: Yup.string().trim().required('Required field')\n }),\n CHECK_A_BOW: Yup.object().shape({\n searchValue: Yup.string().trim().required('Required field')\n })\n};\n","import { createAction, createReducer } from '@reduxjs/toolkit';\nimport { User, AuthState } from 'shared/types';\n\nconst initialState: AuthState = {\n isAuth: false,\n user: null\n};\n\n// Actions\n\nexport const loginUserSuccess = createAction('auth/loginUserSuccess');\nexport const loginUserFail = createAction('auth/loginUserFail');\nexport const logoutUser = createAction('auth/logout');\n\n// Reducer\n\nexport const authReducer = createReducer(initialState, (builder): void => {\n builder\n .addCase(\n loginUserSuccess,\n (state, action): AuthState => ({\n ...state,\n isAuth: true,\n user: action.payload\n })\n )\n .addCase(\n loginUserFail,\n (state): AuthState => ({\n ...state,\n isAuth: false,\n user: null\n })\n )\n\n .addCase(logoutUser, (state): AuthState => {\n localStorage.removeItem('token');\n return {\n ...state,\n isAuth: false,\n user: null\n };\n });\n});\n","import { createAction, createReducer } from '@reduxjs/toolkit';\nimport { SidebarState } from 'shared/types';\n\n// Actions\n\nexport const openSidebar = createAction('sidebar/openSidebar');\nexport const closeSidebar = createAction('sidebar/closeSidebar');\n\nconst initialState: SidebarState = {\n isSidebarOpened: false\n};\n\n// Reducer\n\nexport const sidebarReducer = createReducer(initialState, (builder): void => {\n builder\n .addCase(openSidebar, (): SidebarState => {\n return { isSidebarOpened: true };\n })\n .addCase(closeSidebar, (): SidebarState => {\n return { isSidebarOpened: false };\n });\n});\n","import { ReactNode } from 'react';\nimport { createAction, createReducer } from '@reduxjs/toolkit';\nimport { ModalState } from 'shared/types';\n\n// Actions\n\nexport const showModal = createAction('modal/showModal');\nexport const closeModal = createAction('modal/closeModal');\nexport const setIsDataLoadingParameter = createAction('modal/setIsDataLoadingParameter');\n\nconst initialState: ModalState = {\n isModalOpened: false,\n isModalDataLoading: false,\n modalWindow: null\n};\n\n// Reducer\n\nexport const modalReducer = createReducer(initialState, (builder): void => {\n builder\n .addCase(showModal, (state, action): ModalState => {\n return { ...state, isModalOpened: true, modalWindow: action.payload };\n })\n .addCase(setIsDataLoadingParameter, (state, action): ModalState => {\n return { ...state, isModalDataLoading: action.payload };\n })\n .addCase(closeModal, (state): ModalState => {\n return { ...state, isModalOpened: false, modalWindow: null };\n });\n});\n","import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';\nimport { authReducer, modalReducer, sidebarReducer } from './reducers';\n\nexport const store = configureStore({\n reducer: {\n auth: authReducer,\n sidebar: sidebarReducer,\n modal: modalReducer\n },\n middleware: [\n ...getDefaultMiddleware({\n serializableCheck: false\n })\n ]\n});\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof store.dispatch;\n","import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios';\nimport { store } from 'services/store';\nimport { logoutUser } from 'services/store/reducers/authReducer';\n\nclass ApiService {\n private instance: AxiosInstance;\n\n constructor(v: string = 'v1') {\n this.instance = axios.create({\n baseURL: `${process.env.REACT_APP_API_URL}/api/${v}`\n });\n\n this.instance.interceptors.request.use(\n (config): AxiosRequestConfig => {\n if (!config.headers.Authorization) {\n const token = localStorage.getItem('token');\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error): Promise => {\n return Promise.reject(error);\n }\n );\n\n this.instance.interceptors.response.use(\n (response): AxiosResponse => {\n return response;\n },\n async (error): Promise | Error> => {\n if (error.response) {\n if (error.response.status === 401 && error.config && !error.config.__isRetryRequest) {\n store.dispatch(logoutUser());\n }\n return Promise.reject(error.response.data);\n } else if (error.request) {\n return Promise.reject(new Error('Network error'));\n }\n return Promise.reject(error);\n }\n );\n }\n\n public get(path: string, config?: AxiosRequestConfig): Promise> {\n return this.instance.get(path, config);\n }\n\n public post(path: string, data: T, config?: AxiosRequestConfig): Promise> {\n return this.instance.post(path, data, config);\n }\n\n public put(path: string, data: T): Promise>> {\n return this.instance.put(path, data);\n }\n\n public patch(path: string, data: T): Promise> {\n return this.instance.patch(path, data);\n }\n\n public delete(path: string): Promise> {\n return this.instance.delete(path);\n }\n}\n\nconst apiService = new ApiService()\nexport default apiService;\nexport const ApiServiceV2 = new ApiService('v2')\n","import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';\nimport type { RootState, AppDispatch } from 'services/store';\n\nexport const useAppDispatch = (): AppDispatch => useDispatch();\nexport const useAppSelector: TypedUseSelectorHook = useSelector;\n","import { notification } from 'antd';\nimport { useCallback } from 'react';\nimport { DEFAULT_ERROR } from 'shared/constants/errors';\nimport { ESnackbarStyle } from 'shared/types';\n\ntype Result = {\n openNotification: (type: ESnackbarStyle, message: string) => void;\n};\n\nconst capitalize = (text: string): string => {\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n};\n\nconst useNotifications = (): Result => {\n const openNotification = useCallback((type: ESnackbarStyle, message: string): void => {\n notification[type]({\n message: `${capitalize(type)}!`,\n description: message || DEFAULT_ERROR\n });\n }, []);\n\n return {\n openNotification\n };\n};\n\nexport default useNotifications;\n","export const DEFAULT_ERROR: string = 'Something went wrong';\n","import { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle } from 'shared/types';\n\ntype Result = {\n copyToClipboard: (tet: string) => Promise;\n};\n\nconst useCopyToClipboard = (): Result => {\n const { openNotification } = useNotifications();\n\n const processCopyAction = (text: string): Promise => {\n if (navigator.clipboard && window.isSecureContext) {\n return navigator.clipboard.writeText(text);\n } else {\n const textArea = document.createElement('textarea');\n textArea.value = text;\n textArea.style.position = 'fixed';\n textArea.style.left = '-999999px';\n textArea.style.top = '-999999px';\n document.body.appendChild(textArea);\n textArea.focus();\n textArea.select();\n return new Promise((resolve, reject): void => {\n document.execCommand('copy') ? resolve() : reject();\n textArea.remove();\n });\n }\n };\n\n const copyToClipboard = async (text: string): Promise => {\n try {\n await processCopyAction(text);\n openNotification(ESnackbarStyle.SUCCESS, 'Successfully copied');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n };\n\n return {\n copyToClipboard\n };\n};\n\nexport default useCopyToClipboard;\n","import { useState, useEffect } from 'react';\n\nconst useDebounce = (value: string, delay: number): string => {\n const [debouncedValue, setDebouncedValue] = useState(value);\n useEffect((): (() => void) => {\n const handler = setTimeout((): void => {\n setDebouncedValue(value);\n }, delay);\n\n return (): void => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n};\n\nexport default useDebounce;\n","type Params = { [key: string]: string | number | boolean | undefined | null };\n\nexport const getSortQueryParams = (sortParams: string[]): string =>\n sortParams\n .map((item): string => (sortParams.length > 1 ? `orderBy[]=${item}` : `orderBy=${item}`))\n .join('&');\n\nexport const getQueryParams = (params: Params): string => {\n const urlParams = Object.entries(params)\n .filter((item): boolean => !!item[1])\n .map(\n (item): string =>\n encodeURIComponent(item[0]) + '=' + encodeURIComponent(item[1] as string | number | boolean)\n )\n .join('&');\n return urlParams;\n};\n","import { AxiosResponse } from 'axios';\nimport { EFirmwareStatus, EFirmwareUpdateChannel, FirmwareVersion, Pagination } from 'shared/types';\nimport { getQueryParams, getSortQueryParams } from 'utils/query-utils';\nimport ApiService from './api';\n\ntype FirmwaresResponse = {\n items: FirmwareVersion[];\n pagination: Pagination;\n};\n\ntype UpdateFirmwareRequest = {\n status?: EFirmwareStatus;\n scheduledAt?: string | null;\n changelog?: string;\n};\n\nconst getURL = (channelId: EFirmwareUpdateChannel, ...rest: string[]): string => {\n const mainUrl = `firmware/channel/${channelId}/versions`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getFirmwareVersions = async (\n page: number,\n limit: number,\n channelId: EFirmwareUpdateChannel,\n sortParams: string[],\n search: string\n): Promise> => {\n const params = getQueryParams({ page, limit, search });\n const urlSortParams = !!sortParams.length\n ? `&${getSortQueryParams(sortParams)}`\n : '&orderBy=-version';\n return await ApiService.get(`${getURL(channelId)}?${params}${urlSortParams}`);\n};\n\nexport const getFirmwareByStatus = async (\n channelId: EFirmwareUpdateChannel,\n status: EFirmwareStatus\n): Promise> => {\n const params = getQueryParams({ [status]: true });\n return await ApiService.get(`${getURL(channelId, 'latest')}?${params}`);\n};\n\nexport const addFirmwareVersion = async (\n file: FormData,\n channelId: EFirmwareUpdateChannel\n): Promise> =>\n await ApiService.post(getURL(channelId), file);\n\nexport const updateFirmwareVersion = async (\n versionId: string,\n channelId: EFirmwareUpdateChannel,\n firmware: UpdateFirmwareRequest\n): Promise> =>\n await ApiService.patch(\n getURL(channelId, versionId),\n firmware\n );\n\nexport const deleteFirmwareVersion = async (\n versionId: string,\n channelId: EFirmwareUpdateChannel\n): Promise> =>\n await ApiService.delete(getURL(channelId, versionId));\n\nexport const downloadFirmware = async (fileId: string): Promise> =>\n await ApiService.get(`firmware/files/${fileId}/download`, { responseType: 'blob' });\n","export const PAGE_SIZE: number = 10;\nexport const LOGS_PAGE_SIZE: number = 25;\n","import { useCallback, useState } from 'react';\nimport { getFirmwareByStatus, getFirmwareVersions } from 'services/api/firmwareService';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { useDebounce, useNotifications } from 'shared/hooks';\nimport {\n EFirmwareStatus,\n EFirmwareUpdateChannel,\n ESnackbarStyle,\n FirmwareVersion\n} from 'shared/types';\n\ntype Result = {\n firmwareVersions: FirmwareVersion[];\n fetchFirmwareByStatus: (status: EFirmwareStatus) => Promise;\n activeFirmware: FirmwareVersion | null;\n scheduledFirmware: FirmwareVersion | null;\n isFirmwareVersionsLoading: boolean;\n totalPages: number;\n setCurrentPage: (page: number) => void;\n currentPage: number;\n totalFirmwares: number;\n fetchFirmwareVersions: () => Promise;\n setSortParams: (values: string[]) => void;\n searchValue: string;\n setSearchValue: (value: string) => void;\n};\n\nconst useFirmwareVersions = (channelId: EFirmwareUpdateChannel): Result => {\n const [firmwareVersions, setFirmwareVersions] = useState([]);\n const [activeFirmware, setActiveFirmware] = useState(null);\n const [scheduledFirmware, setScheduledFirmware] = useState(null);\n const [isFirmwareVersionsLoading, setIsFirmwareVersionsLoading] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [totalFirmwares, setTotalFirmwares] = useState(0);\n const [sortParams, setSortParams] = useState([]);\n const [searchValue, setSearchValue] = useState('');\n\n const debouncedSearchValue = useDebounce(searchValue, 1000);\n const { openNotification } = useNotifications();\n\n const fetchFirmwareVersions = useCallback(async (): Promise => {\n setIsFirmwareVersionsLoading(true);\n try {\n const response = await getFirmwareVersions(\n currentPage,\n PAGE_SIZE,\n channelId,\n sortParams,\n debouncedSearchValue\n );\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setFirmwareVersions(response.data.items);\n setTotalPages(totalPagesCount);\n setTotalFirmwares(totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsFirmwareVersionsLoading(false);\n }\n }, [currentPage, channelId, sortParams, debouncedSearchValue, openNotification]);\n\n const fetchFirmwareByStatus = useCallback(\n async (status: EFirmwareStatus): Promise => {\n try {\n const response = await getFirmwareByStatus(channelId, status);\n const version = !!response.data.semver ? response.data : null;\n status === EFirmwareStatus.active\n ? setActiveFirmware(version)\n : setScheduledFirmware(version);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n [channelId, openNotification]\n );\n\n return {\n firmwareVersions,\n fetchFirmwareByStatus,\n activeFirmware,\n scheduledFirmware,\n isFirmwareVersionsLoading,\n fetchFirmwareVersions,\n totalPages,\n currentPage,\n setCurrentPage,\n totalFirmwares,\n setSortParams,\n searchValue,\n setSearchValue\n };\n};\n\nexport default useFirmwareVersions;\n","import { AxiosResponse } from 'axios';\nimport ApiService from './api';\nimport { UpdatedUser, Pagination, User, NewUser } from 'shared/types';\nimport { getQueryParams, getSortQueryParams } from 'utils/query-utils';\n\ntype ChangeUserPasswordRequest = {\n updatedPassword: string;\n confirmPassword: string;\n sendEmail: boolean;\n};\n\ntype UsersResponse = {\n items: User[];\n pagination: Pagination;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `users`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const updateUser = async (userId: string, user: UpdatedUser): Promise> =>\n await ApiService.patch(getURL(userId), user);\n\nexport const updateBowUser = async (\n userId: string,\n formData: FormData\n): Promise> => await ApiService.patch(getURL(userId), formData);\n\nexport const changeUserPassword = async (\n userId: string,\n passwords: ChangeUserPasswordRequest\n): Promise> =>\n await ApiService.post(getURL(userId, 'changePassword'), {\n ...passwords\n });\n\nexport const getUser = async (userId: string): Promise> =>\n await ApiService.get(getURL(userId));\n\nexport const getUsers = async (\n page: number,\n limit: number,\n sortParams: string[],\n search: string,\n showAll: boolean = false\n): Promise> => {\n const params = getQueryParams({ page, limit, search, showAll });\n const urlSortParams = !!sortParams.length\n ? `&${getSortQueryParams(sortParams)}`\n : '&orderBy=-createdAt&withDisabled=true';\n return await ApiService.get(`/users?${params}${urlSortParams}`);\n};\n\nexport const addUser = async (newUser: NewUser): Promise> =>\n await ApiService.post(getURL('register'), newUser);\n\nexport const deleteUser = async (userId: string): Promise> =>\n await ApiService.delete(getURL(userId));\n\nexport const activateUserAccount = async (userId: string): Promise> =>\n await ApiService.patch(getURL('confirm', userId), undefined);\n","import { Dispatch, SetStateAction, useCallback, useState } from 'react';\nimport { deleteUser, getUser } from 'services/api/usersService';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, User } from 'shared/types';\n\ntype Result = {\n user: User | null;\n setUser: Dispatch>;\n isUserLoading: boolean;\n fetchUser: (userId: string) => Promise;\n removeUser: (userId: string) => Promise;\n};\n\nconst useUser = (): Result => {\n const [user, setUser] = useState(null);\n const [isUserLoading, setIsUserLoading] = useState(true);\n\n const { openNotification } = useNotifications();\n\n const fetchUser = useCallback(\n async (userId: string): Promise => {\n setIsUserLoading(true);\n try {\n const response = await getUser(userId);\n setUser(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsUserLoading(false);\n }\n },\n [openNotification]\n );\n\n const removeUser = async (userId: string): Promise => {\n setIsUserLoading(true);\n try {\n await deleteUser(userId);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsUserLoading(false);\n }\n };\n\n return {\n user,\n setUser,\n isUserLoading,\n fetchUser,\n removeUser\n };\n};\n\nexport default useUser;\n","import { useCallback, useState } from 'react';\nimport { ESnackbarStyle, Pagination, User } from 'shared/types';\nimport { getUsers } from 'services/api/usersService';\nimport { useNotifications, useDebounce } from 'shared/hooks';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\n\ntype Result = {\n users: User[];\n isUsersLoading: boolean;\n searchValue: string;\n pagination: Pagination;\n onChangePagination: (currentPage: number, pageSize?: number) => void;\n fetchUsers: (showAll?: boolean) => Promise;\n setSortParams: (values: string[]) => void;\n setSearchValue: (value: string) => void;\n};\n\nconst useUsers = (): Result => {\n const [users, setUsers] = useState([]);\n const [isUsersLoading, setIsUsersLoading] = useState(true);\n const [sortParams, setSortParams] = useState([]);\n const [searchValue, setSearchValue] = useState('');\n const [pagination, setPagination] = useState({\n currentPage: 1,\n pageSize: PAGE_SIZE,\n totalPagesCount: 0,\n totalItemsCount: 0\n });\n\n const debouncedSearchValue = useDebounce(searchValue, 1000);\n const { openNotification } = useNotifications();\n\n const fetchUsers = useCallback(\n async (showAll?: boolean): Promise => {\n setIsUsersLoading(true);\n try {\n const response = await getUsers(\n pagination.currentPage,\n pagination.pageSize,\n sortParams,\n debouncedSearchValue,\n showAll\n );\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setUsers(response.data.items);\n setPagination((prevState) => ({ ...prevState, totalPagesCount, totalItemsCount }));\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsUsersLoading(false);\n }\n },\n [\n pagination.currentPage,\n pagination.pageSize,\n openNotification,\n sortParams,\n debouncedSearchValue\n ]\n );\n\n const onChangePagination = (\n currentPage: number,\n pageSize: number | undefined = PAGE_SIZE\n ): void => {\n setPagination((prevState) => ({ ...prevState, currentPage, pageSize }));\n };\n\n return {\n users,\n pagination,\n isUsersLoading,\n searchValue,\n fetchUsers,\n setSortParams,\n setSearchValue,\n onChangePagination\n };\n};\n\nexport default useUsers;\n","import { AxiosResponse } from 'axios';\nimport { Device, Pagination, Shot, ShotEvent } from 'shared/types';\nimport { getQueryParams, getSortQueryParams } from 'utils/query-utils';\nimport ApiService from './api';\n\ntype DevicesResponse = {\n items: Device[];\n pagination: Pagination;\n};\n\ntype ShotsResponse = {\n items: Shot[];\n pagination: Pagination;\n};\n\ntype EventsResponse = {\n items: ShotEvent[];\n pagination: Pagination;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `users/all/bows`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getDevices = async (\n page: number,\n limit: number,\n sortParams: string[]\n): Promise> => {\n const params = getQueryParams({ page, limit });\n const urlSortParams = !!sortParams.length\n ? `&${getSortQueryParams(sortParams)}`\n : '&orderBy=-createdAt';\n return await ApiService.get(`${getURL()}?${params}${urlSortParams}`);\n};\n\nexport const getDeviceBySerialNumber = async (\n serialNumber: string\n): Promise> => await ApiService.get(getURL(serialNumber));\n\nexport const getDeviceShots = async (\n bowSerialNumber: string,\n page: number,\n limit: number,\n startDate: string | null,\n endDate: string | null,\n sortParams: string[]\n): Promise> => {\n const params = getQueryParams({ page, limit });\n const dateRange =\n !!startDate && !!endDate ? `&timeRange.from=${startDate}&timeRange.to=${endDate}` : '';\n const urlSortParams = !!sortParams.length\n ? `&${getSortQueryParams(sortParams)}`\n : '&orderBy=-timestamp';\n return await ApiService.get(\n `${getURL(bowSerialNumber, 'shots')}?${params}${dateRange}${urlSortParams}`\n );\n};\n\nexport const getDeviceEvents = async (\n bowSerialNumber: string,\n page: number,\n limit: number,\n startDate: string | null,\n endDate: string | null,\n sortParams: string[]\n): Promise> => {\n const params = getQueryParams({ page, limit });\n const dateRange =\n !!startDate && !!endDate ? `&timeRange.from=${startDate}&timeRange.to=${endDate}` : '';\n const urlSortParams = !!sortParams.length\n ? `&${getSortQueryParams(sortParams)}`\n : '&orderBy=-timestamp';\n return await ApiService.get(\n `${getURL(bowSerialNumber, 'events')}?${params}${dateRange}${urlSortParams}`\n );\n};\n\nexport const downloadDeviceData = async (bowSerialNumber: string): Promise> => {\n const params = getQueryParams({ format: 'xls' });\n return await ApiService.get(`${getURL(bowSerialNumber, 'export')}?${params}`, {\n responseType: 'blob'\n });\n};\n","import { useCallback, useState } from 'react';\nimport { getDevices } from 'services/api/devicesService';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { useNotifications } from 'shared/hooks';\nimport { Device, ESnackbarStyle } from 'shared/types';\n\ntype Result = {\n devices: Device[];\n isDevicesLoading: boolean;\n totalPages: number;\n setCurrentPage: (page: number) => void;\n currentPage: number;\n totalDevices: number;\n fetchDevices: () => Promise;\n setSortParams: (values: string[]) => void;\n};\n\nconst useDevices = (): Result => {\n const [devices, setDevices] = useState([]);\n const [isDevicesLoading, setIsDevicesLoading] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [totalDevices, setTotalDevices] = useState(0);\n const [sortParams, setSortParams] = useState([]);\n\n const { openNotification } = useNotifications();\n\n const fetchDevices = useCallback(async (): Promise => {\n setIsDevicesLoading(true);\n try {\n const response = await getDevices(currentPage, PAGE_SIZE, sortParams);\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setDevices(response.data.items);\n setTotalPages(totalPagesCount);\n setTotalDevices(totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsDevicesLoading(false);\n }\n }, [openNotification, currentPage, sortParams]);\n\n return {\n devices,\n isDevicesLoading,\n fetchDevices,\n totalPages,\n currentPage,\n setCurrentPage,\n totalDevices,\n setSortParams\n };\n};\n\nexport default useDevices;\n","import { useCallback, useState } from 'react';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, Shot, RequestParams } from 'shared/types';\nimport { getDeviceShots } from 'services/api/devicesService';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\n\ntype Result = {\n shots: Shot[];\n fetchDeviceShots: () => Promise;\n requestShotsParams: RequestParams;\n setRequestShotsParams: (requestParams: RequestParams) => void;\n totalPages: number;\n totalShots: number;\n isShotsLoading: boolean;\n setShotsSortParams: (values: string[]) => void;\n};\n\nconst useShotsData = (bowSerialNumber: string): Result => {\n const [shots, setShots] = useState([]);\n const [requestShotsParams, setRequestShotsParams] = useState({\n dateRange: { start: null, end: null },\n currentPage: 1\n });\n const [totalPages, setTotalPages] = useState(0);\n const [totalShots, setTotalShots] = useState(0);\n const [isShotsLoading, setIsShotsLoading] = useState(true);\n const [shotSortParams, setShotsSortParams] = useState([]);\n const { openNotification } = useNotifications();\n\n const fetchDeviceShots = useCallback(async (): Promise => {\n setIsShotsLoading(true);\n try {\n const { start, end } = requestShotsParams.dateRange;\n const { currentPage } = requestShotsParams;\n const response = await getDeviceShots(\n bowSerialNumber,\n currentPage,\n PAGE_SIZE,\n start,\n end,\n shotSortParams\n );\n setShots(response.data.items);\n setTotalPages(response.data.pagination.totalPagesCount);\n setTotalShots(response.data.pagination.totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsShotsLoading(false);\n }\n }, [openNotification, bowSerialNumber, requestShotsParams, shotSortParams]);\n\n return {\n shots,\n fetchDeviceShots,\n requestShotsParams,\n setRequestShotsParams,\n totalPages,\n totalShots,\n isShotsLoading,\n setShotsSortParams\n };\n};\n\nexport default useShotsData;\n","import { useCallback, useState } from 'react';\nimport { ESnackbarStyle, SessionShot } from 'shared/types';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { getCsvShot, getShots } from 'services/api/shotsService';\nimport { useNotifications } from 'shared/hooks/helper-hooks';\nimport { parseISO } from 'date-fns';\n\ntype Result = {\n shots: SessionShot[];\n fetchShots: (userId: string | number) => Promise;\n fetchCsvShot: (shotId: string | number, shotName: string) => Promise;\n totalPages: number;\n setCurrentPage: (page: number) => void;\n currentPage: number;\n totalShots: number;\n isShotsLoading: boolean;\n};\n\nconst useUserShots = (): Result => {\n const [shots, setShots] = useState([]);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [totalShots, setTotalShots] = useState(0);\n const [isShotsLoading, setIsShotsLoading] = useState(true);\n\n const { openNotification } = useNotifications();\n\n const fetchShots = useCallback(async (userId: string | number): Promise => {\n setIsShotsLoading(true);\n try {\n const response = await getShots(currentPage, PAGE_SIZE, userId);\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setShots(response.data.items);\n setTotalPages(totalPagesCount);\n setTotalShots(totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsShotsLoading(false);\n }\n }, [currentPage, openNotification]);\n\n const fetchCsvShot = useCallback(async (shotId: string | number, shotName: string): Promise => {\n try {\n const {data: {data, timestamp}} = await getCsvShot(shotId);\n const link = document.createElement('a');\n link.href = window.URL.createObjectURL(new Blob([data]))\n link.setAttribute('download', `csv_shot_${shotName}_${parseISO(timestamp).getTime()}.csv`);\n document.body.appendChild(link);\n link.click();\n link.remove();\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }, [openNotification])\n\n return {\n shots,\n totalPages,\n totalShots,\n isShotsLoading,\n currentPage,\n setCurrentPage,\n fetchShots,\n fetchCsvShot,\n }\n}\n\nexport default useUserShots;\n","import { AxiosResponse } from 'axios';\nimport { getQueryParams } from 'utils/query-utils';\nimport { ApiServiceV2 } from './api';\nimport { CsvShot, Pagination, SessionShot } from 'shared/types';\n\ntype ShotsResponse = {\n items: SessionShot[];\n pagination: Pagination\n}\n\nexport const getShots = async (\n page: number,\n limit: number,\n userId: string | number,\n): Promise> => {\n const params = getQueryParams({ page, limit, userId });\n return await ApiServiceV2.get(`/shots?${params}`);\n};\n\nexport const getCsvShot = async (shotId: string | number):Promise> => {\n return await ApiServiceV2.get(`/shots-csv/${shotId}`);\n}\n","import { useCallback, useState } from 'react';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, RequestParams, ShotEvent } from 'shared/types';\nimport { getDeviceEvents } from 'services/api/devicesService';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\n\ntype Result = {\n events: ShotEvent[];\n fetchDeviceEvents: () => Promise;\n requestEventsParams: RequestParams;\n setRequestEventsParams: (requestParams: RequestParams) => void;\n totalPages: number;\n totalEvents: number;\n isEventsLoading: boolean;\n setEventsSortParams: (values: string[]) => void;\n};\n\nconst useEventsData = (bowSerialNumber: string): Result => {\n const [events, setEvents] = useState([]);\n const [requestEventsParams, setRequestEventsParams] = useState({\n dateRange: { start: null, end: null },\n currentPage: 1\n });\n const [totalPages, setTotalPages] = useState(0);\n const [totalEvents, setTotalEvents] = useState(0);\n const [isEventsLoading, setIsEventsLoading] = useState(true);\n const [eventsSortParams, setEventsSortParams] = useState([]);\n const { openNotification } = useNotifications();\n\n const fetchDeviceEvents = useCallback(async (): Promise => {\n setIsEventsLoading(true);\n try {\n const { start, end } = requestEventsParams.dateRange;\n const { currentPage } = requestEventsParams;\n const response = await getDeviceEvents(\n bowSerialNumber,\n currentPage,\n PAGE_SIZE,\n start,\n end,\n eventsSortParams\n );\n setEvents(response.data.items);\n setTotalPages(response.data.pagination.totalPagesCount);\n setTotalEvents(response.data.pagination.totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsEventsLoading(false);\n }\n }, [openNotification, bowSerialNumber, requestEventsParams, eventsSortParams]);\n\n return {\n events,\n fetchDeviceEvents,\n requestEventsParams,\n setRequestEventsParams,\n totalPages,\n totalEvents,\n isEventsLoading,\n setEventsSortParams\n };\n};\n\nexport default useEventsData;\n","import { getQueryParams } from 'utils/query-utils';\nimport ApiService from './api';\nimport { Log, LogType, Pagination } from 'shared/types';\nimport { AxiosResponse } from 'axios';\n\ntype GetLogsParams = {\n page: number;\n limit: number;\n userId: string | number;\n search: string;\n type?: LogType;\n qwpnr?: string;\n};\n\nexport type LogsResponse = {\n items: Log[];\n pagination: Pagination;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `logs`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getLogs = async (\n query: Partial,\n logsType: string\n): Promise> => {\n const params = getQueryParams(query);\n return await ApiService.get(`${logsType}${getURL()}?${params}`);\n};\n\nexport const getLogById = async (logId: string, logType: string): Promise> => {\n return await ApiService.get(`${logType}${getURL(logId)}?qwpnr=nSdjySDdtb`);\n};\n\nexport const deleteLogs = async (): Promise> =>\n await ApiService.delete(getURL());\n\nexport const deleteUserLogs = async (userId: string): Promise> =>\n await ApiService.delete(getURL(userId));\n","import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react';\nimport { LOGS_PAGE_SIZE } from 'shared/constants/pagination';\nimport { DebouncedFunc, ESnackbarStyle, Log, LogType, Pagination } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { getLogs, LogsResponse } from 'services/api/logService';\nimport debounce from 'lodash.debounce';\n\ntype Params = {\n userId?: string | number;\n logsType?: string;\n};\n\ntype Result = {\n items: Log[];\n pagination: Pagination;\n isLogsLoading: boolean;\n currentPage: number;\n inputSearch: string;\n type: LogType | undefined;\n setInputSearch: Dispatch>;\n setCurrentPage: Dispatch>;\n fetchLogs: (useLoader?: boolean) => Promise;\n handleChangeSearch: DebouncedFunc<(data: string) => void>;\n isAutoUpdate: boolean;\n setIsAutoUpdate: Dispatch>;\n setType: Dispatch>;\n};\n\nconst initialLogs: LogsResponse = {\n items: [],\n pagination: {\n totalItemsCount: 0,\n totalPagesCount: 0,\n currentPage: 1,\n pageSize: LOGS_PAGE_SIZE\n }\n};\n\nconst useLogs = ({ userId, logsType = '' }: Params): Result => {\n const [logs, setLogs] = useState(initialLogs);\n const [isLogsLoading, setIsLogsLoading] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const [search, setSearch] = useState('');\n const [inputSearch, setInputSearch] = useState('');\n const [type, setType] = useState(undefined);\n const [isAutoUpdate, setIsAutoUpdate] = useState(false);\n\n const { openNotification } = useNotifications();\n\n const fetchLogs = useCallback(\n async (useLoader: boolean = true): Promise => {\n if (useLoader) {\n setIsLogsLoading(true);\n }\n try {\n const [response] = await Promise.all([\n getLogs(\n {\n page: currentPage,\n limit: LOGS_PAGE_SIZE,\n search,\n qwpnr: 'nSdjySDdtb',\n type,\n userId\n },\n logsType\n )\n ]);\n setLogs(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsLogsLoading(false);\n }\n },\n [openNotification, userId, currentPage, search, type, logsType]\n );\n\n const handleChangeSearch = useMemo(\n (): DebouncedFunc<(data: string) => void> =>\n debounce((data: string): void => {\n setSearch(data);\n setInputSearch(data);\n }, 500),\n []\n );\n\n return {\n ...logs,\n fetchLogs,\n isLogsLoading,\n currentPage,\n inputSearch,\n type,\n handleChangeSearch,\n setCurrentPage,\n setInputSearch,\n isAutoUpdate,\n setIsAutoUpdate,\n setType\n };\n};\n\nexport default useLogs;\n","import { useCallback, useState } from 'react';\nimport { ESnackbarStyle, Log } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { getLogById } from '../../../../services/api/logService';\n\ntype Result = {\n log: Log | null;\n isLogLoading: boolean;\n fetchLog: () => Promise;\n};\n\nconst useLog = (logId: string, logType = ''): Result => {\n const [log, setLog] = useState(null);\n const [isLogLoading, setIsLogLoading] = useState(true);\n const { openNotification } = useNotifications();\n\n const fetchLog = useCallback(async (): Promise => {\n setIsLogLoading(true);\n try {\n const response = await getLogById(logId, logType);\n setLog(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsLogLoading(false);\n }\n }, [openNotification, logId, logType]);\n\n return {\n log,\n isLogLoading,\n fetchLog\n };\n};\n\nexport default useLog;\n","import { AxiosResponse } from 'axios';\nimport { ApiServiceV2 } from './api';\nimport { Pagination, Session, SessionComment } from 'shared/types';\nimport { getQueryParams } from 'utils/query-utils';\n\ntype SessionsResponse = {\n items: Session[];\n pagination: Pagination;\n};\n\ntype CommentsResponse = {\n items: SessionComment[];\n pagination: Pagination;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `sessions`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getSessions = async (params: {\n page: number;\n limit: number;\n search: string;\n userId?: number;\n withoutShots: boolean;\n}): Promise> => {\n const { page, limit, search, userId, withoutShots } = params;\n const queryParams = getQueryParams({ page, limit, search, userId, withoutShots });\n return await ApiServiceV2.get(`/sessions?${queryParams}`);\n};\n\nexport const getSessionComments = async (\n sessionId: string,\n page: number,\n limit: number\n): Promise> => {\n const params = getQueryParams({ page, limit });\n return await ApiServiceV2.get(`/sessions/${sessionId}/comments?${params}`);\n};\n\nexport const deleteSessionComment = async (commentId: string): Promise> =>\n await ApiServiceV2.delete(getURL('comments', commentId));\n\nexport const deleteSession = async (sessionId: string): Promise> =>\n await ApiServiceV2.delete(getURL(sessionId));\n","import { ESnackbarStyle, Pagination, Session } from 'shared/types';\nimport { deleteSession, getSessions } from 'services/api/sessionsService';\nimport { useCallback, useState } from 'react';\nimport { useDebounce, useNotifications } from 'shared/hooks';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\n\ntype Result = {\n sessions: Session[];\n pagination: Pagination;\n searchValue: string;\n isSessionsLoading: boolean;\n fetchSessions: (params?: Partial<{ withoutShots: boolean; userId?: number }>) => Promise;\n setSearchValue: (value: string) => void;\n removeSession: (sessionId: string) => Promise;\n onChangePagination: (currentPage: number, pageSize?: number) => void;\n};\n\nconst useSessions = (): Result => {\n const [sessions, setSessions] = useState([]);\n const [isSessionsLoading, setIsSessionsLoading] = useState(true);\n const [searchValue, setSearchValue] = useState('');\n const [pagination, setPagination] = useState({\n totalItemsCount: 0,\n totalPagesCount: 0,\n currentPage: 1,\n pageSize: PAGE_SIZE\n });\n\n const debouncedSearchValue = useDebounce(searchValue, 1000);\n const { openNotification } = useNotifications();\n\n const fetchSessions = useCallback(\n async (params?: Partial<{ withoutShots?: boolean; userId?: number }>): Promise => {\n const { withoutShots = false, userId } = params ?? {};\n setIsSessionsLoading(true);\n try {\n const response = await getSessions({\n page: pagination.currentPage,\n limit: pagination.pageSize,\n search: debouncedSearchValue,\n withoutShots,\n userId\n });\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setSessions(response.data.items);\n setPagination((prevState) => ({ ...prevState, totalPagesCount, totalItemsCount }));\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsSessionsLoading(false);\n }\n },\n [pagination.currentPage, pagination.pageSize, openNotification, debouncedSearchValue]\n );\n\n const removeSession = async (sessionId: string): Promise => {\n setIsSessionsLoading(true);\n try {\n await deleteSession(sessionId);\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsSessionsLoading(false);\n }\n };\n\n const onChangePagination = (\n currentPage: number,\n pageSize: number | undefined = PAGE_SIZE\n ): void => {\n setPagination((prevState) => ({ ...prevState, currentPage, pageSize }));\n };\n\n return {\n sessions,\n pagination,\n searchValue,\n isSessionsLoading,\n fetchSessions,\n removeSession,\n setSearchValue,\n onChangePagination\n };\n};\n\nexport default useSessions;\n","import { useCallback, useState } from 'react';\nimport { deleteSessionComment, getSessionComments } from 'services/api/sessionsService';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, SessionComment } from 'shared/types';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\n\ntype Result = {\n sessionComments: SessionComment[];\n isSessionLoading: boolean;\n fetchSessionComments: (sessionId: string) => Promise;\n removeSessionComment: (commentId: string) => Promise;\n totalPages: number;\n setCurrentPage: (page: number) => void;\n currentPage: number;\n totalComments: number;\n}\n\nconst useSessionComments = (): Result => {\n const [sessionComments, setSessionComments] = useState([]);\n const [isSessionLoading, setIsSessionLoading] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [totalComments, setTotalComments] = useState(0);\n\n const { openNotification } = useNotifications();\n\n const fetchSessionComments = useCallback(\n async (sessionId: string): Promise => {\n setIsSessionLoading(true);\n try {\n const response = await getSessionComments(sessionId, currentPage, PAGE_SIZE);\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n\n setSessionComments(response.data.items);\n setTotalPages(totalPagesCount);\n setTotalComments(totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsSessionLoading(false);\n }\n },\n [openNotification, currentPage]\n );\n\n const removeSessionComment = async (commentId: string): Promise => {\n setIsSessionLoading(true);\n try {\n await deleteSessionComment(commentId);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsSessionLoading(false);\n }\n };\n\n return {\n sessionComments,\n isSessionLoading,\n fetchSessionComments,\n removeSessionComment,\n totalComments,\n totalPages,\n setCurrentPage,\n currentPage\n }\n}\n\nexport default useSessionComments;\n","import { AxiosResponse } from 'axios';\nimport ApiService from './api';\nimport { Pagination, UserGroup } from 'shared/types';\nimport {getQueryParams} from 'utils/query-utils';\n\ntype GroupsResponse = {\n items: UserGroup[];\n pagination: Pagination;\n}\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `groups`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getGroups = async (\n page: number,\n limit: number,\n search: string,\n): Promise> => {\n const params = getQueryParams({ page, limit, search });\n return await ApiService.get(`/groups?${params}`);\n}\n\nexport const getGroup = async (groupId: string): Promise> =>\n await ApiService.get(getURL(groupId));\n\nexport const updateGroup = async (groupId: string, formData: FormData): Promise> =>\n await ApiService.patch(getURL(groupId, 'admin'), formData);\n\nexport const deleteGroup = async (groupId: string): Promise> =>\n await ApiService.delete(getURL(groupId));\n","import { ESnackbarStyle, Pagination, UserGroup } from 'shared/types';\nimport { getGroups } from 'services/api/groupsService';\nimport { useCallback, useState } from 'react';\nimport { useDebounce, useNotifications } from 'shared/hooks';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\n\ntype Result = {\n groups: UserGroup[];\n isGroupsLoading: boolean;\n searchValue: string;\n pagination: Pagination;\n onChangePagination: (currentPage: number, pageSize?: number) => void;\n fetchGroups: () => Promise;\n setSearchValue: (value: string) => void;\n};\n\nconst useGroups = (): Result => {\n const [groups, setGroups] = useState([]);\n const [isGroupsLoading, setIsGroupsLoading] = useState(true);\n const [searchValue, setSearchValue] = useState('');\n const [pagination, setPagination] = useState({\n currentPage: 1,\n pageSize: PAGE_SIZE,\n totalPagesCount: 0,\n totalItemsCount: 0\n });\n\n const debouncedSearchValue = useDebounce(searchValue, 1000);\n const { openNotification } = useNotifications();\n\n const fetchGroups = useCallback(async (): Promise => {\n setIsGroupsLoading(true);\n try {\n const response = await getGroups(\n pagination.currentPage,\n pagination.pageSize,\n debouncedSearchValue\n );\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setGroups(response.data.items);\n setPagination((prevState) => ({ ...prevState, totalPagesCount, totalItemsCount }));\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsGroupsLoading(false);\n }\n }, [pagination.currentPage, pagination.pageSize, openNotification, debouncedSearchValue]);\n\n const onChangePagination = (\n currentPage: number,\n pageSize: number | undefined = PAGE_SIZE\n ): void => {\n setPagination((prevState) => ({ ...prevState, currentPage, pageSize }));\n };\n\n return {\n groups,\n isGroupsLoading,\n searchValue,\n pagination,\n onChangePagination,\n fetchGroups,\n setSearchValue\n };\n};\n\nexport default useGroups;\n","import { useCallback, useState } from 'react';\nimport {deleteGroup, getGroup } from 'services/api/groupsService';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, UserGroup } from 'shared/types';\n\ntype Result = {\n group: UserGroup | null;\n isGroupLoading: boolean;\n fetchGroup: (groupId: string) => Promise;\n removeGroup: (groupId: string) => Promise;\n};\n\nconst useGroup = (): Result => {\n const [group, setGroup] = useState(null);\n const [isGroupLoading, setIsGroupLoading] = useState(true);\n\n const { openNotification } = useNotifications();\n\n const fetchGroup = useCallback(\n async (groupId: string): Promise => {\n setIsGroupLoading(true);\n try {\n const response = await getGroup(groupId);\n setGroup(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsGroupLoading(false);\n }\n },\n [openNotification]\n );\n\n const removeGroup = async (groupId: string): Promise => {\n setIsGroupLoading(true);\n try {\n await deleteGroup(groupId);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsGroupLoading(false);\n }\n };\n\n return {\n group,\n isGroupLoading,\n fetchGroup,\n removeGroup\n }\n}\n\nexport default useGroup;\n","import { useCallback, useState } from 'react';\nimport { getMessages } from 'services/api/supportMessagesService';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, SupportMessage } from 'shared/types';\n\ntype Result = {\n messages: SupportMessage[];\n fetchMessages: (useLoader?: boolean) => Promise;\n isMessagesLoading: boolean;\n totalMessages: number;\n currentPage: number;\n totalPages: number;\n setCurrentPage: (page: number) => void;\n};\n\nconst useSupportMessages = (userId: string): Result => {\n const [messages, setMessages] = useState([]);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [totalMessages, setTotalMessages] = useState(0);\n const [isMessagesLoading, setIsMessagesLoading] = useState(true);\n\n const { openNotification } = useNotifications();\n\n const fetchMessages = useCallback(async(useLoader: boolean = true): Promise => {\n if (useLoader) {\n setIsMessagesLoading(true);\n }\n try {\n const response = await getMessages(userId, currentPage, PAGE_SIZE);\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setTotalPages(totalPagesCount);\n setTotalMessages(totalItemsCount);\n setMessages(response.data.items);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsMessagesLoading(false);\n }\n }, [currentPage, openNotification, userId]);\n\n return {\n messages,\n totalMessages,\n totalPages,\n currentPage,\n setCurrentPage,\n fetchMessages,\n isMessagesLoading\n }\n}\n\nexport default useSupportMessages;\n","import { AxiosResponse } from 'axios';\nimport ApiService from './api';\nimport { Pagination, SupportMessage } from 'shared/types';\nimport { getQueryParams } from 'utils/query-utils';\n\ntype SupportMessagesResponse = {\n items: SupportMessage[],\n pagination: Pagination;\n}\n\nexport const getMessages = async (\n userId: string,\n page: number,\n limit: number\n): Promise> => {\n const params = getQueryParams({ page, limit });\n return await ApiService.get(`/support/${userId}?${params}`);\n}\n\nexport const addMessage = async (userId: number, content: string ): Promise> =>\n await ApiService.post<{ userId: number, content: string }, SupportMessage>(`/support`, { userId, content });\n","import { AxiosResponse } from 'axios';\nimport { Bow, Pagination } from '../../shared/types';\nimport ApiService from './api';\nimport { getQueryParams } from '../../utils/query-utils';\n\ntype BowsResponse = {\n items: Bow[];\n pagination: Pagination;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `bow-models`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getBows = async (\n page: number,\n limit: number,\n): Promise> => {\n const params = getQueryParams({ page, limit });\n return await ApiService.get(`/bow-models?${params}`);\n};\n\nexport const getBow = async (bowId: string): Promise> =>\n await ApiService.get(getURL(bowId));\n\nexport const addBow = async (newBow: FormData): Promise> =>\n await ApiService.post(`/bow-models`, newBow);\n\nexport const updateBow = async (bowId: string, bow: FormData): Promise> =>\n await ApiService.patch(getURL(bowId), bow);\n\nexport const deleteBow = async (bowId: string): Promise> =>\n await ApiService.delete(getURL(bowId));\n","import { useCallback, useState } from 'react';\nimport { useNotifications } from 'shared/hooks';\nimport { Bow, ESnackbarStyle } from 'shared/types';\nimport { addBow, deleteBow, getBow, updateBow } from 'services/api/bowsService';\n\ntype Result = {\n bow: Bow | null;\n isBowLoading: boolean;\n fetchBow: (bowId: string) => Promise;\n createBow: (newBow: FormData) => Promise;\n editBow: (bowId: string, updatedBow: FormData) => Promise;\n removeBow: (bowId: string) => Promise;\n};\n\nconst useBow = (): Result => {\n const [bow, setBow] = useState(null);\n const [isBowLoading, setIsBowLoading] = useState(false);\n\n const { openNotification } = useNotifications();\n\n const fetchBow = useCallback(\n async (bowId: string): Promise => {\n setIsBowLoading(true);\n try {\n const response = await getBow(bowId);\n setBow(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsBowLoading(false);\n }\n },\n [openNotification]\n );\n\n const createBow = async (newBow: FormData): Promise => {\n setIsBowLoading(true);\n try {\n const response = await addBow(newBow);\n setBow(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsBowLoading(false);\n }\n };\n\n const editBow = async (bowId: string, updatedBow: FormData): Promise => {\n setIsBowLoading(true);\n try {\n const response = await updateBow(bowId, updatedBow);\n setBow(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsBowLoading(false);\n }\n };\n\n const removeBow = async (bowId: string): Promise => {\n setIsBowLoading(true);\n try {\n await deleteBow(bowId);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsBowLoading(false);\n }\n };\n\n return {\n bow,\n isBowLoading,\n fetchBow,\n createBow,\n editBow,\n removeBow\n };\n};\n\nexport default useBow;\n","import { useCallback, useState } from 'react';\nimport { Bow, ESnackbarStyle } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { getBows } from 'services/api/bowsService';\n\ntype Result = {\n bows: Bow[];\n fetchBows: (showAll?: boolean) => Promise;\n totalPages: number;\n setCurrentPage: (page: number) => void;\n currentPage: number;\n totalBows: number;\n isBowsLoading: boolean;\n};\n\nconst useBows = (): Result => {\n const [bows, setBows] = useState([]);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [totalBows, setTotalBows] = useState(0);\n const [isBowsLoading, setIsBowsLoading] = useState(true);\n\n const { openNotification } = useNotifications();\n\n const fetchBows = useCallback(async (): Promise => {\n setIsBowsLoading(true);\n try {\n const response = await getBows(currentPage, PAGE_SIZE);\n const { totalPagesCount, totalItemsCount } = response.data.pagination;\n setBows(response.data.items);\n setTotalPages(totalPagesCount);\n setTotalBows(totalItemsCount);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsBowsLoading(false);\n }\n }, [currentPage, openNotification]);\n\n return {\n bows,\n fetchBows,\n totalPages,\n currentPage,\n setCurrentPage,\n totalBows,\n isBowsLoading\n };\n};\n\nexport default useBows;\n","import {\n Report, Pagination, ReportStatus, ReportObjectType, Session, PostedShot,\n} from 'shared/types';\nimport { AxiosResponse } from 'axios';\nimport { getQueryParams } from 'utils/query-utils';\nimport ApiService, { ApiServiceV2 } from './api';\n\ntype GetReportsParams = {\n page: number;\n limit: number;\n search: string;\n status: string;\n};\n\nexport type ReportsResponse = {\n items: Report[];\n pagination: Pagination;\n};\n\nexport type UpdatedReport = {\n status: ReportStatus;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `reports`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getReports = async (\n query: Partial\n): Promise> => {\n const params = getQueryParams(query);\n return await ApiService.get(`${getURL()}?${params}`);\n};\n\nexport const getReportById = async (reportId: string): Promise> => {\n return await ApiService.get(getURL(reportId));\n};\n\nexport const deleteReport = async (reportId: string): Promise> =>\n await ApiService.delete(getURL(reportId));\n\nexport const updateReport = async (\n reportId: string,\n data: UpdatedReport\n): Promise> => {\n return await ApiService.patch(getURL(reportId), data);\n};\n\nexport const getReportedObject = async (\n parentId: string,\n reportType: ReportObjectType\n): Promise> => {\n return await ApiServiceV2.get(\n `${['picture_session', 'session'].includes(reportType) ? 'sessions' : 'posted-shots'}/${parentId}`\n );\n};\n","import { Dispatch, SetStateAction, useCallback, useState } from 'react';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { ESnackbarStyle, Pagination, Report } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { getReports } from 'services/api/reportsService';\n\ntype Result = {\n items: Report[];\n pagination: Pagination;\n status: string;\n isReportsLoading: boolean;\n setStatus: Dispatch>;\n fetchReports: () => Promise;\n onChangePagination: (currentPage: number, pageSize?: number) => void;\n};\n\nconst useReports = (): Result => {\n const [reports, setReports] = useState([]);\n const [isReportsLoading, setIsReportsLoading] = useState(true);\n const [status, setStatus] = useState('');\n const [pagination, setPagination] = useState({\n totalItemsCount: 0,\n totalPagesCount: 0,\n currentPage: 1,\n pageSize: PAGE_SIZE\n });\n\n const { openNotification } = useNotifications();\n\n const fetchReports = useCallback(async (): Promise => {\n setIsReportsLoading(true);\n try {\n const response = await getReports({\n page: pagination.currentPage,\n limit: pagination.pageSize,\n status\n });\n const {\n items,\n pagination: { totalItemsCount, totalPagesCount }\n } = response.data;\n setReports(items);\n setPagination((prevState) => ({ ...prevState, totalItemsCount, totalPagesCount }));\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsReportsLoading(false);\n }\n }, [pagination.currentPage, pagination.pageSize, status, openNotification]);\n\n const onChangePagination = (\n currentPage: number,\n pageSize: number | undefined = PAGE_SIZE\n ): void => {\n setPagination((prevState) => ({ ...prevState, currentPage, pageSize }));\n };\n\n return {\n status,\n pagination,\n items: reports,\n isReportsLoading,\n setStatus,\n fetchReports,\n onChangePagination\n };\n};\n\nexport default useReports;\n","import { useCallback, useState } from 'react';\nimport { useNotifications } from 'shared/hooks';\nimport {\n ESnackbarStyle,\n PostedShot,\n Report,\n ReportObjectType,\n ReportStatus,\n Session\n} from 'shared/types';\nimport {\n deleteReport,\n getReportById,\n getReportedObject,\n updateReport\n} from 'services/api/reportsService';\n\ntype Result = {\n report: Report | null;\n reportedObject: Session | PostedShot | null;\n isReportLoading: boolean;\n isReportedObjectLoading: boolean;\n fetchReport: (reportId: string, fetchReportedObject?: boolean) => Promise;\n fetchParentObject: (reportId: string, reportType: ReportObjectType) => Promise;\n removeReport: (reportId: string) => Promise;\n changeReportStatus: (reportId: string, status: ReportStatus) => Promise;\n};\n\nconst useReport = (): Result => {\n const [report, setReport] = useState(null);\n const [reportedObject, setReportedObject] = useState(null);\n const [isReportLoading, setIsReportLoading] = useState(true);\n const [isReportedObjectLoading, setIsReportedObjectLoading] = useState(false);\n\n const { openNotification } = useNotifications();\n\n const fetchParentObject = useCallback(\n async (parentId: string, reportType: ReportObjectType): Promise => {\n try {\n setIsReportedObjectLoading(true);\n const response = await getReportedObject(parentId, reportType);\n setReportedObject(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsReportedObjectLoading(false);\n }\n },\n [openNotification]\n );\n\n const fetchReport = useCallback(\n async (reportId: string, fetchReportedObject = true): Promise => {\n setIsReportLoading(true);\n try {\n const response = await getReportById(reportId);\n if (fetchReportedObject)\n await fetchParentObject(response.data.parentId, response.data.reportObjectType);\n setReport(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsReportLoading(false);\n }\n },\n [openNotification, fetchParentObject]\n );\n\n const removeReport = async (reportId: string): Promise => {\n setIsReportLoading(true);\n try {\n await deleteReport(reportId);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsReportLoading(false);\n }\n };\n\n const changeReportStatus = async (reportId: string, status: ReportStatus): Promise => {\n setIsReportLoading(true);\n try {\n await updateReport(reportId, { status });\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsReportLoading(false);\n }\n };\n\n return {\n report,\n reportedObject,\n isReportLoading,\n isReportedObjectLoading,\n fetchReport,\n fetchParentObject,\n removeReport,\n changeReportStatus\n };\n};\n\nexport default useReport;\n","import { Pagination, PublicGroup } from 'shared/types';\nimport { AxiosResponse } from 'axios';\nimport { getQueryParams } from 'utils/query-utils';\nimport ApiService from './api';\n\ntype GetPublicGroupsParams = {\n page: number;\n limit: number;\n};\n\nexport type PublicGroupsResponse = {\n items: PublicGroup[];\n pagination: Pagination;\n};\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `public-groups`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getPublicGroups = async (\n query: Partial\n): Promise> => {\n const params = getQueryParams(query);\n return await ApiService.get(`${getURL('requests')}?${params}`);\n};\n\nexport const getPublicGroupById = async (\n publicGroupId: string\n): Promise> => {\n return await ApiService.get(`${getURL('requests')}?requestId=${publicGroupId}`);\n};\n\nexport const acceptGroup = async (publicGroupId: string): Promise> => {\n return await ApiService.get(getURL(publicGroupId, 'accept'));\n};\n\nexport const rejectGroup = async (\n publicGroupId: string,\n type: 'name' | 'image'\n): Promise> => {\n return await ApiService.get(`${getURL(publicGroupId, 'reject')}?type=${type}`);\n};\n","import { useCallback, useState } from 'react';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { ESnackbarStyle, Pagination, PublicGroup } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { getPublicGroups } from 'services/api/publicGroupsService';\n\ntype Result = {\n items: PublicGroup[];\n pagination: Pagination;\n isPublicGroupsLoading: boolean;\n fetchPublicGroups: () => Promise;\n onChangePagination: (currentPage: number, pageSize?: number) => void;\n};\n\nconst usePublicGroups = (): Result => {\n const [publicGroups, setPublicGroups] = useState([]);\n const [isPublicGroupsLoading, setIsPublicGroupsLoading] = useState(true);\n const [pagination, setPagination] = useState({\n totalItemsCount: 0,\n totalPagesCount: 0,\n currentPage: 1,\n pageSize: PAGE_SIZE\n });\n\n const { openNotification } = useNotifications();\n\n const fetchPublicGroups = useCallback(async (): Promise => {\n setIsPublicGroupsLoading(true);\n try {\n const response = await getPublicGroups({\n page: pagination.currentPage,\n limit: pagination.pageSize\n });\n const {\n items,\n pagination: { totalItemsCount, totalPagesCount }\n } = response.data;\n setPublicGroups(items);\n setPagination((prevState) => ({ ...prevState, totalItemsCount, totalPagesCount }));\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsPublicGroupsLoading(false);\n }\n }, [pagination.currentPage, pagination.pageSize, openNotification]);\n\n const onChangePagination = (\n currentPage: number,\n pageSize: number | undefined = PAGE_SIZE\n ): void => {\n setPagination((prevState) => ({ ...prevState, currentPage, pageSize }));\n };\n\n return {\n items: publicGroups,\n pagination,\n isPublicGroupsLoading,\n fetchPublicGroups,\n onChangePagination\n };\n};\n\nexport default usePublicGroups;\n","import { useCallback, useState } from 'react';\nimport { useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, PublicGroup } from 'shared/types';\nimport { acceptGroup, rejectGroup, getPublicGroupById } from 'services/api/publicGroupsService';\n\ntype Result = {\n publicGroup: PublicGroup | null;\n isPublicGroupLoading: boolean;\n fetchPublicGroup: (publicGroupId: string) => Promise;\n acceptPublicGroup: (publicGroupId: string) => Promise;\n rejectPublicGroup: (publicGroupId: string, type: 'name' | 'image') => Promise;\n};\n\nconst usePublicGroup = (): Result => {\n const [publicGroup, setPublicGroup] = useState(null);\n const [isPublicGroupLoading, setIsPublicGroupLoading] = useState(true);\n\n const { openNotification } = useNotifications();\n\n const fetchPublicGroup = useCallback(\n async (publicGroupId: string): Promise => {\n setIsPublicGroupLoading(true);\n try {\n const response = await getPublicGroupById(`${publicGroupId}`);\n if (response.data.length) {\n setPublicGroup(response.data[0]);\n }\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsPublicGroupLoading(false);\n }\n },\n [openNotification]\n );\n\n const acceptPublicGroup = async (publicGroupId: string): Promise => {\n setIsPublicGroupLoading(true);\n try {\n const response = await acceptGroup(`${publicGroupId}`);\n setPublicGroup(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsPublicGroupLoading(false);\n }\n };\n\n const rejectPublicGroup = async (publicGroupId: string, type: 'name' | 'image'): Promise => {\n setIsPublicGroupLoading(true);\n try {\n const response = await rejectGroup(`${publicGroupId}`, type);\n setPublicGroup(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsPublicGroupLoading(false);\n }\n };\n\n return {\n publicGroup,\n isPublicGroupLoading,\n fetchPublicGroup,\n acceptPublicGroup,\n rejectPublicGroup\n };\n};\n\nexport default usePublicGroup;\n","import styled from 'styled-components';\n\nexport const ErrorMessage = styled.div`\n margin-top: 3px;\n color: #de3618;\n font-size: 12px;\n`;\n\nexport const PaginationContainer = styled.div`\n margin-top: 30px;\n display: flex;\n justify-content: center;\n`;\n","import { FormikContextType } from 'formik';\nimport { ErrorMessage } from 'shared/styles';\n\nexport const getFieldError = (formik: FormikContextType, fieldName: string): JSX.Element => {\n const meta = formik.getFieldMeta(fieldName);\n const errorText = meta.touched && meta.error ? meta.error : '';\n return !!errorText ? {errorText} :
;\n};\n","import React from 'react';\nimport * as Styled from './styles';\nimport { Button, Input } from 'antd';\nimport { useFormik } from 'formik';\nimport { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';\nimport { validation } from 'services/validation';\nimport { login } from 'services/api/authService';\nimport { useAppDispatch, useNotifications } from 'shared/hooks';\nimport { loginUserFail, loginUserSuccess } from 'services/store/reducers/authReducer';\nimport { ESnackbarStyle } from 'shared/types';\nimport { getFieldError } from 'utils/error-utils';\n\ntype FormValues = {\n email: string;\n password: string;\n};\n\nconst LoginPage = (): JSX.Element => {\n const initialValues: FormValues = {\n email: '',\n password: ''\n };\n\n const dispatch = useAppDispatch();\n const { openNotification } = useNotifications();\n\n const formik = useFormik({\n initialValues,\n onSubmit: async (values): Promise => {\n try {\n const response = await login(values.email, values.password);\n localStorage.setItem('token', response.data.token);\n dispatch(loginUserSuccess(response.data));\n } catch (e) {\n dispatch(loginUserFail());\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n validationSchema: validation.LOG_IN\n });\n\n return (\n \n \n Please login\n \n \n {getFieldError(formik, 'email')}\n \n \n \n visible ? : \n }\n disabled={formik.isSubmitting}\n />\n {getFieldError(formik, 'password')}\n \n \n Login\n \n \n \n );\n};\n\nexport default LoginPage;\n","import { AxiosResponse } from 'axios';\nimport { User } from 'shared/types';\nimport ApiService from './api';\n\ntype LoginRequest = {\n email: string;\n password: string;\n};\n\ntype LoginResponse = User & {\n token: string;\n};\n\nexport const login = async (\n email: string,\n password: string\n): Promise> =>\n await ApiService.post(\n '/auth/login?isAdmin=true',\n { email, password },\n { headers: { Authorization: `Bearer ${process.env.REACT_APP_API_KEY}` } }\n );\n\nexport const getCurrentUser = async (): Promise> =>\n await ApiService.get('auth/me');\n","import styled from 'styled-components';\n\nexport const NotFoundPageContainer = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n`;\n","import { Result, Button } from 'antd';\nimport { useHistory } from 'react-router';\nimport { NotFoundPageContainer } from './styles';\n\nconst NotFoundPage = (): JSX.Element => {\n const history = useHistory();\n\n const navigateBack = (): void => {\n history.goBack();\n };\n\n return (\n \n \n Back\n \n }\n />\n \n );\n};\n\nexport default NotFoundPage;\n","import {\n FileDoneOutlined,\n IssuesCloseOutlined,\n CodepenOutlined,\n UserOutlined,\n StockOutlined,\n TeamOutlined,\n GlobalOutlined,\n ShoppingOutlined,\n AuditOutlined,\n PieChartOutlined,\n BarChartOutlined,\n ShareAltOutlined\n} from '@ant-design/icons';\nimport { ElementType } from 'react';\nimport { EUserRole } from 'shared/types';\n\ntype SidebarItem = {\n title: string;\n link: string;\n icon: ElementType;\n roles: EUserRole[];\n subItems?: SidebarItem[];\n};\n\nexport const SIDEBAR_ITEMS: SidebarItem[] = [\n {\n title: 'Firmware',\n link: '/firmware',\n icon: CodepenOutlined,\n subItems: [\n {\n title: 'Release',\n link: '/firmware/release',\n icon: FileDoneOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'Testing',\n link: '/firmware/testing',\n icon: IssuesCloseOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n }\n ],\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'Users',\n link: '/users',\n icon: UserOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin, EUserRole.moderator]\n },\n {\n title: 'Bow Users',\n link: '/bow-users',\n icon: TeamOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin, EUserRole.moderator]\n },\n {\n title: 'Bows',\n link: '/bows',\n icon: ShoppingOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'User Groups',\n link: '/groups',\n icon: GlobalOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'External Activity log',\n link: '/ex-activity-log',\n icon: StockOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'Reports',\n link: '/reports',\n icon: AuditOutlined,\n roles: [EUserRole.moderator, EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'Statistics',\n link: '/statistics',\n icon: PieChartOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'User Device Statistics',\n link: '/user-device-statistics',\n icon: PieChartOutlined,\n roles: [EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'Public Groups',\n link: '/public-groups',\n icon: ShareAltOutlined,\n roles: [EUserRole.moderator, EUserRole.admin_user, EUserRole.master_admin]\n },\n {\n title: 'Group Events',\n link: '/group-events',\n icon: BarChartOutlined,\n roles: [EUserRole.moderator, EUserRole.admin_user, EUserRole.master_admin]\n }\n];\n","import styled from 'styled-components';\nimport { DEVICE } from 'shared/constants/deviceSizes';\n\nexport const SidebarContainer = styled.div<{ isSidebarOpened: boolean }>`\n width: 256px;\n top: 0;\n left: 0;\n height: 100vh;\n overflow-x: hidden;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n position: fixed;\n z-index: 999;\n border-right: 1px solid #f0f0f0;\n background: #fff;\n transition: all 0.3s;\n\n @media ${DEVICE.tabletLarge} {\n transform: ${({ isSidebarOpened }): string =>\n isSidebarOpened ? 'translateX(0%)' : 'translateX(-100%)'};\n }\n\n @media ${DEVICE.tablet} {\n width: 100%;\n }\n`;\n\nexport const CloseButton = styled.button`\n position: absolute;\n right: 10px;\n top: 10px;\n display: none;\n\n @media ${DEVICE.tablet} {\n display: block;\n }\n`;\n\nexport const SidebarContent = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nexport const SidebarLogo = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 20px;\n\n img {\n width: 170px;\n }\n`;\n\nexport const SidebarItems = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nexport const SidebarFooter = styled.div`\n display: flex;\n flex-direction: column;\n padding: 0 16px 40px 24px;\n`;\n\nexport const SidebarUserInfo = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nexport const SidebarUserActions = styled.div`\n margin-top: 10px;\n display: flex;\n justify-content: flex-end;\n`;\n\nexport const Overlay = styled.div<{ isSidebarOpened: boolean }>`\n display: none;\n z-index: 2;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n overflow: auto;\n background: rgba(0, 0, 0, 0.4);\n @media (max-width: 992px) {\n display: ${({ isSidebarOpened }): string => (isSidebarOpened ? 'flex' : 'none')};\n }\n`;\n","export default __webpack_public_path__ + \"static/media/logo.dc56b18d.svg\";","import React from 'react';\nimport { useAppDispatch, useAppSelector } from 'shared/hooks';\nimport { SIDEBAR_ITEMS } from './constants';\nimport * as Styled from './styles';\nimport { Button, Menu } from 'antd';\nimport { useLocation } from 'react-router';\nimport { NavLink, useHistory } from 'react-router-dom';\nimport LogoIcon from 'assets/images/logo.svg';\nimport { logoutUser } from 'services/store/reducers/authReducer';\nimport { closeSidebar } from 'services/store/reducers/sidebarReducer';\nimport { CloseOutlined } from '@ant-design/icons';\nimport { User } from 'shared/types';\n\nconst Sidebar = (): JSX.Element => {\n const isSidebarOpened = useAppSelector((state): boolean => state.sidebar.isSidebarOpened);\n const user = useAppSelector((state): User | null => state.auth.user);\n const location = useLocation();\n const dispatch = useAppDispatch();\n const history = useHistory();\n\n const logOut = (): void => {\n dispatch(logoutUser());\n };\n\n const allowedSidebarItems = SIDEBAR_ITEMS.filter((role): boolean =>\n role.roles.some((permissibleRole): boolean => permissibleRole === user?.role)\n );\n\n const handleMenuItemClick = (subItemLink: string): void => {\n dispatch(closeSidebar());\n history.push(`${subItemLink}`);\n };\n\n const handleCloseButtonClick = (): void => {\n dispatch(closeSidebar());\n };\n\n return (\n <>\n \n \n \n \n \n \n \n Logo\n \n \n \n \n {allowedSidebarItems.map(({ title, icon: Icon, link, subItems }): JSX.Element => {\n return subItems ? (\n } title={title}>\n {subItems.map(\n ({\n title: subItemTitle,\n icon: SubItemIcon,\n link: subItemLink\n }): JSX.Element => {\n return (\n }\n onClick={(): void => handleMenuItemClick(subItemLink)}\n >\n {subItemTitle}\n \n );\n }\n )}\n \n ) : (\n }\n onClick={(): void => handleMenuItemClick(link)}\n >\n {title}\n \n );\n })}\n \n \n \n \n \n
Logged in as
\n
{user?.email}
\n
\n \n \n \n
\n
\n \n \n );\n};\n\nexport default Sidebar;\n","import { DEVICE } from 'shared/constants/deviceSizes';\nimport styled from 'styled-components';\n\nexport const Container = styled.div`\n display: flex;\n flex: 1;\n margin: 0 auto;\n width: 100%;\n max-width: 1250px;\n padding: 15px 15px 30px 15px;\n min-height: 100vh;\n\n @media ${DEVICE.tabletLarge} {\n padding-top: 50px;\n }\n`;\n","import React, { CSSProperties, ReactNode } from 'react';\nimport { Container } from './styles';\n\ntype Props = {\n children: ReactNode;\n containerStyle?: CSSProperties\n};\n\nconst ContentContainer: React.FC = ({ children, containerStyle }): JSX.Element => {\n return {children};\n};\n\nexport default ContentContainer;\n","import styled from 'styled-components';\nimport { DEVICE } from 'shared/constants/deviceSizes';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n padding-bottom: 50px;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const VersionsGroup = styled.div`\n margin-top: 30px;\n font-weight: bold;\n`;\n\nexport const ScheduledVersion = styled.div`\n margin-top: 10px;\n\n & span:last-child {\n margin-left: 30px;\n }\n`;\n\nexport const SearchInput = styled.div`\n margin: 30px 0 0 auto;\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 20px;\n width: 100%;\n overflow: auto;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & tbody tr td:last-child {\n width: 35%;\n\n @media ${DEVICE.tablet} {\n width: 25%;\n }\n }\n`;","import {\n FilterValue,\n TablePaginationConfig,\n ColumnType,\n SortOrder,\n Key\n} from 'antd/lib/table/interface';\nimport { ESortType } from 'shared/types';\n\ntype SorterResult = {\n column?: ColumnType & {\n sortKey?: string;\n };\n order?: SortOrder;\n field?: Key | readonly Key[];\n columnKey?: Key;\n};\n\nconst getSortByValue = (field: string, order: string): string => {\n return order === ESortType.ASC ? field : `-${field}`;\n};\n\nexport const handleSortAction =\n (\n setSortParams: (value: string[]) => void\n ): ((\n pagination: TablePaginationConfig,\n filters: Record,\n sorter: SorterResult | SorterResult[]\n ) => Promise) =>\n async (pagination, filters, sorter): Promise => {\n let sortParams: string[];\n if (Array.isArray(sorter)) {\n sortParams = sorter.reduce((acc: string[], item): string[] => {\n const { column, order } = item;\n if (!!column && !!order) {\n const sortByValue = getSortByValue(column.sortKey as string, order as string);\n return [...acc, sortByValue];\n } else {\n return acc;\n }\n }, []);\n } else {\n const { column, order } = sorter;\n sortParams =\n !!column && !!order ? [getSortByValue(column.sortKey as string, order as string)] : [];\n }\n setSortParams(sortParams);\n };\n","export const FIRMWARE_COLUMNS = [\n {\n title: 'Version',\n dataIndex: 'version',\n key: 'version',\n sortKey: 'version',\n sorter: { multiple: 1 }\n },\n {\n title: 'Upload date',\n dataIndex: 'createdAt',\n key: 'createdAt',\n sortKey: 'createdAt',\n sorter: { multiple: 1 }\n },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n sortKey: 'status',\n sorter: { multiple: 1 }\n },\n {\n title: 'Author',\n dataIndex: 'author',\n key: 'author',\n sortKey: 'uploadedBy',\n sorter: { multiple: 1 }\n },\n {\n title: 'Log description',\n dataIndex: 'changelog',\n key: 'changelog',\n sortKey: 'changelog',\n sorter: { multiple: 1 }\n }\n];\n","import React from 'react';\nimport { ContentContainer, FirmwareActionsModal } from 'shared/components';\nimport { Button, PageHeader, Table, Pagination, Input } from 'antd';\nimport * as Styled from './styles';\nimport { useAppDispatch, useNotifications } from 'shared/hooks';\nimport { showModal } from 'services/store/reducers/modalReducer';\nimport {\n EFirmwareUpdateChannel,\n ESnackbarStyle,\n FirmwareTableRow,\n FirmwareVersion\n} from 'shared/types';\nimport { useFormik } from 'formik';\nimport { validation } from 'services/validation';\nimport { PaginationContainer } from 'shared/styles';\nimport { addFirmwareVersion } from 'services/api/firmwareService';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { RcFile } from 'antd/lib/upload';\nimport { handleSortAction } from 'utils/sorting-utils';\nimport { FIRMWARE_COLUMNS } from './constants';\nimport moment from 'moment';\n\ntype FormValues = {\n file: RcFile | null;\n version: string;\n changelog: string;\n};\n\ntype RowAction = {\n onClick: () => void;\n};\n\ntype Props = {\n firmwareUpdateChannel: EFirmwareUpdateChannel;\n fetchFirmwareData: () => Promise;\n data: FirmwareTableRow[];\n activeFirmware: FirmwareVersion | null;\n scheduledFirmware: FirmwareVersion | null;\n isDataLoading: boolean;\n setCurrentPage: (page: number) => void;\n currentPage: number;\n totalFirmwares: number;\n setSortParams: (value: string[]) => void;\n searchValue: string;\n setSearchValue: (value: string) => void;\n};\n\nconst FirmwareList: React.FC = ({\n firmwareUpdateChannel,\n fetchFirmwareData,\n data,\n activeFirmware,\n scheduledFirmware,\n isDataLoading,\n setCurrentPage,\n totalFirmwares,\n currentPage,\n setSortParams,\n searchValue,\n setSearchValue\n}): JSX.Element => {\n const dispatch = useAppDispatch();\n const { openNotification } = useNotifications();\n\n const handleSearchInputChange = (event: React.ChangeEvent): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const showFirmwareActionsModal = (record?: FirmwareTableRow): void => {\n dispatch(\n showModal(\n \n )\n );\n };\n\n const initialValues: FormValues = {\n file: null,\n version: '',\n changelog: ''\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise => {\n formik.setSubmitting(true);\n try {\n const formData = new FormData();\n formData.append('file', values.file!);\n formData.append('version', values.version);\n formData.append('changelog', values.changelog);\n await addFirmwareVersion(formData, firmwareUpdateChannel);\n await fetchFirmwareData();\n formik.setValues(initialValues);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n formik.setSubmitting(false);\n }\n },\n initialValues,\n validationSchema: validation.UPLOAD_FIRMWARE\n });\n\n return (\n \n \n \n showFirmwareActionsModal()}\n >\n Upload Firmware\n \n \n {!!activeFirmware &&
{`Current version: ${activeFirmware.semver}`}
}\n {!!scheduledFirmware && (\n \n {`Scheduled version: ${scheduledFirmware.semver}`}\n {moment(scheduledFirmware.scheduledAt).format('YYYY-MM-DD hh:mm:ss')}\n \n )}\n
\n \n \n \n \n ({\n onClick: (): void => showFirmwareActionsModal(record)\n })}\n />\n \n {totalFirmwares > PAGE_SIZE && (\n \n \n \n )}\n
\n
\n );\n};\n\nexport default FirmwareList;\n","import styled from 'styled-components';\n\nexport const FormInputContainer = styled.div`\n height: 68px;\n width: 100%;\n`;\n\nexport const FormCheckboxContainer = styled.div`\n margin-bottom: 24px;\n`;\n\nexport const FormInputInner = styled.div`\n display: flex;\n align-items: center;\n\n button {\n margin-left: 10px;\n }\n`;\n","import React from 'react';\nimport { Modal, Input, Checkbox, Button } from 'antd';\nimport { useAppDispatch, useAppSelector, useCopyToClipboard, useNotifications } from 'shared/hooks';\nimport { closeModal } from 'services/store/reducers/modalReducer';\nimport { ESnackbarStyle } from 'shared/types';\nimport { useFormik } from 'formik';\nimport { FormCheckboxContainer, FormInputContainer, FormInputInner } from './styles';\nimport { EyeInvisibleOutlined, EyeTwoTone, CopyOutlined } from '@ant-design/icons';\nimport { validation } from 'services/validation';\nimport { CheckboxChangeEvent } from 'antd/lib/checkbox';\nimport { changeUserPassword } from 'services/api/usersService';\nimport { getFieldError } from 'utils/error-utils';\n\ntype FormValues = {\n updatedPassword: string;\n confirmPassword: string;\n sendEmail: boolean;\n};\n\ntype Props = {\n userId: string;\n};\n\nconst ChangePasswordModal: React.FC = ({ userId }): JSX.Element => {\n const dispatch = useAppDispatch();\n const isModalOpened = useAppSelector((state): boolean => state.modal.isModalOpened);\n const { openNotification } = useNotifications();\n const { copyToClipboard } = useCopyToClipboard();\n\n const initialValues: FormValues = {\n updatedPassword: '',\n confirmPassword: '',\n sendEmail: false\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise => {\n try {\n const { confirmPassword, updatedPassword, sendEmail } = values;\n await changeUserPassword(userId, { confirmPassword, updatedPassword, sendEmail });\n openNotification(ESnackbarStyle.SUCCESS, `Password was successfully updated`);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n handleCancel();\n }\n },\n initialValues,\n validationSchema: validation.CHANGE_PASSWORD\n });\n\n const handleSubmit = (): void => {\n formik.handleSubmit();\n };\n\n const handleCancel = (): void => {\n dispatch(closeModal());\n };\n\n const handleCheckboxChange =\n (fieldName: string): ((event: CheckboxChangeEvent) => void) =>\n (event: CheckboxChangeEvent): void => {\n formik.setFieldValue(fieldName, event.target.checked);\n };\n\n const handleGeneratePasswordClick = (): void => {\n const password = Math.random().toString(36).slice(-8);\n formik.setValues({ ...formik.values, updatedPassword: password, confirmPassword: password });\n };\n\n const handleCopyButtonClick = (): void => {\n copyToClipboard(formik.values.confirmPassword);\n };\n\n return (\n \n \n \n \n visible ? : \n }\n />\n {formik.values.updatedPassword && (\n }\n />\n )}\n \n {getFieldError(formik, 'updatedPassword')}\n \n \n \n visible ? : \n }\n />\n {getFieldError(formik, 'confirmPassword')}\n \n \n \n \n \n \n Send credentials by e-mail\n \n \n \n );\n};\n\nexport default ChangePasswordModal;\n","import React from 'react';\nimport { Modal } from 'antd';\nimport { useAppDispatch, useAppSelector } from 'shared/hooks';\nimport { closeModal } from 'services/store/reducers/modalReducer';\nimport { ModalState } from 'shared/types';\n\ntype Props = {\n title: string;\n confirmAction: () => void;\n modalTitle?: string;\n};\n\nconst ConfirmModal: React.FC = ({\n title,\n confirmAction,\n modalTitle = 'Confirm'\n}): JSX.Element => {\n const dispatch = useAppDispatch();\n const { isModalOpened, isModalDataLoading } = useAppSelector((state): ModalState => state.modal);\n\n const handleCancel = (): void => {\n dispatch(closeModal());\n };\n\n return (\n \n {title}\n \n );\n};\n\nexport default ConfirmModal;\n","import { DEVICE } from 'shared/constants/deviceSizes';\nimport styled from 'styled-components';\n\nexport const UploadForm = styled.form`\n display: flex;\n flex-direction: column;\n max-width: 420px;\n width: 100%;\n`;\n\nexport const UploadFormFieldContainer = styled.div`\n height: 68px;\n\n &.textarea {\n height: auto;\n margin-bottom: 24px;\n }\n`;\n\nexport const UploadArea = styled.div`\n position: relative;\n display: flex;\n justify-content: space-between;\n width: 270px;\n margin-bottom: 24px;\n`;\n\nexport const FormatText = styled.span`\n position: absolute;\n right: 0;\n margin-top: 5px;\n color: #ccc;\n font-weight: bold;\n`;\n\nexport const RadioGroupContainer = styled.div``;\n\nexport const ScheduledButtonContainer = styled.div`\n display: flex;\n align-items: center;\n`;\n\nexport const DatePickerContainer = styled.div`\n display: flex;\n align-items: center;\n\n .ant-typography {\n margin-right: 10px;\n }\n\n .ant-picker-input > input {\n width: 150px;\n min-width: 114px;\n\n @media ${DEVICE.tablet} {\n width: 100%;\n }\n }\n`;\n\nexport const RemoveButton = styled.div`\n margin-top: 30px;\n width: max-content;\n\n & button {\n background: #f5222d;\n color: #fff;\n border-radius: 4px;\n transition: all 0.2s;\n }\n\n & button:hover {\n opacity: 0.8;\n background: #f5222d;\n color: #fff;\n border: 1px solid #fff;\n }\n`;\n\nexport const DownloadButton = styled.div`\n margin-top: 20px;\n width: max-content;\n`;\n","import React from 'react';\nimport { Modal, Input, Button, Upload, Radio, RadioChangeEvent, DatePicker } from 'antd';\nimport { useAppDispatch, useAppSelector, useNotifications } from 'shared/hooks';\nimport {\n closeModal,\n setIsDataLoadingParameter,\n showModal\n} from 'services/store/reducers/modalReducer';\nimport {\n EFirmwareStatus,\n EFirmwareUpdateChannel,\n ESnackbarStyle,\n FirmwareTableRow\n} from 'shared/types';\nimport { useFormik } from 'formik';\nimport { DeleteOutlined, UploadOutlined, DownloadOutlined } from '@ant-design/icons';\nimport { validation } from 'services/validation';\nimport * as Styled from './styles';\nimport { RcFile, UploadChangeParam } from 'antd/lib/upload';\nimport { UploadFile } from 'antd/lib/upload/interface';\nimport Space from 'antd/lib/space';\nimport moment from 'moment';\nimport {\n addFirmwareVersion,\n deleteFirmwareVersion,\n downloadFirmware,\n updateFirmwareVersion\n} from 'services/api/firmwareService';\nimport { ConfirmModal } from 'shared/components';\nimport { getFieldError } from 'utils/error-utils';\n\nenum EApplyStatus {\n ACTIVE = 'active',\n SCHEDULED = 'scheduled',\n DRAFT = 'draft'\n}\n\ntype FormValues = {\n file: RcFile | null;\n version: string;\n changelog: string;\n applyStatus: EApplyStatus;\n scheduledAt: string;\n};\n\ntype Props = {\n record?: FirmwareTableRow;\n firmwareUpdateChannel: EFirmwareUpdateChannel;\n fetchFirmwareData: () => Promise;\n};\n\nconst FirmwareActionsModal: React.FC = ({\n record,\n firmwareUpdateChannel,\n fetchFirmwareData\n}): JSX.Element => {\n const dispatch = useAppDispatch();\n const isModalOpened = useAppSelector((state): boolean => state.modal.isModalOpened);\n const { openNotification } = useNotifications();\n\n const initialValues: FormValues = {\n file: null,\n version: record?.version || '',\n changelog: record?.changelog || '',\n applyStatus: EApplyStatus.ACTIVE,\n scheduledAt: moment(record?.scheduledAt ? record.scheduledAt : new Date()).toISOString()\n };\n\n const checkIsCorrectDate = (): boolean => {\n if (formik.values.applyStatus === EApplyStatus.SCHEDULED) {\n const isDateCorrect =\n moment(formik.values.scheduledAt).toISOString() > moment(new Date()).toISOString();\n if (!isDateCorrect) {\n setFieldValue('scheduledAt', moment(new Date()).toISOString());\n openNotification(ESnackbarStyle.ERROR, 'Please, choose the correct date');\n }\n return isDateCorrect;\n }\n return true;\n };\n\n const getDataForUpdate = (values: FormValues): { [key: string]: string } => {\n const { applyStatus, scheduledAt, changelog } = values;\n switch (applyStatus) {\n case EApplyStatus.SCHEDULED: {\n return { changelog, scheduledAt, status: EFirmwareStatus.scheduled };\n }\n case EApplyStatus.ACTIVE: {\n return { changelog, status: EFirmwareStatus.active };\n }\n default:\n return {};\n }\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise => {\n const { applyStatus, scheduledAt, version, changelog, file } = values;\n if (!checkIsCorrectDate()) return;\n try {\n if (!!record) {\n if (\n record?.status === EFirmwareStatus.active ||\n record?.status === EFirmwareStatus.archived\n ) {\n await updateFirmwareVersion(record.version, firmwareUpdateChannel, { changelog });\n } else {\n const updateData = getDataForUpdate(values);\n await updateFirmwareVersion(record.version, firmwareUpdateChannel, updateData);\n }\n } else {\n const formData = new FormData();\n formData.append('file', file!);\n formData.append('version', version);\n formData.append('changelog', changelog);\n if (applyStatus === EApplyStatus.SCHEDULED) {\n formData.append('scheduledAt', scheduledAt);\n }\n await addFirmwareVersion(formData, firmwareUpdateChannel);\n if (applyStatus === EApplyStatus.ACTIVE) {\n await updateFirmwareVersion(version, firmwareUpdateChannel, {\n status: EFirmwareStatus.active\n });\n }\n }\n await fetchFirmwareData();\n openNotification(\n ESnackbarStyle.SUCCESS,\n `Firmware was successfully ${!!record ? 'updated' : 'uploaded'}`\n );\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n handleCancel();\n }\n },\n initialValues,\n validationSchema: validation.UPLOAD_FIRMWARE\n });\n\n const { values, setFieldValue, isSubmitting } = formik;\n\n const handleFileChange = (file: UploadChangeParam>): void => {\n const regexp = /\\.(zip)$/;\n if (file?.fileList[0]) {\n if (regexp.test(file.file.name)) {\n setFieldValue('file', file.fileList[0].originFileObj);\n } else {\n openNotification(ESnackbarStyle.ERROR, 'File must be in .zip format only');\n }\n } else {\n setFieldValue('file', null);\n }\n };\n\n const handleSubmit = (): void => {\n formik.handleSubmit();\n };\n\n const handleCancel = (): void => {\n dispatch(closeModal());\n };\n\n const handleRadioButtonChange = (event: RadioChangeEvent): void => {\n const { value } = event.target;\n setFieldValue('applyStatus', value);\n };\n\n const handleDateChange = (date: moment.Moment | null, dateString: string): void => {\n setFieldValue('scheduledAt', moment(dateString).toISOString());\n };\n\n const handleDownloadButtonClick = async (): Promise => {\n if (!!record) {\n try {\n const response = await downloadFirmware(record.fileId);\n const fileName =\n response.headers['content-disposition'].split('filename=')[1].slice(1, -1) ||\n 'Firmware.zip';\n const url = window.URL.createObjectURL(new Blob([response.data]));\n const a = document.createElement('a');\n a.href = url;\n a.download = fileName;\n a.click();\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }\n };\n\n const removeFirmware = async (versionId: string): Promise => {\n dispatch(setIsDataLoadingParameter(true));\n try {\n await deleteFirmwareVersion(versionId, firmwareUpdateChannel);\n await fetchFirmwareData();\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n dispatch(setIsDataLoadingParameter(false));\n dispatch(closeModal());\n }\n };\n\n const showRemoveFirmwareModal = (): void => {\n dispatch(\n showModal(\n => removeFirmware(record!.version)}\n />\n )\n );\n };\n\n return (\n \n \n {!record && (\n \n false}\n >\n \n \n Only .zip format\n \n )}\n <>\n {!record && (\n \n \n {getFieldError(formik, 'version')}\n \n )}\n \n \n \n {!(\n record?.status === EFirmwareStatus.active || record?.status === EFirmwareStatus.archived\n ) && (\n \n \n \n Activate now\n \n Scheduled on\n \n moment().add(-1, 'second') >= current}\n disabled={values.applyStatus !== EApplyStatus.SCHEDULED}\n placeholder='Scheduled date'\n showTime\n inputReadOnly\n allowClear={false}\n showNow={false}\n />\n \n \n {!record && Make it as a draft}\n \n \n \n )}\n {!!record && (\n <>\n \n }\n type='default'\n onClick={showRemoveFirmwareModal}\n disabled={isSubmitting}\n >\n Remove firmware\n \n \n \n }\n type='primary'\n onClick={handleDownloadButtonClick}\n disabled={isSubmitting}\n >\n Download firmware\n \n \n \n )}\n \n \n \n );\n};\n\nexport default FirmwareActionsModal;\n","import styled from 'styled-components';\n\nexport const SupportMessageFieldContainer = styled.div`\n height: 115px;\n\n textarea {\n height: auto;\n resize: none;\n margin-bottom: 24px;\n }\n`;","import React from 'react';\nimport { Modal, Input } from 'antd';\nimport { useAppDispatch, useAppSelector, useNotifications } from 'shared/hooks';\nimport {\n closeModal,\n} from 'services/store/reducers/modalReducer';\nimport {\n ESnackbarStyle,\n} from 'shared/types';\nimport { useFormik } from 'formik';\nimport { validation } from 'services/validation';\nimport * as Styled from './styles';\nimport { addMessage } from 'services/api/supportMessagesService';\nimport { getFieldError } from 'utils/error-utils';\n\ntype Props = {\n userId: string;\n fetchMessages: () => Promise;\n};\n\nconst SupportMessageModal: React.FC = ({\n userId,\n fetchMessages\n}): JSX.Element => {\n const dispatch = useAppDispatch();\n const isModalOpened = useAppSelector((state): boolean => state.modal.isModalOpened);\n const { openNotification } = useNotifications();\n\n const initialValues = {\n message: '',\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise => {\n const { message } = values;\n try {\n await addMessage(Number(userId), message);\n await fetchMessages();\n openNotification(\n ESnackbarStyle.SUCCESS,\n `Message was successfully sent`\n );\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n handleCancel();\n }\n },\n initialValues,\n validationSchema: validation.ADD_SUPPORT_MESSAGE\n });\n\n const { values, isSubmitting, isValid } = formik;\n\n const handleSubmit = (): void => {\n formik.handleSubmit();\n };\n\n const handleCancel = (): void => {\n dispatch(closeModal());\n };\n\n return (\n \n \n \n {getFieldError(formik, 'message')}\n \n \n );\n}\n\nexport default SupportMessageModal;\n","import styled from 'styled-components';\n\nexport const ContentContainer = styled.div`\n display: flex;\n align-items: center;\n height: 250px;\n width: 100%;\n\n @media (max-width: 530px) {\n flex-direction: column;\n height: 370px;\n }\n`;\n\nexport const DiagramContainer = styled.div`\n width: 200px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n`;\n\nexport const EventListContainer = styled.div`\n margin-left: 30px;\n width: 220px;\n\n @media (max-width: 530px) {\n margin-left: 0;\n }\n`;\n\nexport const EventColor = styled.div<{ color: string }>`\n width: 20px;\n height: 20px;\n background: ${({ color }): string => color};\n border-radius: 4px;\n`;\n\nexport const EventContainer = styled.div<{ isActiveSection: boolean }>`\n display: flex;\n justify-content: center;\n width: 220px;\n padding: 7px 0;\n transform: ${({ isActiveSection }): string => (isActiveSection ? 'scale(1.03)' : 'scale(1)')};\n border-bottom: ${({ isActiveSection }): string => (isActiveSection ? '1px solid #ccc' : '0')};\n cursor: pointer;\n`;\n\nexport const EventTitle = styled.div`\n margin: 0 20px;\n`;\n\nexport const EventTotal = styled.span`\n margin-left: auto;\n font-weight: bold;\n`;\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { EDiagramSections } from 'shared/types';\nimport * as Styled from './styles';\n\ntype DrawParams = {\n context: CanvasRenderingContext2D;\n index: number;\n currentAngle: number;\n endAngle: number;\n x: number;\n y: number;\n};\n\ntype Props = {\n shotAttempts: { [key: string]: number };\n};\n\nconst CircleDiagram: React.FC = ({ shotAttempts }): JSX.Element => {\n const COLORS = useMemo((): string[] => ['#00796a', '#659f33', '#ffa600', '#144a5c'], []);\n const [context, setContext] = useState(null);\n const canvasRef = useRef(null);\n const RADIUS: number = 80;\n const OFFSET_END: number = 5;\n const OFFSET_STEP: number = 0.5;\n const ANGLE_STEP: number = 0.05 * Math.PI;\n const CANVAS_WIDTH: number = 200;\n const CANVAS_HEIGHT: number = 200;\n const CENTER_X: number = CANVAS_WIDTH / 2;\n const CENTER_Y: number = CANVAS_HEIGHT / 2;\n const isDiagramRendered = useRef(false);\n const hoverSectionIndex = useRef(null);\n const [activeSectionIndex, setActiveSectionIndex] = useState(null);\n\n useEffect((): void => {\n if (!!canvasRef.current) {\n setContext(canvasRef.current.getContext('2d'));\n }\n }, [canvasRef]);\n\n const attempts: [string, number][] = Object.entries(shotAttempts);\n const total: number = Object.values(shotAttempts).reduce(\n (sum: number, item): number => sum + item,\n 0\n );\n\n const angles: number[] = attempts.map((item): number => {\n const onePercentOfShots = total * 0.01;\n const percent = item[1] / onePercentOfShots;\n return percent * 0.02 * Math.PI;\n });\n\n const bordersAngles: number[] = angles.reduce(\n (acc: number[], angle, index): number[] => [...acc, !!index ? acc[index - 1] + angle : angle],\n []\n );\n\n const clearCanvas = useCallback(\n (): void => context?.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT),\n [context]\n );\n\n const currentOffset = useRef(OFFSET_STEP);\n\n const getCoordinates = useCallback(\n (\n activeIndex: number,\n currentAngle: number,\n endAngle: number\n ): { x: number; y: number; labelX: number; labelY: number } => {\n const offsetValue = currentOffset.current;\n const isSingleValue = currentAngle === 0 && endAngle.toFixed(3) === (2 * Math.PI).toFixed(3);\n const isHoverSection = activeIndex === hoverSectionIndex.current && !isSingleValue;\n const medianAngle = (endAngle + currentAngle) / 2;\n const offsetX = Math.cos(medianAngle) * offsetValue;\n const offsetY = Math.sin(medianAngle) * offsetValue;\n const sectionCenter = isHoverSection ? RADIUS / 1.5 + offsetValue : RADIUS / 1.5;\n const x = isHoverSection ? CENTER_X + offsetX : CENTER_X;\n const y = isHoverSection ? CENTER_Y + offsetY : CENTER_Y;\n const labelX = isSingleValue ? CENTER_X : CENTER_X + sectionCenter * Math.cos(medianAngle);\n const labelY = isSingleValue ? CENTER_Y : CENTER_Y + sectionCenter * Math.sin(medianAngle);\n if (hoverSectionIndex.current !== null) {\n currentOffset.current =\n offsetValue < OFFSET_END ? (currentOffset.current += OFFSET_STEP) : offsetValue;\n }\n return { x, y, labelX, labelY };\n },\n [currentOffset, CENTER_X, CENTER_Y]\n );\n\n const drawDiagram = useCallback(\n ({ context, index, currentAngle, endAngle, x, y }: DrawParams): void => {\n context.beginPath();\n context.fillStyle = COLORS[index];\n context.strokeStyle = COLORS[index];\n context.moveTo(x, y);\n context.arc(x, y, RADIUS, currentAngle, endAngle);\n context.lineTo(x, y);\n context.stroke();\n context.fill();\n },\n [COLORS]\n );\n\n const renderDiagram = useCallback((): void => {\n if (!!context) {\n clearCanvas();\n angles.forEach((angle, index): void => {\n if (!angle) return;\n const currentAngle = bordersAngles[index - 1] || 0;\n const endAngle = bordersAngles[index];\n const { labelX, labelY, x, y } = getCoordinates(index, currentAngle, endAngle);\n drawDiagram({ context, index, currentAngle, endAngle, x, y });\n context.fillStyle = '#FFF';\n context.fillText(`${attempts[index][1]}`, labelX, labelY);\n context.font = 'bold 12px Arial';\n });\n }\n if (currentOffset.current < OFFSET_END && activeSectionIndex !== null) {\n requestAnimationFrame(renderDiagram);\n }\n }, [\n context,\n activeSectionIndex,\n clearCanvas,\n angles,\n bordersAngles,\n getCoordinates,\n drawDiagram,\n attempts\n ]);\n\n const renderStartDiagram = useCallback(\n (context: CanvasRenderingContext2D): void => {\n let index = 0;\n let endAngle = 0;\n let currentAngle = 0;\n const draw = (): void => {\n const nextAngle = endAngle + ANGLE_STEP;\n currentAngle = endAngle;\n endAngle = nextAngle < bordersAngles[index] ? nextAngle : bordersAngles[index];\n const { x, y } = getCoordinates(index, currentAngle, endAngle);\n currentAngle !== endAngle\n ? drawDiagram({ context, index, currentAngle, endAngle, x, y })\n : (index += 1);\n if (index <= angles.length - 1) {\n requestAnimationFrame(draw);\n } else {\n isDiagramRendered.current = true;\n renderDiagram();\n }\n };\n draw();\n },\n [ANGLE_STEP, bordersAngles, getCoordinates, drawDiagram, angles.length, renderDiagram]\n );\n\n useEffect((): void => {\n if (!!context && !isDiagramRendered.current) {\n renderStartDiagram(context);\n }\n }, [context, renderStartDiagram]);\n\n useEffect((): void => {\n if (activeSectionIndex !== null) {\n renderDiagram();\n }\n }, [activeSectionIndex, renderDiagram]);\n\n const handleMouseLeave = (): void => {\n hoverSectionIndex.current = null;\n setActiveSectionIndex(null);\n renderDiagram();\n };\n\n const handleMouseMove = (e: React.MouseEvent): void => {\n if (isDiagramRendered.current) {\n const { offsetY, offsetX } = e.nativeEvent;\n const y = CENTER_Y - offsetY;\n const x = CENTER_X - offsetX;\n const distanceFromCenter = Math.sqrt(x * x + y * y);\n const angle = Math.atan2(y, x) / Math.PI;\n const hoverAngle = (1 + angle) * Math.PI;\n\n if (distanceFromCenter <= RADIUS) {\n const index = bordersAngles.findIndex((angle): boolean => hoverAngle <= angle);\n if (hoverSectionIndex.current !== index) currentOffset.current = OFFSET_STEP;\n hoverSectionIndex.current = index;\n setActiveSectionIndex(index);\n } else {\n if (hoverSectionIndex.current !== null) handleMouseLeave();\n }\n }\n };\n\n const handleEventOnMouseMove = (index: number): void => {\n if (isDiagramRendered.current) {\n hoverSectionIndex.current = index;\n setActiveSectionIndex(index);\n renderDiagram();\n }\n };\n\n const getEventTitle = (eventKey: string): string => {\n switch (eventKey) {\n case EDiagramSections.DRY_FIRE: {\n return 'Dry fire';\n }\n case EDiagramSections.DERAIL: {\n return 'Derail';\n }\n case EDiagramSections.BOW_DROP: {\n return 'Bow drop';\n }\n default: {\n return 'Shots';\n }\n }\n };\n\n const getEventList = (): JSX.Element[] => {\n return attempts.map(\n (attempt, index): JSX.Element => (\n handleEventOnMouseMove(index)}\n onMouseLeave={handleMouseLeave}\n key={attempt[0]}\n isActiveSection={activeSectionIndex === index}\n >\n \n {getEventTitle(attempt[0])}\n {attempt[1]}\n \n )\n );\n };\n\n return (\n \n \n \n \n {getEventList()}\n \n );\n};\n\nexport default CircleDiagram;\n","import styled from 'styled-components';\n\nexport const Session = styled.div`\n position: relative;\n border-radius: 10px;\n padding-top: 26px;\n background-color: #231f20;\n`;\n\nexport const ChartGroup = styled.div`\n display: flex;\n justify-content: space-between;\n background-color: #231f20;\n padding-left: 10px;\n padding-right: 10px;\n margin-top: 15px;\n margin-bottom: 20px;\n`;\n\nexport const UserInfo = styled.div`\n position: absolute;\n top: -22px;\n left: -15px;\n display: flex;\n`;\n\nexport const AvatarContainer = styled.div`\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border-right: 5px solid #363636;\n border-bottom: 5px solid #363636;\n`;\n\nexport const Avatar = styled.img`\n width: 100%;\n height: 100%;\n border-radius: 20px;\n object-fit: cover;\n`;\n\nexport const Date = styled.div`\n position: absolute;\n top: -22px;\n right: 5px;\n`;\n\nexport const Summary = styled.div`\n margin-bottom: 6px;\n padding-left: 29px;\n padding-right: 10px;\n`;\n\nexport const Stats = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n`;\n\nexport const StatItem = styled.div`\n display: flex;\n flex-shrink: 1;\n flex-wrap: wrap;\n justify-content: center;\n`;\n\nexport const Target = styled.div`\n margin-top: 12px;\n margin-bottom: 16px;\n padding-left: 24px;\n padding-right: 9px;\n`;\n\nexport const PictureSection = styled.div<{ withBorder: boolean }>`\n padding: 11px;\n border: ${({withBorder}): string => withBorder ? '3px solid #1677FF' : 'unset'}\n`\n\nexport const PictureContainer = styled.div`\n height: 130px;\n border-radius: 6px;\n overflow: hidden;\n`;\n\nexport const Picture = styled.img`\n width: 100%;\n height: 100%;\n`;\n\nexport const Separator = styled.div`\n height: 1px;\n background-color: #363636;\n`\n","export default \"data:image/png;base64,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\"","import { ReportStatus, SessionStats } from 'shared/types';\nimport _ from 'lodash';\nimport {\n differenceInDays,\n differenceInHours,\n differenceInMinutes,\n differenceInSeconds,\n format,\n parseISO\n} from 'date-fns';\n\nexport const getReportColor = (type: ReportStatus): string =>\n ({ invalid: '#ff4d4f', valid: '#52c41a', pending: '#1677ff' }[type]);\n\nexport const formatNumber = (num?: number, absoluteValue = true): string | undefined => {\n if (num === undefined) {\n return num;\n }\n num = Number(num?.toPrecision(3));\n num = absoluteValue ? Math.abs(num) : num;\n const numFixed2 = Math.round(roundNearest5(num * 100)) / 100;\n\n return numFixed2.toString().replace(/^0./, '.');\n};\n\nexport const roundNearest5 = (num: number): number => {\n return Math.round(num / 5) * 5;\n};\n\nexport const getAverageScore = (total: number, value: number, dec: boolean = false): number => {\n const score = dec ? Math.round((value / total) * 10) / 10 : Math.floor(value / total);\n return total ? score : 0;\n};\n\nexport const formatTimeValue = (value: number = 0): number | string =>\n value < 10 ? `0${value}` : value;\n\nexport const formatSessionDuration = ({ hours, minutes, seconds }: Duration = {}): string => {\n return `${formatTimeValue(hours)}:${formatTimeValue(minutes)}:${formatTimeValue(seconds)}`;\n};\n\nexport const getStatisticsItems = ({\n score,\n shots,\n duration\n}: SessionStats): { title: string; value: string }[] => [\n { title: 'AVG. SCORE', value: `${score}%` },\n { title: 'SHOTS', value: `${shots}` },\n { title: 'DURATION', value: formatSessionDuration(duration) }\n];\n\nexport const getDate = (date?: string | number | Date | null): Date => {\n if (!date) {\n return new Date();\n }\n if (_.isString(date)) {\n return parseISO(date);\n }\n return _.isNumber(date) ? new Date(date) : date;\n};\n\nexport const formatTimestamp = (sessionDate?: string | Date | null | number): string => {\n const date = getDate(sessionDate);\n const currDate = new Date();\n\n const [diffInDays, diffInHours, diffInMinutes, diffInSeconds] = [\n differenceInDays,\n differenceInHours,\n differenceInMinutes,\n differenceInSeconds\n ].map((action): number => action(currDate, date));\n\n if (diffInDays) {\n return format(date, 'M/dd/yyyy');\n }\n if (!diffInMinutes && !diffInHours) {\n return `${diffInSeconds}s`;\n }\n if (!diffInHours) {\n return `${diffInMinutes}m`;\n }\n return `${diffInHours}h`;\n};\n\nexport const truncateName = (name: string, maxLength: number = 13): string => {\n if (name.length > maxLength) {\n return name.slice(0, maxLength) + '...';\n } else {\n return name;\n }\n};\n\nexport const getShotTime = (\n shotTime: string | Date\n): { period: string; fullTime: string; time: string } => {\n const date = _.isString(shotTime) ? parseISO(shotTime) : shotTime;\n const time = format(date, 'hh:mm:ss');\n const period = format(date, 'a');\n\n return {\n time,\n period,\n fullTime: `${time} ${period}`\n };\n};\n\nexport const getFullName = (params: {\n firstName?: string;\n lastName?: string;\n username?: string;\n}): string => {\n const {firstName = '', lastName = '', username = ''} = params;\n\n if (firstName && lastName) {\n return `${firstName} ${lastName}`;\n }\n\n if (username) {\n return username;\n }\n\n return '-';\n};\n","import React, { useMemo } from 'react';\nimport { ReportObjectType, Session } from 'shared/types';\nimport _ from 'lodash';\nimport * as Styled from './styles';\nimport { Duration, Level, Steadiness, Torque, Target, Title } from 'shared/components';\nimport AvatarPlaceholder from 'assets/images/bow-ava.png';\nimport { formatTimestamp, getStatisticsItems, truncateName } from 'utils/report-utils';\n\ntype Props = {\n session: Session;\n reportObjectType: ReportObjectType;\n};\n\nconst SessionDetails: React.FC = (props): JSX.Element => {\n const { session, reportObjectType } = props;\n\n const {\n shotLevel,\n shotDuration,\n shotSteadinessScore,\n shotSteadiness,\n shotTorque,\n bowLevelDegrees,\n aimTime,\n bowTorque,\n targetHitsStat,\n targetHits\n } = session.stats;\n\n const isOneDetail = useMemo(\n (): boolean =>\n [..._.values(session.details).filter(Boolean), !!session.sessionPictureS3Url].length === 1,\n [session.details, session.sessionPictureS3Url]\n );\n\n return (\n \n \n \n \n \n {session.user.username && (\n \n )}\n \n \n \n \n {session.details.summary && (\n \n \n {getStatisticsItems(session.stats).map(\n (item, index): JSX.Element => (\n 0 ? 20 : 0 }}\n >\n \n \n \n )\n )}\n \n \n )}\n {!isOneDetail && }\n {session.details.stat && (\n \n \n \n \n \n \n )}\n {!isOneDetail && (session.details.target || !!session.sessionPictureS3Url) && (\n \n )}\n {session.details.target && (\n \n \n \n )}\n {!isOneDetail && !!session.sessionPictureS3Url && }\n {session.sessionPictureS3Url && (\n \n \n \n \n \n )}\n \n );\n};\n\nexport default SessionDetails;\n","import styled from 'styled-components';\n\nexport const Shot = styled.div`\n position: relative;\n display: flex;\n flex-direction: column;\n`;\n\nexport const UserInfo = styled.div`\n position: absolute;\n top: -22px;\n left: -15px;\n display: flex;\n`;\n\nexport const AvatarContainer = styled.div`\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border-right: 5px solid #363636;\n border-bottom: 5px solid #363636;\n`;\n\nexport const Avatar = styled.img`\n width: 100%;\n height: 100%;\n border-radius: 20px;\n object-fit: cover;\n`;\n\nexport const Logo = styled.div`\n position: absolute;\n top: -57px;\n display: flex;\n flex-direction: column;\n align-self: center;\n align-items: center;\n justify-content: flex-end;\n padding-bottom: 10px;\n width: 86px;\n height: 86px;\n background-color: #363636;\n border-bottom-right-radius: 43px;\n border-bottom-left-radius: 43px;\n z-index: 2;\n`;\n\nexport const Date = styled.div`\n position: absolute;\n top: -22px;\n right: 5px;\n`;\n\nexport const ShotContent = styled.div<{ color: string }>`\n border-radius: 10px;\n padding: 18px 13px 0;\n background-color: ${(props): string => props.color};\n`;\n\nexport const Statistic = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const StatisticTime = styled.div`\n display: flex;\n justify-content: center;\n border: 3px solid #231f20;\n border-radius: 4px;\n width: 86px;\n height: 30px;\n`;\n\nexport const StatisticDistance = styled.div`\n margin-top: 15px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-wrap: wrap;\n flex-grow: 1;\n flex-shrink: 1;\n`;\n\nexport const StatisticScore = styled.div`\n display: flex;\n justify-content: space-between;\n border: 3px solid #231f20;\n border-radius: 4px;\n width: 86px;\n height: 30px;\n`;\n\nexport const ChartGroup = styled.div`\n display: flex;\n justify-content: space-between;\n padding: 10px 6px;\n margin-top: 10px;\n border-radius: 6px;\n background-color: #231f20;\n`;\n\nexport const Target = styled.div`\n margin-top: 15px;\n padding-top: 22px;\n padding-bottom: 10px;\n border: 1px solid #707070;\n border-radius: 6px;\n background-color: #363636;\n`;\n\nexport const PictureSection = styled.div<{ withBorder: boolean }>`\n margin: 0 -13px;\n padding: 15px 13px;\n border: ${({ withBorder }): string => (withBorder ? '3px solid #1677FF' : 'unset')};\n`;\n\nexport const PictureContainer = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 155px;\n border-radius: 6px;\n overflow: hidden;\n background-color: #363636;\n`;\n\nexport const Picture = styled.img`\n width: 100%;\n height: 320px;\n`;\n","import React, { useMemo } from 'react';\nimport { PostedShot, ReportObjectType, SessionType } from 'shared/types';\nimport { Duration, FloatGraph, Icon, Level, Steadiness, Title, Torque } from 'shared/components';\nimport * as Styled from './styles';\nimport AvatarPlaceholder from 'assets/images/bow-ava.png';\nimport { getShotTime, truncateName } from 'utils/report-utils';\nimport _ from 'lodash';\n\ntype Props = {\n shot: PostedShot;\n reportObjectType: ReportObjectType;\n};\n\nconst sessionTypeToTitle: Record = {\n hunting: 'Hunt/Event',\n training: 'Training',\n tournament: 'Hunt/Event'\n};\n\nconst ShotDetails: React.FC = (props): JSX.Element => {\n const { shot, reportObjectType } = props;\n\n const color = useMemo(\n (): string => (['hunting', 'tournament'].includes(shot.sessionType) ? '#C1B8AF' : '#707070'),\n [shot.sessionType]\n );\n\n const shouldDisplayCharts = useMemo(\n (): boolean =>\n Object.values(_.pick(shot.configuration, ['steadiness', 'duration', 'level', 'torque'])).some(\n Boolean\n ),\n [shot]\n );\n\n return (\n \n \n \n \n \n {shot.user.username && (\n \n )}\n \n \n \n \n <Icon\n name={shot.sessionType === 'training' ? 'training' : 'hunting'}\n size={31}\n color={color}\n />\n </Styled.Logo>\n <Styled.Date>\n <Title\n title={new Date(shot?.publishedAt || shot?.timestamp).toLocaleDateString('en-US')}\n uppercase={false}\n type='defaultRegular'\n size='sm'\n color='#707070'\n />\n </Styled.Date>\n <Styled.ShotContent color={color}>\n <Styled.Statistic>\n <Styled.StatisticTime>\n <Title title={getShotTime(shot.timestamp).fullTime} variant='dark' color='#231F20' />\n </Styled.StatisticTime>\n <Styled.StatisticDistance>\n <Title\n title={'DISTANCE'}\n variant='light'\n color='#231F20'\n containerStyles={{ marginRight: 10, paddingTop: 2 }}\n />\n <Title title={`${shot.distance} YDS`} type='regular' size='lg' color='#231F20' />\n </Styled.StatisticDistance>\n <Styled.StatisticScore>\n <Title\n title={'SCORE'}\n variant='dark'\n color='#231F20'\n containerStyles={{ flex: 1, display: 'flex', justifyContent: 'center' }}\n />\n <Title\n title={String(shot.shotScoreTotal)}\n type='bold'\n size={'xl'}\n color='#FFD600'\n containerStyles={{\n display: 'flex',\n backgroundColor: '#231F20',\n padding: '0 5px'\n }}\n titleStyles={{ position: 'relative', top: -2 }}\n />\n </Styled.StatisticScore>\n </Styled.Statistic>\n {shouldDisplayCharts && (\n <Styled.ChartGroup>\n {shot.configuration.level && (\n <Level value={shot.shotScoreBowAngle} bowLevelDegrees={shot.bowLevelDegrees} />\n )}\n {shot.configuration.steadiness && (\n <Steadiness\n value={shot.shotScoreAimSteadiness}\n aimSteadinessValueDps={shot.aimSteadinessValueDps}\n />\n )}\n {shot.configuration.torque && (\n <Torque value={shot.shotScoreBowTorque} bowTorque={shot.bowTorque} />\n )}\n {shot.configuration.duration && (\n <Duration value={shot.shotScoreAimTime} aimTime={shot.aimTime} />\n )}\n </Styled.ChartGroup>\n )}\n {shot.configuration.imageType === 'TARGET' ? (\n <Styled.Target>\n <FloatGraph\n radius={131}\n preShotAimGraphData={shot.aimGraphDataPre || []}\n postShotAimGraphData={[]}\n fov={10}\n containerStyles={{ marginBottom: 10 }}\n />\n </Styled.Target>\n ) : (\n <Styled.PictureSection withBorder={reportObjectType === 'picture_shot'}>\n <Styled.PictureContainer>\n <Styled.Picture src={shot.shotPictureS3Url || AvatarPlaceholder} />\n </Styled.PictureContainer>\n </Styled.PictureSection>\n )}\n </Styled.ShotContent>\n </Styled.Shot>\n );\n};\n\nexport default ShotDetails;\n","import styled, { CSSObject } from 'styled-components';\nimport { TitleProps, TitleSizes, TitleStyles, TitleTypes } from './types';\nimport _ from 'lodash';\n\nconst STYLES: TitleStyles = {\n default: {\n fontFamily: 'AvenirNextCyr Demi',\n fontSize: 16,\n color: '#FFD600'\n },\n light: {\n fontFamily: 'BebasNeue Light',\n fontSize: 18,\n color: '#FFF'\n },\n dark: {\n color: '#000',\n fontSize: 18,\n fontFamily: 'BebasNeue Regular'\n },\n text: {\n fontFamily: 'AvenirNextCyr Regular',\n fontSize: 14,\n color: '#FFF'\n },\n title: {\n fontFamily: 'BebasNeue Bold',\n fontSize: 23,\n color: '#FFF'\n }\n};\n\nconst TYPES: TitleTypes = {\n default: 'AvenirNextCyr Demi',\n defaultRegular: 'AvenirNextCyr Regular',\n bold: 'BebasNeue Bold',\n regular: 'BebasNeue Regular',\n light: 'BebasNeue Light'\n};\n\nconst SIZES: TitleSizes = {\n xxs: 12,\n xs: 14,\n sm: 15,\n md: 16,\n lg: 18,\n xl: 22,\n xxl: 23\n};\n\nexport const TitleContainer = styled.div``;\n\nexport const Title = styled.div((props: Partial<TitleProps>): CSSObject => {\n const {\n variant = 'default',\n centered = false,\n uppercase = true,\n capitalize = false,\n underline = false,\n titleStyles = {},\n size,\n color,\n type\n } = props;\n\n const styles: CSSObject = {\n ...STYLES[variant],\n ...(size && { fontSize: _.isNumber(size) ? size : SIZES[size] }),\n ...(type && { fontFamily: TYPES[type] || type }),\n ...(color && { color }),\n textTransform: uppercase ? 'uppercase' : capitalize ? 'capitalize' : 'none',\n textAlign: centered ? 'center' : 'start',\n textDecoration: underline ? 'underline' : 'none',\n ...titleStyles\n };\n return styles;\n});\n","import React from 'react';\nimport { TitleProps } from './types';\nimport * as Styled from './styles';\n\nconst Title = (props: TitleProps): JSX.Element => {\n const { containerStyles, title, ...rest } = props;\n\n return (\n <Styled.TitleContainer style={containerStyles}>\n <Styled.Title {...rest}>{title}</Styled.Title>\n </Styled.TitleContainer>\n );\n};\n\nexport default Title;\n","export const getActiveColorTorqueAndLevel = (\n currentPercentage: number | undefined,\n currentColor: string\n): string => {\n return currentPercentage === undefined\n ? currentColor\n : currentPercentage >= 12\n ? '#0BB127'\n : currentPercentage >= 7\n ? '#FFD600'\n : '#F90707';\n};\n\nexport const getActiveColorSteadiness = (\n currentPercentage: number | undefined,\n currentColor: string\n): string => {\n return currentPercentage === undefined\n ? currentColor\n : currentPercentage >= 52\n ? '#0BB127'\n : currentPercentage >= 33\n ? '#FFD600'\n : '#F90707';\n};\n\nexport const getActiveColorDuration = (\n currentPercentage: number | undefined,\n currentColor: string\n): string => {\n return currentPercentage === undefined\n ? currentColor\n : currentPercentage >= 4\n ? '#0BB127'\n : currentPercentage >= 2.5\n ? '#FFD600'\n : '#F90707';\n};\n","import styled from 'styled-components';\n\nexport const Chart = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-width: 75px;\n`\n\nexport const FloatGraph = styled.div`\n display: flex;\n justify-content: center;\n margin-bottom: 22px;\n`\n","import React from 'react';\nimport { formatNumber } from 'utils/report-utils';\nimport { getActiveColorTorqueAndLevel } from './helpers';\nimport * as Styled from './styles';\nimport { Title } from 'shared/components/title';\n\ntype Props = {\n value?: number;\n bowLevelDegrees?: number;\n activeColor?: string;\n};\n\nconst Level: React.FC<Props> = ({\n value,\n bowLevelDegrees,\n activeColor = '#0BB127'\n}): JSX.Element => {\n const formattedValue = formatNumber(bowLevelDegrees);\n const valueForIndicator = Math.max(-5, Math.min(5, bowLevelDegrees || 0));\n const translateXForIndicator = valueForIndicator * -4.5;\n activeColor = getActiveColorTorqueAndLevel(value, activeColor);\n\n return (\n <Styled.Chart>\n <svg height='52' width='80' viewBox='0 0 80 52'>\n <rect ry='6' y={15.25} x={16.5} height={21.5} width={47} fill='#707070' />\n <rect y={15.25} x={31.25} height={21.5} width={2} fill='231F20' />\n <rect y={15.25} x={46.75} height={21.5} width={2} fill='231F20' />\n {value !== undefined ? (\n <path\n fill={activeColor}\n transform={`translate(${translateXForIndicator}, 0)`}\n d='M34.96 5.57a.5.5 0 0 0-.43.75l4.54 7.53v16.23a1.5 1.5 0 1 0 3 0V13.83l3.42-7.5a.5.5 0 0 0-.45-.71Z'\n />\n ) : null}\n </svg>\n <Title title={formattedValue ? formattedValue + '°' : '--'} variant='light' type='regular' />\n </Styled.Chart>\n );\n};\n\nexport default Level;\n","import React from 'react';\nimport { getActiveColorSteadiness } from './helpers';\nimport { formatNumber } from 'utils/report-utils';\nimport * as Styled from './styles';\nimport { Title } from 'shared/components';\n\ntype Props = {\n value?: number;\n aimSteadinessValueDps?: number;\n activeColor?: string;\n};\n\nconst Steadiness: React.FC<Props> = ({\n value,\n aimSteadinessValueDps,\n activeColor = '#707070'\n}): JSX.Element => {\n const r1 = 12.5;\n const r2 = 18.5;\n const r3 = 24.5;\n const strokeDashR1 = (r1 * 2 * Math.PI) / 4;\n const strokeDashR2 = (r2 * 2 * Math.PI) / 4;\n const strokeDashR3 = (r3 * 2 * Math.PI) / 4;\n const defaultColor = '#707070';\n activeColor = getActiveColorSteadiness(value, activeColor);\n const centerColor = activeColor;\n\n const r1Color = value !== undefined && value < 65 ? activeColor : defaultColor;\n const r2Color = value !== undefined && value < 52 ? activeColor : defaultColor;\n const r3Color = value !== undefined && value < 39 ? activeColor : defaultColor;\n const formattedValue = formatNumber(aimSteadinessValueDps);\n\n return (\n <Styled.Chart>\n <svg height='52' width='52' viewBox='0 0 52 52'>\n <circle cx='26' cy='26' r='6.5' fill={centerColor} />\n <circle\n cx='26'\n cy='26'\n r={r1}\n stroke={r1Color}\n strokeWidth={3}\n strokeDasharray={`${strokeDashR1} ${strokeDashR1}`}\n strokeDashoffset={strokeDashR1 / 2}\n fill='transparent'\n />\n <circle\n cx='26'\n cy='26'\n r={r2}\n stroke={r2Color}\n strokeWidth={3}\n strokeDasharray={`${strokeDashR2} ${strokeDashR2}`}\n strokeDashoffset={strokeDashR2 / 2}\n fill='transparent'\n />\n <circle\n cx='26'\n cy='26'\n r={r3}\n stroke={r3Color}\n strokeWidth={3}\n strokeDasharray={`${strokeDashR3} ${strokeDashR3}`}\n strokeDashoffset={strokeDashR3 / 2}\n fill='transparent'\n />\n </svg>\n <Title\n title={formattedValue ? formattedValue + ' MOA' : '--'}\n variant='light'\n type='regular'\n />\n </Styled.Chart>\n );\n};\n\nexport default Steadiness;\n","import React from 'react';\nimport _ from 'lodash';\nimport * as Styled from './styles';\nimport { formatNumber } from 'utils/report-utils';\nimport { getActiveColorTorqueAndLevel } from './helpers';\nimport { Title } from 'shared/components';\n\ntype Props = {\n value?: number;\n bowTorque?: number;\n activeColor?: string;\n};\n\nconst Torque: React.FC<Props> = ({ value, activeColor = '#F90707', bowTorque }): JSX.Element => {\n const formattedValue = formatNumber(bowTorque);\n const valueForIndicator = Math.max(-100, Math.min(100, bowTorque || 0));\n const translateXForIndicator = valueForIndicator * 0.25;\n activeColor = getActiveColorTorqueAndLevel(value, activeColor);\n\n return (\n <Styled.Chart>\n <svg height='52' width='80' viewBox='0 0 80 52'>\n <line\n y1={26}\n x1={16}\n y2={26}\n x2={36}\n strokeWidth={3}\n strokeDasharray={'1 1'}\n stroke='#707070'\n />\n <line\n y1={26}\n x1={44}\n y2={26}\n x2={64}\n strokeWidth={3}\n strokeDasharray={'1 1'}\n stroke='#707070'\n />\n <line y1={6.5} x1={40} y2={22} x2={40} strokeWidth={3} stroke='#707070' />\n <line y1={30} x1={40} y2={45.5} x2={40} strokeWidth={3} stroke='#707070' />\n <circle cx='40' cy='26' r={4} stroke='#707070' strokeWidth={3} fill='transparent' />\n {value !== undefined ? (\n <circle\n cx='40'\n cy='26'\n r={11.5}\n stroke={activeColor}\n strokeWidth={3}\n fill='transparent'\n transform={`translate(${translateXForIndicator}, 0)`}\n />\n ) : null}\n </svg>\n <Title\n title={\n formattedValue && !_.isNil(bowTorque)\n ? formattedValue + '% ' + (bowTorque ? (bowTorque > 0 ? 'R' : 'L') : '')\n : '--'\n }\n variant='light'\n type='regular'\n />\n </Styled.Chart>\n );\n};\n\nexport default Torque;\n","import React from 'react';\nimport { formatNumber } from 'utils/report-utils';\nimport { getActiveColorDuration } from './helpers';\nimport * as Styled from './styles';\nimport { Title } from 'shared/components';\n\ntype Props = {\n value?: number;\n aimTime?: number;\n activeColor?: string;\n};\n\nconst Duration: React.FC<Props> = ({ value, aimTime, activeColor = '#FF8800' }): JSX.Element => {\n const formattedValue = formatNumber(aimTime);\n const showFirstSegment = aimTime && aimTime > 0;\n const showSecondSegment = aimTime && aimTime >= 3;\n const showThirdSegment = aimTime && aimTime >= 5;\n activeColor = getActiveColorDuration(value, activeColor);\n\n return (\n <Styled.Chart>\n <svg height='52' width='52' viewBox='0 0 52 52'>\n <path\n fill='#707070'\n d='M20.5 4.5v4h11v-4zm16.67 4.41-2.67 2.97A16.37 16.37 0 0 0 26 9.5C16.9 9.5 9.5 16.9 9.5 26S16.9 42.5 26 42.5 42.5 35.1 42.5 26c0-4.54-1.85-8.67-4.84-11.65l2.49-2.76zM26 12.5c7.47 0 13.5 6.03 13.5 13.5S33.47 39.5 26 39.5 12.5 33.47 12.5 26 18.53 12.5 26 12.5z'\n />\n {showFirstSegment ? (\n <path fill={activeColor} d='m27.1 25.2-.02-11.25a12 12 0 0 1 9.93 16.98z' />\n ) : null}\n {showSecondSegment ? (\n <path fill={activeColor} d='m16.39 32.95 9.72-5.6 9.72 5.6a12 12 0 0 1-19.44 0z' />\n ) : null}\n {showThirdSegment ? (\n <path\n fill={activeColor}\n d='M14.1 25.91a12 12 0 0 1 10.82-11.94L24.9 25.2l-9.75 5.64a11.96 11.96 0 0 1-1.05-4.92z'\n />\n ) : null}\n </svg>\n <Title title={formattedValue ? formattedValue + 'S' : '--'} variant='light' type='regular' />\n </Styled.Chart>\n );\n};\n\nexport default Duration;\n","import React from 'react';\nimport { TargetHit } from 'shared/types';\n\ntype Props = {\n targetHits: TargetHit[]\n};\n\nconst SmallTarget: React.FC<Props> = ({ targetHits }): JSX.Element => {\n const maxRadius = 130;\n const fov = 40;\n const height = maxRadius;\n const width = maxRadius + 8;\n\n return (\n <svg height={height} width={width} viewBox={`0 0 ${width} ${height}`}>\n <g transform={`translate(4, 0)`}>\n <circle cx='65' cy='65' r='64.5' stroke='#FFF' strokeWidth={1} fill='transparent' />\n <circle cx='65' cy='65' r='54.5' stroke='#FFF' strokeWidth={1} fill='transparent' />\n <circle cx='65' cy='65' r='44.5' stroke='#FFF' strokeWidth={1} fill='transparent' />\n <circle cx='65' cy='65' r='34.5' stroke='#FFF' strokeWidth={1} fill='transparent' />\n <circle cx='65' cy='65' r='22.5' stroke='#FFF' strokeWidth={1} fill='#484848' />\n <circle cx='65' cy='65' r='13.5' fill='#918f90' />\n <path\n d={\n 'm63.4 62.84-.67.74L64.27 65l-1.56 1.42.68.74L65 65.68l1.6 1.48.68-.74L65.75 65l1.47-1.34-.67-.74-1.54 1.4z'\n }\n fill='#231F20'\n />\n {targetHits?.map(\n ({ x, y }, index): JSX.Element => (\n <circle\n key={index}\n cx='65'\n cy='65'\n r='4'\n transform={`translate(${(x / fov) * maxRadius}, ${(y / fov) * maxRadius})`}\n fill='#FFF'\n />\n )\n )}\n </g>\n </svg>\n );\n};\n\nexport default SmallTarget;\n","import React, { CSSProperties } from 'react';\nimport { line, curveBasis } from 'd3';\nimport { AimGraphItem } from 'shared/types';\nimport * as Styled from './styles';\n\ntype Props = {\n preShotAimGraphData: AimGraphItem[];\n postShotAimGraphData: AimGraphItem[];\n fov: number;\n radius?: number;\n containerStyles?: CSSProperties;\n};\n\nconst FloatGraphComponent: React.FC<Props> = ({\n preShotAimGraphData,\n postShotAimGraphData,\n fov,\n containerStyles,\n radius = 152\n}): JSX.Element => {\n const resultRadius = radius + 2;\n const diameter = resultRadius * 2;\n const preShotAimGraphDataPoints = preShotAimGraphData.map(\n ({ x, y }): AimGraphItem => ({\n x: (x / fov) * radius + radius,\n y: (y / fov) * -radius + radius\n })\n );\n const postShotAimGraphDataPoints = postShotAimGraphData.map(\n ({ x, y }): AimGraphItem => ({\n x: (x / fov) * radius + radius,\n y: (y / fov) * -radius + radius\n })\n );\n\n const preShotAimGraphDataCurvedLine =\n line<AimGraphItem>()\n .x((d): number => d.x)\n .y((d): number => d.y)\n .curve(curveBasis)(preShotAimGraphDataPoints) || '';\n\n const postShotAimGraphDataCurvedLine =\n line<AimGraphItem>()\n .x((d): number => d.x)\n .y((d): number => d.y)\n .curve(curveBasis)(postShotAimGraphDataPoints) || '';\n\n const circles = (fov > 10 ? Math.round(fov / 10) : fov) - 1;\n const circlesStep = (radius * 0.9) / (circles + 1);\n\n return (\n <Styled.FloatGraph style={containerStyles}>\n <svg width={diameter} height={diameter} viewBox={`0 0 ${diameter} ${diameter}`}>\n <defs>\n <clipPath id='circle-mask'>\n <circle cx={resultRadius} cy={resultRadius} r={radius} fill='transparent' />\n </clipPath>\n </defs>\n <circle\n cx={resultRadius}\n cy={resultRadius}\n r={radius}\n fill='transparent'\n stroke='#E60019'\n strokeWidth={1}\n />\n {new Array(circles).fill(0).map(\n (v, index): JSX.Element => (\n <circle\n key={index}\n cx={resultRadius}\n cy={resultRadius}\n r={radius - (index + 1) * circlesStep}\n stroke='#FFF'\n strokeWidth={1}\n fill='transparent'\n />\n )\n )}\n <path\n transform={`translate(${resultRadius - 13}, ${resultRadius - 13})`}\n d='M 16.061,13.104 25.595,3.5700001 A 2.091,2.091 0 1 0 22.638,0.61300009 L 13.104,10.147 3.5700001,0.61300009 A 2.091,2.091 0 0 0 0.61300009,3.5700001 L 10.147,13.104 0.61300009,22.638 A 2.091,2.091 0 1 0 3.5700001,25.595 L 13.104,16.061 l 9.534,9.534 a 2.091,2.091 0 1 0 2.957,-2.957 z'\n fill='#FFF'\n />\n <path\n clipPath={'url(#circle-mask)'}\n d={postShotAimGraphDataCurvedLine}\n strokeWidth={3}\n stroke='#FFF'\n fill='transparent'\n />\n <path\n clipPath={'url(#circle-mask)'}\n d={preShotAimGraphDataCurvedLine}\n strokeWidth={3}\n stroke='#FFD600'\n fill='transparent'\n />\n </svg>\n </Styled.FloatGraph>\n );\n};\n\nexport default FloatGraphComponent;\n","import styled from 'styled-components';\n\nexport const Row = styled.div`\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n`;\n\nexport const RowValue = styled.div`\n display: flex;\n align-items: baseline;\n`;\n\nexport const Target = styled.div`\n display: flex;\n`;\n\nexport const TargetStats = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n`;\n\nexport const TargetChart = styled.div`\n flex: 1;\n display: flex;\n justify-content: flex-end;\n`\n","import React, { CSSProperties, useMemo } from 'react';\nimport { getAverageScore } from 'utils/report-utils';\nimport { TargetHit } from 'shared/types';\nimport { SmallTarget, Title } from 'shared/components';\nimport * as Styled from './styles';\n\ntype Props = {\n targetHits: TargetHit[];\n shoots: {\n total: number;\n result: number;\n distance: string;\n }[];\n};\n\ntype RowProps = {\n title: string;\n value: string;\n unit?: string;\n targetRowStyles?: CSSProperties;\n};\n\nconst TargetRow: React.FC<RowProps> = (props): JSX.Element => {\n const { title, value, unit, targetRowStyles } = props;\n\n return (\n <Styled.Row style={targetRowStyles}>\n <Title title={title} variant='light' />\n <Styled.RowValue>\n <Title title={value} variant='light' type='regular' />\n {unit && <Title title={`${unit}`} variant='light' />}\n </Styled.RowValue>\n </Styled.Row>\n );\n};\n\nconst Target: React.FC<Props> = (props): JSX.Element => {\n const { shoots, targetHits } = props;\n\n const overall = useMemo((): number => {\n const result = shoots.reduce((acc, curr): number => acc + curr.result, 0);\n return getAverageScore(Object.keys(shoots).length, result, true);\n }, [shoots]);\n\n return (\n <Styled.Target>\n <Styled.TargetStats>\n {shoots.map(\n ({ result, distance }, index): JSX.Element => (\n <TargetRow key={index} title={`${distance} YDS.`} value={`${result}`} unit='IN.' />\n )\n )}\n <TargetRow\n title={'OVERALL'}\n value={`${overall} IN.`}\n targetRowStyles={{ marginTop: 'auto' }}\n />\n </Styled.TargetStats>\n <Styled.TargetChart>\n <SmallTarget targetHits={targetHits} />\n </Styled.TargetChart>\n </Styled.Target>\n );\n};\n\nexport default Target;\n","import styled from 'styled-components';\n\nexport const Comment = styled.div`\n display: flex;\n`\n\nexport const CommentDetails = styled.div`\n flex-shrink: 1;\n margin-left: 13px;\n`\n\nexport const UserInfo = styled.div`\n display: flex;\n`\n\nexport const AvatarContainer = styled.div`\n min-width: 40px;\n max-width: 40px;\n min-height: 40px;\n max-height: 40px;\n border-radius: 20px;\n`;\n\nexport const Avatar = styled.img`\n width: 100%;\n height: 100%;\n border-radius: 20px;\n`;\n","import React, { CSSProperties } from 'react';\nimport * as Styled from './styles';\nimport AvatarPlaceholder from 'assets/images/bow-ava.png';\nimport { SessionComment, ShotComment } from '../../types';\nimport { Title } from 'shared/components';\nimport { getFullName, formatTimestamp } from 'utils/report-utils';\n\ntype Props = {\n comment: SessionComment | ShotComment;\n containerStyles?: CSSProperties;\n};\n\nconst Comment: React.FC<Props> = (props): JSX.Element => {\n const {\n comment: { user, createdAt, content },\n containerStyles\n } = props;\n\n return (\n <Styled.Comment style={containerStyles}>\n <Styled.AvatarContainer>\n <Styled.Avatar src={user.profilePictureS3Url || AvatarPlaceholder} />\n </Styled.AvatarContainer>\n <Styled.CommentDetails>\n <Styled.UserInfo>\n <Title\n title={getFullName(user)}\n type='regular'\n size='lg'\n color='#FFF'\n containerStyles={{ flexShrink: 1, marginRight: 15 }}\n />\n <Title\n title={formatTimestamp(createdAt)}\n uppercase={false}\n type='defaultRegular'\n size='xs'\n color='#707070'\n containerStyles={{ paddingTop: 2 }}\n />\n </Styled.UserInfo>\n <Title\n title={content}\n uppercase={false}\n type='defaultRegular'\n size='xs'\n color='#FFF'\n containerStyles={{ marginTop: 10 }}\n />\n </Styled.CommentDetails>\n </Styled.Comment>\n );\n};\n\nexport default Comment;\n","import React from 'react';\nimport TrainingIcon from './TrainingIcon';\nimport HuntIcon from './HuntIcon';\n\ntype IconName = 'training' | 'hunting';\n\ntype Props = {\n name: IconName;\n color?: string;\n size?: number;\n};\n\nconst ICONS: { [key in IconName]: React.FC<Omit<Props, 'name'>> } = {\n training: TrainingIcon,\n hunting: HuntIcon\n};\n\nconst Icon: React.FC<Props> = (props): JSX.Element => {\n const { name, ...rest } = props;\n const IconComponent = ICONS[name];\n return <IconComponent {...rest} />;\n};\n\nexport default Icon;\n","import React from 'react';\n\ntype Props = {\n color?: string;\n size?: number;\n};\n\nconst TrainingIcon: React.FC<Props> = (props): JSX.Element => {\n const { size = 20, color = '#000' } = props;\n return (\n <svg\n xmlns='http://www.w3.org/2000/svg'\n width={size}\n height={size}\n viewBox={`0 0 ${size * 2} ${size * 2}`}\n >\n <g\n id='Group_21738'\n data-name='Group 21738'\n transform='matrix(0.259, 0.966, -0.966, 0.259, 47.418, -1.154)'\n >\n <g id='Group_21028' data-name='Group 21028' transform='translate(0 0)'>\n <path\n id='Path_34153'\n data-name='Path 34153'\n d='M25.977,3.906H24.613L23.249,0S14.6-.061,8.866,1.178,0,7.5,0,7.5L5.3,8.587A5.57,5.57,0,0,1,8.928,4.836C11.9,3.875,20.8,3.6,20.8,3.6l1.7,4.681h3.472Z'\n transform='translate(1.674 18.444)'\n fill={color}\n stroke={color}\n stroke-linejoin='round'\n stroke-width='2'\n />\n <g\n id='Ellipse_2243'\n data-name='Ellipse 2243'\n transform='translate(0 23.838)'\n fill={color}\n stroke={color}\n stroke-width='2'\n >\n <circle cx='3.968' cy='3.968' r='3.968' stroke='none' />\n <circle cx='3.968' cy='3.968' r='2.968' fill='none' />\n </g>\n <path\n id='Path_34157'\n data-name='Path 34157'\n d='M0,30.472c.083.162,26.225,18.475,26.225,18.475V0L23.59,6.262,25.574,8.4V43.677l-2.511,3.038Z'\n transform='translate(1.829 0)'\n fill={color}\n stroke={color}\n stroke-linejoin='round'\n stroke-width='1'\n />\n </g>\n <g id='Group_21029' data-name='Group 21029' transform='translate(28.054 0)'>\n <path\n id='Path_34153-2'\n data-name='Path 34153'\n d='M0,3.906H1.364L2.728,0s8.648-.062,14.383,1.178S25.977,7.5,25.977,7.5l-5.3,1.085a5.57,5.57,0,0,0-3.627-3.751C14.073,3.875,5.177,3.6,5.177,3.6l-1.7,4.681H0Z'\n transform='translate(0.403 18.444)'\n fill={color}\n stroke={color}\n stroke-linejoin='round'\n stroke-width='2'\n />\n <g\n id='Ellipse_2243-2'\n data-name='Ellipse 2243'\n transform='translate(20.118 23.838)'\n fill={color}\n stroke={color}\n stroke-width='2'\n >\n <circle cx='3.968' cy='3.968' r='3.968' stroke='none' />\n <circle cx='3.968' cy='3.968' r='2.968' fill='none' />\n </g>\n <path\n id='Path_34157-2'\n data-name='Path 34157'\n d='M26.225,30.472C26.143,30.634,0,48.947,0,48.947V0L2.635,6.262.651,8.4V43.677l2.511,3.038Z'\n transform='translate(0 0)'\n fill={color}\n stroke={color}\n stroke-linejoin='round'\n stroke-width='1'\n />\n </g>\n </g>\n </svg>\n );\n};\n\nexport default TrainingIcon;\n","import React from 'react';\n\ntype Props = {\n color?: string;\n size?: number;\n};\n\nconst HuntIcon: React.FC<Props> = (props): JSX.Element => {\n const { size = 20, color = '#000' } = props;\n return (\n <svg\n xmlns='http://www.w3.org/2000/svg'\n width={size}\n height={size}\n viewBox={`0 0 ${size * 2} ${size * 2}`}\n >\n <g id='Group_21928' data-name='Group 21928' transform='translate(-263.794 -144.227)'>\n <path\n id='Subtraction_31'\n data-name='Subtraction 31'\n d='M13.853,45.537H0V0H14.729c.014.154.084,3.363-.012,6.237h7.793a39.807,39.807,0,0,1-2.262,13.878A22.344,22.344,0,0,1,13.9,27.808c-2.58,1.909-10.414,5.85-11.3,6.294v3.1c.333.928,1.826,3.087,8.474,3.087h2.782v5.251Zm.531-34.375c-.075.653-.164,1.244-.25,1.784a47.744,47.744,0,0,1-2.793,10.6,15.689,15.689,0,0,0,4.5-5.614,18.176,18.176,0,0,0,1.71-6.775Z'\n transform='translate(285.138 153.08)'\n fill={color}\n />\n <path\n id='Union_32'\n data-name='Union 32'\n d='M18.27,54.39,9.961,48.1s-.831-6.012,0-8.063a23.47,23.47,0,0,1,3.531-5.022,5.912,5.912,0,0,1-1.317-3.254,7.411,7.411,0,0,1,.971-3.041s-3.185.354-5.055-.707-3.117-4.244-3.117-4.244a6.9,6.9,0,0,1,4.086,0c2.076.707,3.532,1.344,3.532,1.344a36.672,36.672,0,0,0-6.146-3.678c-4.155-2.069-8.622-6.9-5.272-14.243S6.775,0,6.775,0A35.731,35.731,0,0,0,3.8,5.7c-.623,1.98-1.247,4.2-1.247,4.2A12.693,12.693,0,0,1,5.562,6.684,4.994,4.994,0,0,1,8.731,5.7,16.408,16.408,0,0,0,5.356,9.018C4.005,10.9,3.243,15.277,3.243,15.277S4.827,12.051,7.675,11.1a9.183,9.183,0,0,1,5.471,0,10.908,10.908,0,0,0-5.35,2.29,7.807,7.807,0,0,0-2.822,4,2.706,2.706,0,0,0,1.732,1.485,59.568,59.568,0,0,1,5.47,2.546s-.969-1.98,0-3.324a6.753,6.753,0,0,1,3.048-1.98s-1.732,1.627-1.732,2.9,4.778,6.648,4.778,6.648Z'\n transform='translate(263.794 144.227)'\n fill={color}\n />\n </g>\n </svg>\n );\n};\n\nexport default HuntIcon;\n","import { DEVICE } from 'shared/constants/deviceSizes';\nimport styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const SearchForm = styled.form`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchFormInputContainer = styled.div`\n width: 70%;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 24px;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & tbody tr td,\n th {\n width: 25%;\n display: inline-block;\n\n @media ${DEVICE.tablet} {\n width: 33%;\n }\n }\n\n & tbody tr td:last-child {\n width: 50%;\n\n @media ${DEVICE.tablet} {\n width: 33%;\n }\n }\n\n & thead tr th:last-child {\n width: 50%;\n\n @media ${DEVICE.tablet} {\n width: 33%;\n }\n }\n`;\n","import { format } from 'date-fns';\n\nexport const parseISODateFormat = (date: string, withTime: boolean = false): string => {\n const dateFormat = withTime ? 'yyyy-MM-dd hh:mm:ss a' : 'yyyy-MM-dd';\n return date ? format(new Date(date), dateFormat) : ``;\n};\n","export const BOW_COLUMNS = [\n {\n title: 'Bow serial number',\n dataIndex: 'productSerialNumber',\n key: 'productSerialNumber',\n sortKey: 'productSerialNumber',\n ellipsis: true,\n sorter: { multiple: 1 }\n },\n {\n title: 'Bow user',\n dataIndex: 'email',\n key: 'users.email',\n sortKey: 'users.email',\n ellipsis: true,\n sorter: { multiple: 1 }\n },\n {\n title: 'Registered',\n dataIndex: 'createdAt',\n key: 'createdAt',\n sortKey: 'createdAt',\n ellipsis: true,\n sorter: { multiple: 1 }\n }\n];\n","import React, { useEffect, useState } from 'react';\nimport { Button, Input, PageHeader, Pagination, Table } from 'antd';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { useFormik } from 'formik';\nimport { useDevices, useNotifications } from 'shared/hooks';\nimport { validation } from 'services/validation';\nimport { PaginationContainer } from 'shared/styles';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { parseISODateFormat } from 'utils/date-utils';\nimport { getDeviceBySerialNumber } from 'services/api/devicesService';\nimport { ESnackbarStyle } from 'shared/types';\nimport { useHistory } from 'react-router';\nimport { handleSortAction } from 'utils/sorting-utils';\nimport { BOW_COLUMNS } from './constants';\nimport { getFieldError } from 'utils/error-utils';\n\ntype TableDevice = {\n key: number;\n id: number;\n productSerialNumber: string;\n email: string;\n createdAt: string;\n};\n\ntype RowAction = {\n onClick: () => void;\n};\n\ntype FormValues = {\n searchValue: string;\n};\n\nconst CheckBowPage = (): JSX.Element => {\n const [tableDevices, setTableDevices] = useState<TableDevice[]>([]);\n const {\n devices,\n fetchDevices,\n isDevicesLoading,\n totalDevices,\n setCurrentPage,\n currentPage,\n setSortParams\n } = useDevices();\n const { openNotification } = useNotifications();\n const history = useHistory();\n\n useEffect((): void => {\n fetchDevices();\n }, [fetchDevices]);\n\n useEffect((): void => {\n const modifiedDevices = devices.map((device): TableDevice => {\n return {\n key: device.id,\n id: device.id,\n productSerialNumber: device.productSerialNumber,\n email: device.deviceUser?.email,\n createdAt: parseISODateFormat(device.createdAt)\n };\n });\n setTableDevices(modifiedDevices);\n }, [devices]);\n\n const initialValues: FormValues = {\n searchValue: ''\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n try {\n await getDeviceBySerialNumber(values.searchValue);\n history.push(`bows/${values.searchValue}`);\n } catch (e) {\n openNotification(ESnackbarStyle.WARNING, 'Bow was not found');\n }\n },\n initialValues,\n validationSchema: validation.CHECK_A_BOW\n });\n\n const handleRowClick = (device: TableDevice): void => {\n history.push(`/bows/${device.productSerialNumber}`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Check a bow' />\n <Styled.SearchForm onSubmit={formik.handleSubmit}>\n <Styled.SearchFormInputContainer>\n <Input\n value={formik.values.searchValue}\n name='searchValue'\n onChange={formik.handleChange}\n size='large'\n placeholder='Serial number'\n />\n {getFieldError(formik, 'searchValue')}\n </Styled.SearchFormInputContainer>\n <Button type='primary' htmlType='submit'>\n Apply\n </Button>\n </Styled.SearchForm>\n <Styled.TableContainer>\n <Table\n onRow={(device: TableDevice): RowAction => ({\n onClick: (): void => handleRowClick(device)\n })}\n columns={BOW_COLUMNS}\n dataSource={tableDevices}\n loading={isDevicesLoading}\n pagination={false}\n size={'middle'}\n onChange={handleSortAction(setSortParams)}\n />\n {totalDevices > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={totalDevices}\n onChange={setCurrentPage}\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default CheckBowPage;\n","import styled from 'styled-components';\n\nexport const MainPageContainer = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n`;","import React, { useEffect } from 'react';\nimport { Spin } from 'antd';\nimport { useAppDispatch, useAppSelector } from 'shared/hooks';\nimport { Redirect, useHistory, useLocation } from 'react-router';\nimport { MainPageContainer } from './styles';\nimport { getCurrentUser } from 'services/api/authService';\nimport { loginUserSuccess } from 'services/store/reducers/authReducer';\nimport { EUserRole } from '../../shared/types';\n\ntype LocationState = {\n from: {\n pathname: string;\n };\n};\n\nconst MainPage = (): JSX.Element => {\n const { isAuth, user } = useAppSelector((state) => state.auth);\n const history = useHistory();\n const location = useLocation<LocationState>();\n const dispatch = useAppDispatch();\n\n useEffect((): void => {\n const fetchUser = async (): Promise<void> => {\n try {\n const response = await getCurrentUser();\n dispatch(loginUserSuccess(response.data));\n } catch (e) {\n history.push('/login');\n }\n };\n fetchUser();\n }, [history, dispatch]);\n\n const { from } = location.state || {\n from: { pathname: user && user.role === EUserRole.moderator ? '/reports' : '/sessions' }\n };\n\n if (isAuth) return <Redirect to={from} />;\n\n return (\n <MainPageContainer>\n <Spin size='large' />\n </MainPageContainer>\n );\n};\n\nexport default MainPage;\n","import { DEVICE } from 'shared/constants/deviceSizes';\nimport styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const Form = styled.form`\n max-width: 480px;\n width: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nexport const FormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n\nexport const FormInputInner = styled.div`\n display: flex;\n align-items: center;\n\n button {\n margin-left: 10px;\n }\n`;\n\nexport const ButtonGroup = styled.div`\n display: flex;\n justify-content: space-between;\n\n & > button {\n width: min-content;\n }\n\n @media ${DEVICE.tablet} {\n justify-content: initial;\n flex-direction: column;\n\n & button:last-child {\n margin-top: 10px;\n }\n }\n`;\n\nexport const CheckboxContainer = styled.div`\n margin-top: 20px;\n`;\n","import { EUserRole } from 'shared/types';\n\ntype Role = {\n label: string;\n value: EUserRole;\n};\n\nexport const ROLES: Role[] = [\n {\n label: 'User',\n value: EUserRole.support_user\n },\n {\n label: 'Admin',\n value: EUserRole.admin_user\n },\n {\n label: 'Moderator',\n value: EUserRole.moderator\n }\n];\n","import { EUserRole } from 'shared/types';\n\nexport const checkRolePermission = (\n permissibleRoles: EUserRole[],\n currentUserRole: EUserRole\n): boolean => permissibleRoles.some((item): boolean => item === currentUserRole);\n","import React, { useState } from 'react';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { Button, Checkbox, Input, PageHeader, Select } from 'antd';\nimport { Redirect, useHistory } from 'react-router';\nimport { useFormik } from 'formik';\nimport { ROLES } from 'shared/constants/roles';\nimport { validation } from 'services/validation';\nimport { CheckboxChangeEvent } from 'antd/lib/checkbox';\nimport { EyeInvisibleOutlined, EyeTwoTone, CopyOutlined } from '@ant-design/icons';\nimport { ESnackbarStyle, EUserRole, NewUser, User } from 'shared/types';\nimport { addUser } from 'services/api/usersService';\nimport { useAppSelector, useCopyToClipboard, useNotifications } from 'shared/hooks';\nimport { getFieldError } from 'utils/error-utils';\nimport { checkRolePermission } from 'utils/role-utils';\n\ntype FormValues = {\n firstName: string;\n lastName: string;\n role: string;\n email: string;\n password: string;\n confirmPassword: string;\n sendEmail: boolean;\n};\n\nconst AddUserPage = (): JSX.Element => {\n const history = useHistory();\n const { openNotification } = useNotifications();\n const user = useAppSelector((state): User | null => state.auth.user);\n const [isNewUserLoading, setIsNewUserLoading] = useState<boolean>(false);\n\n const { copyToClipboard } = useCopyToClipboard();\n\n const initialValues: FormValues = {\n firstName: '',\n lastName: '',\n role: ROLES[0].value,\n email: '',\n password: '',\n confirmPassword: '',\n sendEmail: false\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n const { email, password, firstName, lastName, role, sendEmail } = values;\n const newUser: NewUser = { email, password, firstName, lastName, role, sendEmail };\n setIsNewUserLoading(true);\n try {\n await addUser(newUser);\n openNotification(ESnackbarStyle.SUCCESS, 'User was added successfully');\n history.push('/users');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsNewUserLoading(false);\n }\n },\n initialValues,\n validationSchema: validation.ADD_USER\n });\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const handleSelectFieldChange =\n (fieldName: string): ((value: string) => void) =>\n (value: string): void => {\n formik.setFieldValue(fieldName, value);\n };\n\n const handleCheckboxChange =\n (fieldName: string): ((event: CheckboxChangeEvent) => void) =>\n (event: CheckboxChangeEvent): void => {\n formik.setFieldValue(fieldName, event.target.checked);\n };\n\n const handleGeneratePasswordClick = (): void => {\n const password = Math.random().toString(36).slice(-8);\n formik.setValues({ ...formik.values, password, confirmPassword: password });\n };\n\n const handleCopyButtonClick = (): void => {\n copyToClipboard(formik.values.password);\n };\n\n if (\n user?.role &&\n !checkRolePermission([EUserRole.master_admin, EUserRole.admin_user], user.role)\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Add a new user' />\n <Styled.Form onSubmit={formik.handleSubmit}>\n <Styled.FormInputContainer>\n <Input\n placeholder='First name'\n size='large'\n value={formik.values.firstName}\n name='firstName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n />\n {getFieldError(formik, 'firstName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Last name'\n size='large'\n value={formik.values.lastName}\n name='lastName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n />\n {getFieldError(formik, 'lastName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Select\n allowClear={false}\n size='large'\n placeholder='Role'\n value={formik.values.role}\n style={{ width: '100%' }}\n onChange={handleSelectFieldChange('role')}\n >\n {ROLES.map(\n (item): JSX.Element => (\n <Select.Option key={item.value} value={item.value}>\n {item.label}\n </Select.Option>\n )\n )}\n </Select>\n {getFieldError(formik, 'role')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Email'\n size='large'\n value={formik.values.email}\n name='email'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n />\n {getFieldError(formik, 'email')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Styled.FormInputInner>\n <Input.Password\n placeholder='Password'\n size='large'\n value={formik.values.password}\n name='password'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n iconRender={(visible): JSX.Element =>\n visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />\n }\n />\n {formik.values.password && (\n <Button\n type='primary'\n onClick={handleCopyButtonClick}\n shape='circle'\n icon={<CopyOutlined />}\n />\n )}\n </Styled.FormInputInner>\n {getFieldError(formik, 'password')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input.Password\n placeholder='Confirm password'\n size='large'\n value={formik.values.confirmPassword}\n name='confirmPassword'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n iconRender={(visible): JSX.Element =>\n visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />\n }\n />\n {getFieldError(formik, 'confirmPassword')}\n </Styled.FormInputContainer>\n <Styled.ButtonGroup>\n <Button type='primary' onClick={handleGeneratePasswordClick}>\n Generate password automatically\n </Button>\n <Button type='primary' htmlType='submit' loading={isNewUserLoading}>\n Add\n </Button>\n </Styled.ButtonGroup>\n <Styled.CheckboxContainer>\n <Checkbox\n checked={formik.values.sendEmail}\n onChange={handleCheckboxChange('sendEmail')}\n >\n Send credentials by e-mail\n </Checkbox>\n </Styled.CheckboxContainer>\n </Styled.Form>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default AddUserPage;\n","import React, { ReactNode, useEffect, useState, useContext } from 'react';\nimport { useAppSelector } from 'shared/hooks';\nimport io, { Socket } from 'socket.io-client';\n\ntype Props = {\n children: ReactNode;\n};\n\ntype ContextState = {\n socket: Socket | null;\n};\n\nconst initialContextState: ContextState = {\n socket: null\n};\n\nexport const SocketContext = React.createContext<ContextState>(initialContextState);\nexport const useSocketContext = (): ContextState => useContext(SocketContext);\n\nexport const SocketProvider: React.FC<Props> = ({ children }): JSX.Element => {\n const [socket, setSocket] = useState<Socket | null>(null);\n const isAuth = useAppSelector((state): boolean => state.auth.isAuth);\n\n useEffect((): (() => void) | void => {\n if (isAuth) {\n const socket = io(`${process.env.REACT_APP_API_URL}`, {\n path: '/ws',\n auth: {\n token: localStorage.getItem('token')\n },\n transports: ['websocket', 'polling'] // use WebSocket first, if available\n });\n\n socket.on('connect_error', (err) => {\n // If WebSocket connection fails, revert to classic upgrade (polling then WebSocket)\n socket.io.opts.transports = ['polling', 'websocket'];\n // tslint:disable-next-line:no-console\n console.error('Connection Error:', err.message);\n });\n\n setSocket(socket);\n\n return (): void => {\n socket.disconnect();\n };\n }\n }, [isAuth]);\n\n return <SocketContext.Provider value={{ socket }}>{children}</SocketContext.Provider>;\n};\n","import React, { useEffect } from 'react';\nimport { FirmwareList } from 'shared/components';\nimport { useFirmwareVersions } from 'shared/hooks';\nimport { useSocketContext } from 'shared/providers';\nimport { EFirmwareStatus, EFirmwareUpdateChannel, FirmwareTableRow } from 'shared/types';\nimport { parseISODateFormat } from 'utils/date-utils';\n\nconst FirmwareRelease = (): JSX.Element => {\n const {\n firmwareVersions,\n fetchFirmwareByStatus,\n activeFirmware,\n scheduledFirmware,\n fetchFirmwareVersions,\n isFirmwareVersionsLoading,\n totalFirmwares,\n currentPage,\n setCurrentPage,\n setSortParams,\n searchValue,\n setSearchValue\n } = useFirmwareVersions(EFirmwareUpdateChannel.release);\n const { socket } = useSocketContext();\n\n useEffect((): void => {\n fetchFirmwareVersions();\n }, [fetchFirmwareVersions]);\n\n useEffect((): void => {\n fetchFirmwareByStatus(EFirmwareStatus.active);\n fetchFirmwareByStatus(EFirmwareStatus.scheduled);\n }, [fetchFirmwareByStatus]);\n\n useEffect((): void => {\n if (socket) {\n socket.on('firmware:update', (): void => {\n fetchFirmwareVersions();\n fetchFirmwareByStatus(EFirmwareStatus.active);\n fetchFirmwareByStatus(EFirmwareStatus.scheduled);\n });\n }\n }, [socket, fetchFirmwareVersions, fetchFirmwareByStatus]);\n\n const fetchFirmwareData = async (): Promise<void> => {\n await fetchFirmwareVersions();\n await fetchFirmwareByStatus(EFirmwareStatus.active);\n await fetchFirmwareByStatus(EFirmwareStatus.scheduled);\n };\n\n const TABLE_DATA = firmwareVersions.map(\n (item): FirmwareTableRow => ({\n key: item.id,\n version: item.semver,\n createdAt: parseISODateFormat(item.createdAt),\n status: item.status === EFirmwareStatus.uploaded ? 'draft' : item.status,\n activatedDate: parseISODateFormat(item.createdAt),\n scheduledAt: item.scheduledAt,\n changelog: item.changelog,\n author: item.uploadedBy,\n fileId: item.fileId\n })\n );\n\n return (\n <FirmwareList\n firmwareUpdateChannel={EFirmwareUpdateChannel.release}\n fetchFirmwareData={fetchFirmwareData}\n activeFirmware={activeFirmware}\n scheduledFirmware={scheduledFirmware}\n data={TABLE_DATA}\n isDataLoading={isFirmwareVersionsLoading}\n totalFirmwares={totalFirmwares}\n currentPage={currentPage}\n setCurrentPage={setCurrentPage}\n setSortParams={setSortParams}\n searchValue={searchValue}\n setSearchValue={setSearchValue}\n />\n );\n};\n\nexport default FirmwareRelease;\n","import React, { useEffect } from 'react';\nimport { FirmwareList } from 'shared/components';\nimport { useFirmwareVersions } from 'shared/hooks';\nimport { useSocketContext } from 'shared/providers';\nimport { EFirmwareStatus, EFirmwareUpdateChannel, FirmwareTableRow } from 'shared/types';\nimport { parseISODateFormat } from 'utils/date-utils';\n\nconst FirmwareTesting = (): JSX.Element => {\n const {\n firmwareVersions,\n fetchFirmwareByStatus,\n activeFirmware,\n scheduledFirmware,\n fetchFirmwareVersions,\n isFirmwareVersionsLoading,\n totalFirmwares,\n currentPage,\n setCurrentPage,\n setSortParams,\n searchValue,\n setSearchValue\n } = useFirmwareVersions(EFirmwareUpdateChannel.testing);\n const { socket } = useSocketContext();\n\n useEffect((): void => {\n fetchFirmwareVersions();\n }, [fetchFirmwareVersions]);\n\n useEffect((): void => {\n fetchFirmwareByStatus(EFirmwareStatus.active);\n fetchFirmwareByStatus(EFirmwareStatus.scheduled);\n }, [fetchFirmwareByStatus]);\n\n useEffect((): void => {\n if (socket) {\n socket.on('firmware:update', (): void => {\n fetchFirmwareVersions();\n fetchFirmwareByStatus(EFirmwareStatus.active);\n fetchFirmwareByStatus(EFirmwareStatus.scheduled);\n });\n }\n }, [socket, fetchFirmwareVersions, fetchFirmwareByStatus]);\n\n const fetchFirmwareData = async (): Promise<void> => {\n await fetchFirmwareVersions();\n await fetchFirmwareByStatus(EFirmwareStatus.active);\n await fetchFirmwareByStatus(EFirmwareStatus.scheduled);\n };\n\n const TABLE_DATA = firmwareVersions.map(\n (item): FirmwareTableRow => ({\n key: item.id,\n version: item.semver,\n createdAt: parseISODateFormat(item.createdAt),\n status: item.status === EFirmwareStatus.uploaded ? 'draft' : item.status,\n activatedDate: parseISODateFormat(item.createdAt),\n scheduledAt: item.scheduledAt,\n changelog: item.changelog,\n author: item.uploadedBy,\n fileId: item.fileId\n })\n );\n\n return (\n <FirmwareList\n firmwareUpdateChannel={EFirmwareUpdateChannel.testing}\n fetchFirmwareData={fetchFirmwareData}\n activeFirmware={activeFirmware}\n scheduledFirmware={scheduledFirmware}\n data={TABLE_DATA}\n isDataLoading={isFirmwareVersionsLoading}\n totalFirmwares={totalFirmwares}\n currentPage={currentPage}\n setCurrentPage={setCurrentPage}\n setSortParams={setSortParams}\n searchValue={searchValue}\n setSearchValue={setSearchValue}\n />\n );\n};\n\nexport default FirmwareTesting;\n","import styled from 'styled-components';\nimport { DEVICE } from 'shared/constants/deviceSizes';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const NewUserButton = styled.div`\n width: 270px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 24px;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & tbody tr td,\n th {\n width: 25%;\n display: inline-block;\n\n @media ${DEVICE.tablet} {\n width: 33%;\n }\n }\n\n & tbody tr td:last-child {\n width: 50%;\n\n @media ${DEVICE.tablet} {\n width: 33%;\n }\n }\n\n & thead tr th:last-child {\n width: 50%;\n\n @media ${DEVICE.tablet} {\n width: 33%;\n }\n }\n`;\n","export const USER_COLUMNS = [\n {\n title: 'User name',\n dataIndex: 'firstName',\n key: 'firstName',\n ellipsis: true,\n sorter: { multiple: 1 },\n sortKey: 'firstName'\n },\n {\n title: 'Role',\n dataIndex: 'role',\n key: 'role',\n ellipsis: true,\n sorter: { multiple: 1 },\n sortKey: 'role'\n },\n {\n title: 'Added',\n dataIndex: 'createdAt',\n key: 'createdAt',\n sorter: { multiple: 1 },\n sortKey: 'createdAt'\n }\n];\n","import React, { useEffect, useState } from 'react';\nimport { NavLink, useHistory } from 'react-router-dom';\nimport * as Styled from './styles';\nimport { ContentContainer } from 'shared/components';\nimport { Button, PageHeader, Table, Input } from 'antd';\nimport { PlusCircleOutlined } from '@ant-design/icons';\nimport { useAppSelector, useUsers } from 'shared/hooks';\nimport { EUserRole, User } from 'shared/types';\nimport { format } from 'date-fns';\nimport Pagination from 'antd/lib/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { ROLES } from 'shared/constants/roles';\nimport { handleSortAction } from 'utils/sorting-utils';\nimport { USER_COLUMNS } from './constants';\nimport { checkRolePermission } from 'utils/role-utils';\n\ntype TableUser = {\n id: number;\n key: number;\n firstName: string;\n role: string;\n createdAt: string;\n};\n\ntype RowAction = {\n onClick: () => void;\n};\n\nconst UsersPage = (): JSX.Element => {\n const history = useHistory();\n const [tableUsers, setTableUsers] = useState<TableUser[]>([]);\n const {\n users,\n pagination,\n searchValue,\n isUsersLoading,\n fetchUsers,\n setSortParams,\n setSearchValue,\n onChangePagination\n } = useUsers();\n const user = useAppSelector((state): User | null => state.auth.user);\n\n useEffect((): void => {\n fetchUsers();\n }, [fetchUsers]);\n\n useEffect((): void => {\n const modifiedUsers = users.map(\n (user): TableUser => ({\n id: user.id,\n key: user.id,\n firstName: `${user.firstName} ${user.lastName}`,\n role: ROLES.find((item): boolean => item.value === user?.role)?.label || '',\n createdAt: format(new Date(user.createdAt), 'yyyy-MM-dd')\n })\n );\n setTableUsers(modifiedUsers);\n }, [users]);\n\n const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const handleRowClick = (user: TableUser): void => {\n history.push(`/users/${user.id}`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Users' />\n <Styled.PageHeader>\n <Styled.NewUserButton>\n <NavLink to='/add-user'>\n {user?.role &&\n checkRolePermission([EUserRole.master_admin, EUserRole.admin_user], user.role) && (\n <Button icon={<PlusCircleOutlined />}>New user</Button>\n )}\n </NavLink>\n </Styled.NewUserButton>\n <Styled.SearchInput>\n <Input\n placeholder='Search'\n onChange={handleSearchInputChange}\n value={searchValue}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n onRow={(user): RowAction => ({ onClick: (): void => handleRowClick(user) })}\n columns={USER_COLUMNS}\n dataSource={tableUsers}\n pagination={false}\n loading={isUsersLoading}\n size={'middle'}\n onChange={handleSortAction(setSortParams)}\n />\n <PaginationContainer>\n <Pagination\n current={pagination.currentPage}\n total={pagination.totalItemsCount}\n onChange={onChangePagination}\n pageSize={pagination.pageSize}\n />\n </PaginationContainer>\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default UsersPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const NewUserButton = styled.div`\n width: 270px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n\nexport const TableActionRow = styled.div`\n display: flex;\n justify-content: space-between;\n gap: 5px;\n`;\n\nexport const TableAction = styled.div`\n flex: 1;\n cursor: pointer;\n\n .subLabel {\n font-size: 12px;\n }\n\n &:nth-child(2) {\n flex: 1.2;\n }\n\n &:last-child {\n flex: 0;\n }\n`;\n","import { Tag } from 'antd';\nimport { EUserStatus } from 'shared/types';\n\nexport const USER_COLUMNS = [\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n sorter: { multiple: 1 },\n sortKey: 'username'\n },\n {\n title: 'Full name',\n dataIndex: 'firstName',\n key: 'firstName',\n ellipsis: true,\n sorter: { multiple: 1 },\n sortKey: 'firstName'\n },\n {\n title: 'Added',\n dataIndex: 'createdAt',\n key: 'createdAt',\n sorter: { multiple: 1 },\n sortKey: 'createdAt'\n },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n render: renderStatusTag\n },\n {\n title: 'Last Shot',\n dataIndex: 'lastShot',\n key: 'lastShot',\n }\n];\n\n// tslint:disable-next-line:typedef\nexport function renderStatusTag(status: EUserStatus) {\n switch (status) {\n case EUserStatus.Active:\n return <Tag color='green'>Active</Tag>;\n case EUserStatus.Disabled:\n return <Tag color='red'>Disabled</Tag>;\n case EUserStatus.Created:\n return <Tag color='blue'>Pending Confirmation</Tag>;\n case EUserStatus.Deleted:\n return <Tag color='gray'>Deleted</Tag>;\n default:\n return status || '-';\n }\n}\n","import React, { useEffect, useState } from 'react';\nimport * as Styled from './styles';\nimport { ContentContainer } from 'shared/components';\nimport { PageHeader, Table, Input, Typography } from 'antd';\nimport { useUsers } from 'shared/hooks';\nimport { EUserRole, EUserStatus } from 'shared/types';\nimport { format } from 'date-fns';\nimport Pagination from 'antd/lib/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { ROLES } from 'shared/constants/roles';\nimport { handleSortAction } from 'utils/sorting-utils';\nimport { USER_COLUMNS } from './constants';\nimport { useHistory } from 'react-router-dom';\n\ntype TableUser = {\n id: number;\n key: number;\n firstName: string;\n username: string;\n status: EUserStatus;\n role: string;\n createdAt: string;\n totalShots: number;\n lastShot: string;\n};\n\nconst BowUsersPage = (): JSX.Element => {\n const history = useHistory();\n const [tableUsers, setTableUsers] = useState<TableUser[]>([]);\n const {\n users,\n pagination,\n searchValue,\n isUsersLoading,\n fetchUsers,\n setSortParams,\n setSearchValue,\n onChangePagination\n } = useUsers();\n\n useEffect((): void => {\n fetchUsers(true);\n }, [fetchUsers]);\n\n useEffect((): void => {\n // tslint:disable-next-line:typedef\n const modifiedUsers = users\n .filter((user) => user.role === EUserRole.application_user)\n .map(\n (user): TableUser => ({\n id: user.id,\n key: user.id,\n username: user.username || '-',\n firstName: [user.firstName, user.lastName].filter(Boolean).join(' ') || '-',\n status: user.status,\n role: ROLES.find((item): boolean => item.value === user?.role)?.label || '',\n createdAt: format(new Date(user.createdAt), 'yyyy-MM-dd'),\n totalShots: user.totalShots,\n lastShot: user.lastShot ? format(new Date(user.lastShot), 'yyyy-MM-dd') : '-'\n })\n );\n setTableUsers(modifiedUsers);\n }, [users]);\n\n const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const handleRowClick = (user: TableUser): void => {\n history.push(`/bow-users/${user.id}`);\n };\n\n const generateActions = (\n record: TableUser\n ): { label: string; subLabel?: string; action: () => void }[] => {\n return [\n {\n label: `Shots`,\n subLabel: `(${record.totalShots})`,\n action: () => history.push(`/shots/${record.id}`)\n },\n {\n label: 'Sessions',\n action: () => history.push(`/bow-users/${record.id}/sessions`, { userId: record.id })\n },\n { label: 'Logs', action: () => history.push('/activity-log', { userId: record.id }) }\n ];\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Users' />\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input\n placeholder='Search'\n onChange={handleSearchInputChange}\n value={searchValue}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n columns={[\n ...USER_COLUMNS.map((obj): any => {\n return {\n ...obj,\n onCell: (record: TableUser): any => {\n return {\n onClick: (): void => handleRowClick(record)\n };\n }\n };\n }),\n {\n title: 'Actions',\n width: 270,\n render: (record): JSX.Element => (\n <Styled.TableActionRow>\n {generateActions(record).map((action, index) => (\n <Styled.TableAction key={`${action.label}_${index}`} onClick={action.action}>\n <Typography.Link>\n {action.label}\n {action.subLabel && <span className='subLabel'> {action.subLabel}</span>}\n </Typography.Link>\n </Styled.TableAction>\n ))}\n </Styled.TableActionRow>\n )\n }\n ]}\n dataSource={tableUsers}\n pagination={false}\n loading={isUsersLoading}\n size={'middle'}\n onChange={handleSortAction(setSortParams)}\n />\n </Styled.TableContainer>\n <PaginationContainer>\n <Pagination\n pageSize={pagination.pageSize}\n current={pagination.currentPage}\n total={pagination.totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default BowUsersPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","import React from 'react';\nimport { Link } from 'react-router-dom';\nimport { Checkbox, Tag, Tooltip } from 'antd';\nimport { TableSession } from './types';\n\nexport const SESSIONS_COLUMNS = [\n {\n title: '#',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n width: 50\n },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n width: 130\n },\n {\n title: 'Email',\n dataIndex: 'email',\n key: 'email',\n ellipsis: true,\n width: 220\n },\n {\n title: 'Name',\n dataIndex: 'name',\n key: 'name',\n width: 100,\n ellipsis: true\n },\n {\n title: 'Likes',\n dataIndex: 'likes',\n key: 'likes',\n width: 80,\n ellipsis: true\n },\n {\n title: 'Comments',\n dataIndex: 'comments',\n key: 'comments',\n width: 100,\n ellipsis: true,\n render: (commentsCount: number, record: TableSession) => {\n return commentsCount > 0 ? (\n <Link to={`/sessions/${record.id}/comments`}>\n <Tag color='green'>{commentsCount}</Tag>\n </Link>\n ) : (\n <Tag>{commentsCount}</Tag>\n );\n }\n },\n {\n title: 'Score',\n dataIndex: ['stats', 'score'],\n key: 'stats.score',\n ellipsis: true,\n width: 60\n },\n {\n title: 'Shots',\n dataIndex: ['stats', 'shots'],\n key: 'stats.shots',\n ellipsis: true,\n width: 60\n },\n {\n title: <Tooltip title='Shot Duration'>S.D.</Tooltip>,\n dataIndex: ['stats', 'shotDuration'],\n key: 'stats.shotDuration',\n ellipsis: true,\n width: 50\n },\n {\n title: <Tooltip title='Shot Level'>S.L.</Tooltip>,\n dataIndex: ['stats', 'shotLevel'],\n key: 'stats.shotLevel',\n ellipsis: true,\n width: 50\n },\n {\n title: <Tooltip title='Shot Steadiness'>S.S.</Tooltip>,\n dataIndex: ['stats', 'shotSteadiness'],\n key: 'stats.shotSteadiness',\n ellipsis: true,\n width: 70\n },\n {\n title: <Tooltip title='Shot Torque'>S.T.</Tooltip>,\n dataIndex: ['stats', 'shotTorque'],\n key: 'stats.shotTorque',\n ellipsis: true,\n width: 50\n },\n {\n title: 'Published',\n dataIndex: 'publishedAt',\n key: 'published',\n ellipsis: true,\n width: 90,\n render: (publishedAt: string) => <Checkbox checked={Boolean(publishedAt)} />\n },\n {\n title: 'Created At',\n dataIndex: 'createdAt',\n key: 'createdAt',\n ellipsis: true,\n width: 155\n }\n];\n","export const SHOTS_COLUMNS = [\n {\n title: 'Name',\n dataIndex: 'name',\n key: 'name',\n ellipsis: true,\n width: 120,\n },\n {\n title: 'Total Score',\n dataIndex: 'shotScoreTotal',\n key: 'shotScoreTotal',\n ellipsis: true,\n width: 100,\n },\n {\n title: 'Aim Steadiness',\n dataIndex: 'shotScoreAimSteadiness',\n key: 'shotScoreAimSteadiness',\n ellipsis: true,\n width: 140,\n },\n {\n title: 'Bow Angle',\n dataIndex: 'shotScoreBowAngle',\n key: 'shotScoreBowAngle',\n ellipsis: true,\n width: 100,\n },\n {\n title: 'Aim Time',\n dataIndex: 'shotScoreAimTime',\n key: 'shotScoreAimTime',\n ellipsis: true,\n width: 100,\n },\n {\n title: 'Bow Torque',\n dataIndex: 'shotScoreBowTorque',\n key: 'shotScoreBowTorque',\n ellipsis: true,\n width: 100,\n },\n {\n title: 'Valid',\n dataIndex: 'valid',\n key: 'valid',\n ellipsis: true,\n width: 60,\n },\n {\n title: 'Timestamp',\n dataIndex: 'timestamp',\n key: 'timestamp',\n ellipsis: true,\n width: 155,\n }\n];\n\nexport const ADVANCED_SHOTS_COLUMN = [\n ...SHOTS_COLUMNS,\n {\n title: 'Brand',\n dataIndex: ['userMetadata', 'deviceBrand'],\n key: 'userMetadata.deviceBrand',\n ellipsis: true,\n },\n {\n title: 'Model',\n dataIndex: ['userMetadata', 'deviceModel'],\n key: 'userMetadata.deviceModel',\n ellipsis: true,\n },\n {\n title: 'System Name',\n dataIndex: ['userMetadata', 'deviceSystemName'],\n key: 'userMetadata.deviceSystemName',\n ellipsis: true,\n },\n {\n title: 'System Version',\n dataIndex: ['userMetadata', 'deviceSystemVersion'],\n key: 'userMetadata.deviceSystemVersion',\n ellipsis: true,\n },\n {\n title: 'App Version',\n dataIndex: ['userMetadata', 'appVersion'],\n key: 'userMetadata.appVersion',\n ellipsis: true,\n },\n]\n","import React, { useEffect, useMemo } from 'react';\nimport { PageHeader, Table, Input, Typography } from 'antd';\nimport Pagination from 'antd/lib/pagination';\nimport * as Styled from './styles';\nimport { useSessions, useAppDispatch, useNotifications } from 'shared/hooks';\nimport { SESSIONS_COLUMNS } from './constants';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\nimport { PaginationContainer } from 'shared/styles';\nimport { format } from 'date-fns';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { ESnackbarStyle } from 'shared/types';\nimport { SHOTS_COLUMNS } from 'pages/user-shots-page/constants';\nimport { useHistory, useParams } from 'react-router-dom';\nimport { SessionShot, TableSession } from './types';\n\nconst BowUserSessionsPage = (): JSX.Element => {\n const history = useHistory();\n const { userId } = useParams<{ userId: string }>();\n\n const dispatch = useAppDispatch();\n const { openNotification } = useNotifications();\n\n const {\n sessions,\n pagination: { currentPage, pageSize, totalItemsCount },\n searchValue,\n isSessionsLoading,\n fetchSessions,\n removeSession,\n setSearchValue,\n onChangePagination\n } = useSessions();\n\n useEffect((): void => {\n fetchSessions({ userId: Number(userId) });\n }, [fetchSessions, userId]);\n\n const tableSessions: TableSession[] = useMemo(() => {\n return sessions.map(\n (session, index): TableSession => ({\n id: session.id,\n key: (currentPage - 1) * pageSize + (index + 1),\n createdAt: format(new Date(session.createdAt), 'yyyy-MM-dd HH:mm:ss'),\n name: session.sessionName,\n comments: session.comments.length,\n likes: session.likes.length,\n stats: {\n score: session.stats?.score,\n shots: session.stats?.shots,\n shotDuration: session.stats?.shotDuration,\n shotLevel: session.stats?.shotLevel,\n shotSteadiness: session.stats?.shotSteadiness,\n shotTorque: session.stats?.shotTorque\n },\n username: session.user.username,\n email: session.user.email,\n publishedAt: session.publishedAt,\n shots: (session.shots ?? []).map(\n (shot): SessionShot => ({\n name: shot.name,\n shotScoreTotal: shot.shotScoreTotal,\n shotScoreAimSteadiness: shot.shotScoreAimSteadiness,\n shotScoreBowAngle: shot.shotScoreBowAngle,\n shotScoreAimTime: shot.shotScoreAimTime,\n shotScoreBowTorque: shot.shotScoreBowTorque,\n valid: shot.isShotDetected ? 'True' : 'False',\n timestamp: format(new Date(shot.timestamp), 'yyyy-MM-dd HH:mm:ss')\n })\n )\n })\n );\n }, [sessions, currentPage, pageSize]);\n\n const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const handleRemoveSession = (session: TableSession): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this session?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeSession(session.id);\n await fetchSessions({ userId: Number(userId) });\n openNotification(ESnackbarStyle.SUCCESS, 'Session successfully deleted');\n }}\n />\n )\n );\n };\n\n const goBack = (): void => {\n history.goBack();\n };\n\n return (\n <ContentContainer containerStyle={{ maxWidth: '1350px' }}>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='User Sessions' />\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input\n placeholder='Search'\n onChange={handleSearchInputChange}\n value={searchValue}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n columns={[\n ...SESSIONS_COLUMNS,\n {\n title: 'Actions',\n width: 100,\n render: (record): JSX.Element => {\n return (\n <Typography.Link onClick={(): void => handleRemoveSession(record)}>\n Remove\n </Typography.Link>\n );\n }\n }\n ]}\n dataSource={tableSessions}\n pagination={false}\n loading={isSessionsLoading}\n size={'middle'}\n expandable={{\n expandedRowRender: (record): JSX.Element => (\n <Table\n columns={SHOTS_COLUMNS}\n dataSource={record.shots}\n pagination={false}\n loading={isSessionsLoading}\n />\n )\n }}\n />\n </Styled.TableContainer>\n <PaginationContainer>\n <Pagination\n pageSize={pageSize}\n current={currentPage}\n total={totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default BowUserSessionsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","import React from 'react';\nimport { Tooltip } from 'antd';\n\nexport const SESSIONS_COLUMNS = [\n {\n title: '#',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n width: 50,\n },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n width: 130,\n },\n {\n title: 'Email',\n dataIndex: 'email',\n key: 'email',\n ellipsis: true,\n width: 220\n },\n {\n title: 'Name',\n dataIndex: 'name',\n key: 'name',\n width: 100,\n ellipsis: true,\n },\n {\n title: 'Score',\n dataIndex: ['stats', 'score'],\n key: 'stats.score',\n ellipsis: true,\n width: 60\n },\n {\n title: 'Shots',\n dataIndex:['stats', 'shots'],\n key: 'stats.shots',\n ellipsis: true,\n width: 60\n },\n {\n title: <Tooltip title='Shot Duration'>S.D.</Tooltip>,\n dataIndex: ['stats', 'shotDuration'],\n key: 'stats.shotDuration',\n ellipsis: true,\n width: 50\n },\n {\n title: <Tooltip title='Shot Level'>S.L.</Tooltip>,\n dataIndex: ['stats', 'shotLevel'],\n key: 'stats.shotLevel',\n ellipsis: true,\n width: 50\n },\n {\n title: <Tooltip title='Shot Steadiness'>S.S.</Tooltip>,\n dataIndex: ['stats', 'shotSteadiness'],\n key: 'stats.shotSteadiness',\n ellipsis: true,\n width: 50\n },\n {\n title: <Tooltip title='Shot Torque'>S.T.</Tooltip>,\n dataIndex: ['stats', 'shotTorque'],\n key: 'stats.shotTorque',\n ellipsis: true,\n width: 50\n },\n {\n title: 'Created At',\n dataIndex: 'createdAt',\n key: 'createdAt',\n ellipsis: true,\n width: 155\n },\n];\n","import React, { useEffect, useState } from 'react';\nimport { PageHeader, Table, Input, Typography } from 'antd';\nimport Pagination from 'antd/lib/pagination';\nimport * as Styled from './styles';\nimport { useSessions, useAppDispatch, useNotifications } from 'shared/hooks';\nimport { SESSIONS_COLUMNS } from './constants';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\nimport { PaginationContainer } from 'shared/styles';\nimport { format } from 'date-fns';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { ESnackbarStyle } from 'shared/types';\nimport { SHOTS_COLUMNS } from 'pages/user-shots-page/constants';\n\ntype SessionStats = {\n score: number;\n shots: number;\n shotDuration: number;\n shotLevel: number;\n shotSteadiness: number;\n shotTorque: number;\n}\n\ntype SessionShot = {\n name: string;\n shotScoreTotal: number;\n shotScoreAimSteadiness: number;\n shotScoreBowAngle: number;\n shotScoreAimTime: number;\n shotScoreBowTorque: number;\n valid: string;\n timestamp: string;\n}\n\ntype TableSession = {\n id: string;\n key: number;\n createdAt: string;\n name: string;\n stats: SessionStats;\n username: string;\n email: string\n shots: SessionShot[];\n}\n\nconst SessionsPage = (): JSX.Element => {\n const [tableSessions, setTableSessions] = useState<TableSession[]>([]);\n const dispatch = useAppDispatch();\n const { openNotification } = useNotifications();\n\n const {\n sessions,\n pagination: { currentPage, pageSize, totalItemsCount },\n searchValue,\n isSessionsLoading,\n fetchSessions,\n removeSession,\n setSearchValue,\n onChangePagination\n } = useSessions();\n\n useEffect((): void => {\n fetchSessions();\n }, [fetchSessions]);\n\n useEffect((): void => {\n let i = (currentPage - 1) * pageSize;\n const modifiedSessions = sessions.map(\n (session): TableSession => {\n i += 1;\n return {\n id: session.id,\n key: i,\n createdAt: format(new Date(session.createdAt), 'yyyy-MM-dd HH:mm:ss'),\n name: session.sessionName,\n stats: {\n score: session.stats?.score,\n shots: session.stats?.shots,\n shotDuration: session.stats?.shotDuration,\n shotLevel: session.stats?.shotLevel,\n shotSteadiness: session.stats?.shotSteadiness,\n shotTorque: session.stats?.shotTorque,\n },\n username: session.user.username,\n email: session.user.email,\n shots: (session.shots ?? []).map((shot): SessionShot => ({\n name: shot.name,\n shotScoreTotal: shot.shotScoreTotal,\n shotScoreAimSteadiness: shot.shotScoreAimSteadiness,\n shotScoreBowAngle: shot.shotScoreBowAngle,\n shotScoreAimTime: shot.shotScoreAimTime,\n shotScoreBowTorque: shot.shotScoreBowTorque,\n valid: shot.isShotDetected ? 'True' : 'False',\n timestamp: format(new Date(shot.timestamp), 'yyyy-MM-dd HH:mm:ss'),\n }))\n }\n }\n );\n setTableSessions(modifiedSessions);\n }, [sessions, currentPage, pageSize]);\n\n const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const handleRemoveSession = (session: TableSession): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this session?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeSession(session.id);\n await fetchSessions();\n openNotification(ESnackbarStyle.SUCCESS, 'Session successfully deleted');\n }}\n />\n )\n );\n };\n\n // const handleRowClick = (session: TableSession): void => {\n // history.push(`/sessions/${session.id}/comments`);\n // };\n\n return (\n <ContentContainer containerStyle={{ maxWidth: '1350px' }}>\n <Styled.PageContainer>\n <PageHeader title='Sessions' />\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input\n placeholder='Search'\n onChange={handleSearchInputChange}\n value={searchValue}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n // onRow={(session): RowAction => ({ onClick: (): void => handleRowClick(session) })}\n columns={[\n ...SESSIONS_COLUMNS,\n {\n title: 'Actions',\n width: 100,\n render: (record): JSX.Element => {\n return (\n <Typography.Link onClick={(): void => handleRemoveSession(record)}>\n Remove\n </Typography.Link>\n );\n }\n }\n ]}\n dataSource={tableSessions}\n pagination={false}\n loading={isSessionsLoading}\n size={'middle'}\n expandable={{\n expandedRowRender: (record): JSX.Element => (\n <Table\n columns={SHOTS_COLUMNS}\n dataSource={record.shots}\n pagination={false}\n loading={isSessionsLoading}\n />\n )\n }}\n />\n </Styled.TableContainer>\n <PaginationContainer>\n <Pagination\n pageSize={pageSize}\n current={currentPage}\n total={totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default SessionsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const Form = styled.form`\n max-width: 480px;\n width: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nexport const FormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n\nexport const FormActions = styled.div`\n margin-top: 20px;\n display: flex;\n justify-content: space-between;\n`;\n\nexport const RemoveButton = styled.div`\n margin-top: 30px;\n width: max-content;\n\n & button {\n background: #f5222d;\n color: #fff;\n border-radius: 4px;\n transition: all .2s;\n }\n\n & button:hover {\n opacity: 0.8;\n background: #f5222d;\n color: #fff;\n border: 1px solid #fff;\n }\n`;\n","import React, { useEffect } from 'react';\nimport { ChangePasswordModal, ConfirmModal, ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { Button, Input, PageHeader, Select } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport { useFormik } from 'formik';\nimport { ROLES } from 'shared/constants/roles';\nimport { validation } from 'services/validation';\nimport { useAppDispatch, useNotifications, useUser } from 'shared/hooks';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { updateUser } from 'services/api/usersService';\nimport { ESnackbarStyle, EUserRole } from 'shared/types';\nimport { DeleteOutlined } from '@ant-design/icons';\nimport { getFieldError } from 'utils/error-utils';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { Redirect } from 'react-router-dom';\n\ntype FormValues = {\n firstName: string;\n lastName: string;\n role: EUserRole | undefined;\n email: string;\n};\n\ntype QueryParams = {\n userId: string;\n};\n\nconst EditUserPage = (): JSX.Element => {\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { userId } = useParams<QueryParams>();\n const { openNotification } = useNotifications();\n const { user, isUserLoading, fetchUser, removeUser } = useUser();\n\n useEffect((): void => {\n fetchUser(userId);\n }, [fetchUser, userId]);\n\n const initialValues: FormValues = {\n firstName: user?.firstName || '',\n lastName: user?.lastName || '',\n role: user?.role || undefined,\n email: user?.email || ''\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n try {\n await updateUser(userId, {\n firstName: values.firstName,\n lastName: values.lastName,\n email: values.email,\n role: values.role!\n });\n history.push('/users');\n openNotification(ESnackbarStyle.SUCCESS, 'User successfully updated');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n initialValues,\n validationSchema: validation.EDIT_USER,\n enableReinitialize: true\n });\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const showRemoveUserModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this user?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeUser(userId);\n history.push('/users');\n openNotification(ESnackbarStyle.SUCCESS, 'User successfully deleted');\n }}\n />\n )\n );\n };\n\n const handleSelectFieldChange =\n (fieldName: string): ((value: string) => void) =>\n (value: string): void => {\n formik.setFieldValue(fieldName, value);\n };\n\n const showChangePasswordModal = (): void => {\n dispatch(showModal(<ChangePasswordModal userId={userId} />));\n };\n\n if (\n user?.role &&\n !checkRolePermission(\n [EUserRole.master_admin, EUserRole.admin_user, EUserRole.support_user, EUserRole.moderator],\n user.role\n )\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Edit user' />\n <Styled.Form onSubmit={formik.handleSubmit}>\n <Styled.FormInputContainer>\n <Input\n placeholder='First name'\n size='large'\n value={formik.values.firstName}\n name='firstName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isUserLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'firstName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Last name'\n size='large'\n value={formik.values.lastName}\n name='lastName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isUserLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'lastName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Select\n size='large'\n placeholder='Role'\n value={formik.values.role}\n style={{ width: '100%' }}\n onChange={handleSelectFieldChange('role')}\n allowClear\n disabled={isUserLoading || formik.isSubmitting}\n >\n {ROLES.map(\n (item): JSX.Element => (\n <Select.Option key={item.value} value={item.value}>\n {item.label}\n </Select.Option>\n )\n )}\n </Select>\n {getFieldError(formik, 'role')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Email'\n size='large'\n value={formik.values.email}\n name='email'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isUserLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'email')}\n </Styled.FormInputContainer>\n <Styled.FormActions>\n <Button\n type='primary'\n htmlType='button'\n onClick={showChangePasswordModal}\n disabled={isUserLoading || formik.isSubmitting}\n >\n Change password\n </Button>\n <Button\n type='primary'\n htmlType='submit'\n disabled={isUserLoading || formik.isSubmitting || !formik.dirty}\n loading={formik.isSubmitting}\n >\n Apply\n </Button>\n </Styled.FormActions>\n <Styled.RemoveButton>\n <Button\n icon={<DeleteOutlined />}\n type='default'\n onClick={showRemoveUserModal}\n disabled={isUserLoading || formik.isSubmitting}\n >\n Remove user\n </Button>\n </Styled.RemoveButton>\n </Styled.Form>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default EditUserPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const Form = styled.form`\n max-width: 480px;\n width: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nexport const FormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n\nexport const Img = styled.div`\n height: 350px;\n width: auto;\n padding: 16px 0;\n\n img {\n max-height: 100%;\n }\n`;\n\nexport const FormActions = styled.div`\n margin-top: 20px;\n display: flex;\n justify-content: space-between;\n`;\n\nexport const RemoveButton = styled.div`\n width: max-content;\n\n & button {\n background: #f5222d;\n color: #fff;\n border-radius: 4px;\n transition: all .2s;\n }\n\n & button:hover {\n opacity: 0.8;\n background: #f5222d;\n color: #fff;\n border: 1px solid #fff;\n }\n`;\n","import React, { useEffect } from 'react';\nimport { ChangePasswordModal, ConfirmModal, ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { Button, Input, PageHeader, Select, Upload } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport { useFormik } from 'formik';\nimport { ROLES } from 'shared/constants/roles';\nimport { validation } from 'services/validation';\nimport { useAppDispatch, useNotifications, useUser } from 'shared/hooks';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { activateUserAccount, updateBowUser } from 'services/api/usersService';\nimport { ESnackbarStyle, EUserRole } from 'shared/types';\nimport { DeleteOutlined, UploadOutlined } from '@ant-design/icons';\nimport { getFieldError } from 'utils/error-utils';\nimport { RcFile, UploadChangeParam } from 'antd/lib/upload';\nimport { UploadFile } from 'antd/lib/upload/interface';\n\ntype FormValues = {\n firstName: string;\n lastName: string;\n role: EUserRole | undefined;\n email: string;\n image: RcFile | null;\n};\n\ntype QueryParams = {\n userId: string;\n};\n\nconst EditUserPage = (): JSX.Element => {\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { userId } = useParams<QueryParams>();\n const { openNotification } = useNotifications();\n const { user, setUser, isUserLoading, fetchUser, removeUser } = useUser();\n\n useEffect((): void => {\n fetchUser(userId);\n }, [fetchUser, userId]);\n\n const initialValues: FormValues = {\n firstName: user?.firstName || '',\n lastName: user?.lastName || '',\n role: user?.role || undefined,\n email: user?.email || '',\n image: null\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n try {\n const formData = new FormData();\n\n formData.append('firstName', values.firstName);\n formData.append('lastName', values.lastName);\n formData.append('email', values.email);\n formData.append('role', values.role!);\n if (values.image) {\n formData.append('image', values.image!);\n }\n\n await updateBowUser(userId, formData);\n history.push('/bow-users');\n openNotification(ESnackbarStyle.SUCCESS, 'User successfully updated');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n initialValues,\n validationSchema: validation.EDIT_USER,\n enableReinitialize: true\n });\n\n const { values, setFieldValue } = formik;\n\n const handleImageChange = (file: UploadChangeParam<UploadFile<File>>): void => {\n if (file?.fileList[0]) {\n setFieldValue('image', file.fileList[0].originFileObj);\n } else {\n setFieldValue('image', null);\n }\n };\n\n const handleChangeUserStatus = async (status: 'active' | 'disabled'): Promise<void> => {\n try {\n const formData = new FormData();\n formData.append('status', status);\n const res = await updateBowUser(userId, formData);\n setUser(res.data);\n openNotification(ESnackbarStyle.SUCCESS, 'User status has been changed successfully');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n };\n\n const handleActivateUserAccount = async (userId: string): Promise<void> => {\n try {\n const res = await activateUserAccount(userId);\n setUser(res.data);\n openNotification(ESnackbarStyle.SUCCESS, 'User account has been activated successfully');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }\n\n const goBack = (): void => {\n // Get the current location\n const currentLocation = history.location;\n\n // Check if there's a previous location in the state\n const prevLocation = (currentLocation.state as Record<string, string>)?.from;\n\n if (prevLocation) {\n // Navigate to the previous location with useLastSearchState\n history.replace({\n pathname: prevLocation,\n state: {\n useLastSearchState: true\n }\n });\n } else {\n // If no previous location, fallback to history.goBack()\n history.goBack();\n }\n };\n\n const showRemoveUserModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this user?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeUser(userId);\n history.push('/users');\n openNotification(ESnackbarStyle.SUCCESS, 'User successfully deleted');\n }}\n />\n )\n );\n };\n\n const handleSelectFieldChange =\n (fieldName: string): ((value: string) => void) =>\n (value: string): void => {\n formik.setFieldValue(fieldName, value);\n };\n\n const showChangePasswordModal = (): void => {\n dispatch(showModal(<ChangePasswordModal userId={userId} />));\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Edit user' />\n <Styled.Form onSubmit={formik.handleSubmit}>\n {user?.profilePictureS3Url && (\n <Styled.Img>\n <img src={user?.profilePictureS3Url} alt={''} />\n </Styled.Img>\n )}\n <Styled.FormInputContainer>\n <Upload\n name='image'\n fileList={values.image ? [values.image] : []}\n onChange={handleImageChange}\n beforeUpload={(): boolean => false}\n >\n <Button icon={<UploadOutlined />}>Choose file</Button>\n </Upload>\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='First name'\n size='large'\n value={formik.values.firstName}\n name='firstName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isUserLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'firstName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Last name'\n size='large'\n value={formik.values.lastName}\n name='lastName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isUserLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'lastName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input placeholder='Username' size='large' value={user?.username || ''} disabled />\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Select\n size='large'\n placeholder='Role'\n value={formik.values.role}\n style={{ width: '100%' }}\n onChange={handleSelectFieldChange('role')}\n allowClear\n disabled={isUserLoading || formik.isSubmitting}\n >\n {ROLES.map(\n (item): JSX.Element => (\n <Select.Option key={item.value} value={item.value}>\n {item.label}\n </Select.Option>\n )\n )}\n </Select>\n {getFieldError(formik, 'role')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Email'\n size='large'\n value={formik.values.email}\n name='email'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isUserLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'email')}\n </Styled.FormInputContainer>\n <Styled.FormActions>\n <Button\n type='primary'\n htmlType='button'\n onClick={showChangePasswordModal}\n disabled={isUserLoading || formik.isSubmitting}\n >\n Change password\n </Button>\n <Button\n type='primary'\n htmlType='submit'\n disabled={isUserLoading || formik.isSubmitting || !formik.dirty}\n loading={formik.isSubmitting}\n >\n Apply\n </Button>\n </Styled.FormActions>\n <Styled.FormActions>\n <Button\n type='primary'\n htmlType='button'\n onClick={(): Promise<void> =>\n handleChangeUserStatus(user?.status === 'active' ? 'disabled' : 'active')\n }\n disabled={isUserLoading || formik.isSubmitting || !user}\n >\n {user?.status === 'active' ? 'Lock Account' : 'Unlock Account'}\n </Button>\n {user?.status === 'new' && (\n <Button\n type='primary'\n htmlType='button'\n onClick={(): Promise<void> => handleActivateUserAccount(userId)}\n disabled={isUserLoading || formik.isSubmitting || !user}\n >\n Activate Account\n </Button>\n )}\n </Styled.FormActions>\n <Styled.FormActions>\n <Styled.RemoveButton>\n <Button\n icon={<DeleteOutlined />}\n type='default'\n onClick={showRemoveUserModal}\n disabled={isUserLoading || formik.isSubmitting}\n >\n Remove user\n </Button>\n </Styled.RemoveButton>\n </Styled.FormActions>\n </Styled.Form>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default EditUserPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n padding-bottom: 50px;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const HeaderDateForm = styled.form`\n display: flex;\n margin-top: 30px;\n\n & > button {\n margin-left: 30px;\n }\n`;\n\nexport const DiagramContainer = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n height: 250px;\n\n @media (max-width: 530px) {\n height: 370px;\n padding-top: 30px;\n }\n`;\n\nexport const DatePickersContainer = styled.div`\n display: flex;\n\n & > div,\n input {\n cursor: pointer;\n }\n\n & > div:last-child {\n margin-left: 20px;\n }\n`;\n\nexport const ShotTableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n\nexport const TableContainer = styled.div`\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n\nexport const ExportButtonContainer = styled.div`\n margin-top: 24px;\n\n button {\n width: min-content;\n }\n`;\n","export const SHOT_COLUMNS = [\n {\n title: 'Shot #',\n dataIndex: 'shotNumber',\n key: 'shotNumber',\n sortKey: 'shotNumber',\n ellipsis: true,\n sorter: {\n multiple: 1\n },\n width: 100\n },\n {\n title: 'Date',\n dataIndex: 'timestamp',\n key: 'timestamp',\n sortKey: 'timestamp',\n ellipsis: true,\n sorter: {\n multiple: 1\n },\n width: 150\n },\n {\n title: 'Bow mode',\n dataIndex: 'deviceMode',\n key: 'deviceMode',\n sortKey: 'deviceMode',\n ellipsis: true,\n sorter: {\n multiple: 1\n },\n width: 140\n },\n {\n title: 'GPS location',\n dataIndex: 'gpsLocation',\n key: 'gpsLocation',\n sortKey: 'shot.location.lat',\n ellipsis: true,\n width: 170\n },\n {\n title: 'Shot status',\n dataIndex: 'shotQuality',\n key: 'shotQuality',\n sortKey: 'shotQuality',\n ellipsis: true,\n sorter: {\n multiple: 1\n },\n width: 120\n },\n {\n title: 'Registered',\n dataIndex: 'registered',\n key: 'registered',\n ellipsis: true,\n width: 150\n },\n {\n title: 'Score',\n dataIndex: 'shotScore',\n key: 'shotScore',\n ellipsis: true,\n sortKey: 'shotScore',\n width: 80,\n sorter: {\n multiple: 1\n }\n },\n {\n title: 'Archived',\n dataIndex: 'archived',\n key: 'archived',\n sortKey: 'archived',\n ellipsis: true,\n sorter: {\n multiple: 1\n }\n }\n];\n\nexport const EVENT_COLUMNS = [\n {\n title: 'Event',\n dataIndex: 'eventType',\n key: 'eventType',\n sortKey: 'eventType',\n ellipsis: true,\n sorter: {\n multiple: 1\n },\n width: 100\n },\n {\n title: 'Date',\n dataIndex: 'timestamp',\n key: 'timestamp',\n sortKey: 'timestamp',\n sorter: {\n multiple: 1\n },\n ellipsis: true\n }\n];\n","export const modifyKeyToString = (value: string): string =>\n value.replace(value[0], value[0].toUpperCase()).split('_').join(' ');\n","import React, { useEffect, useState } from 'react';\nimport { Button, DatePicker, PageHeader, Table, Pagination, Collapse } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { useFormik } from 'formik';\nimport { SHOT_COLUMNS, EVENT_COLUMNS } from './constants';\nimport moment from 'moment';\nimport { useEventsData, useNotifications, useShotsData } from 'shared/hooks';\nimport { modifyKeyToString } from 'utils/string-modifier-utils';\nimport { PaginationContainer } from 'shared/styles';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { handleSortAction } from 'utils/sorting-utils';\nimport { downloadDeviceData } from 'services/api/devicesService';\nimport { ESnackbarStyle } from 'shared/types';\nimport { ExportOutlined } from '@ant-design/icons';\n\ntype TableShot = {\n key: number;\n shotNumber: number;\n timestamp: string;\n deviceMode: string;\n gpsLocation: string;\n shotQuality: string;\n registered: string;\n shotScore: string;\n archived: string;\n};\n\ntype TableEvent = {\n key: number;\n eventType: string;\n timestamp: string;\n};\n\ntype FormValues = {\n startDate: string | null;\n endDate: string | null;\n};\n\nconst BowDetailsPage = (): JSX.Element => {\n const { bowSerialNumber } = useParams<{ bowSerialNumber: string }>();\n const {\n fetchDeviceShots,\n requestShotsParams,\n setRequestShotsParams,\n shots,\n totalShots,\n setShotsSortParams,\n isShotsLoading\n } = useShotsData(bowSerialNumber);\n const {\n fetchDeviceEvents,\n requestEventsParams,\n setRequestEventsParams,\n events,\n totalEvents,\n setEventsSortParams,\n isEventsLoading\n } = useEventsData(bowSerialNumber);\n const { openNotification } = useNotifications();\n const history = useHistory();\n const { Panel } = Collapse;\n const [tableShots, setTableShots] = useState<TableShot[]>([]);\n const [tableEvents, setTableEvents] = useState<TableEvent[]>([]);\n\n useEffect((): void => {\n fetchDeviceShots();\n }, [fetchDeviceShots]);\n\n useEffect((): void => {\n fetchDeviceEvents();\n }, [fetchDeviceEvents]);\n\n useEffect((): void => {\n const modifiedShots = shots.map(\n (shot): TableShot => ({\n key: shot.id,\n shotNumber: shot.shotNumber,\n timestamp: moment(shot.timestamp).format('YYYY-MM-DD HH:mm:ss'),\n deviceMode: modifyKeyToString(shot.deviceMode),\n gpsLocation: `${shot.location?.lat}, ${shot.location?.lon}`,\n shotQuality: modifyKeyToString(shot.shotQuality),\n registered: moment(shot.timestamp).format('YYYY-MM-DD HH:mm:ss'),\n shotScore: shot.shotScore,\n archived: shot.archived\n })\n );\n setTableShots(modifiedShots);\n }, [shots]);\n\n useEffect((): void => {\n const modifiedEvents = events.map(\n (shot): TableEvent => ({\n key: shot.id,\n eventType: modifyKeyToString(shot.eventType),\n timestamp: moment(shot.timestamp).format('YYYY-MM-DD HH:mm:ss')\n })\n );\n setTableEvents(modifiedEvents);\n }, [events]);\n\n const initialValues: FormValues = {\n startDate: null,\n endDate: null\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n const { startDate, endDate } = values;\n const start = moment(startDate).toISOString();\n const end = moment(endDate).toISOString();\n setRequestShotsParams({ dateRange: { start, end }, currentPage: 1 });\n setRequestEventsParams({ dateRange: { start, end }, currentPage: 1 });\n },\n initialValues\n });\n\n const { startDate, endDate } = formik.values;\n\n const handleDateChange = (date: string, isStartDate: boolean): void => {\n formik.setFieldValue(isStartDate ? 'startDate' : 'endDate', date);\n if (!date) {\n setRequestShotsParams({ dateRange: { start: null, end: null }, currentPage: 1 });\n setRequestEventsParams({ dateRange: { start: null, end: null }, currentPage: 1 });\n }\n };\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const handleExportButtonClick = async (): Promise<void> => {\n try {\n const response = await downloadDeviceData(bowSerialNumber);\n const fileName =\n response.headers['content-disposition'].split('filename=')[1].slice(1, -1) ||\n 'firmware.xls';\n const url = window.URL.createObjectURL(new Blob([response.data]));\n const a = document.createElement('a');\n a.href = url;\n a.download = fileName;\n a.click();\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title={`Bow details #${bowSerialNumber}`} />\n <Styled.HeaderDateForm onSubmit={formik.handleSubmit}>\n <Styled.DatePickersContainer>\n <DatePicker\n name={'startDate'}\n value={startDate ? moment(startDate) : null}\n onChange={(date, dateString): void => handleDateChange(dateString, true)}\n size='small'\n disabledDate={(current): boolean => current >= moment(endDate)}\n placeholder='Start date'\n inputReadOnly={true}\n />\n <DatePicker\n name={'endingDate'}\n value={endDate ? moment(endDate) : null}\n onChange={(date, dateString): void => handleDateChange(dateString, false)}\n size='small'\n disabledDate={(current): boolean => current <= moment(startDate)}\n placeholder='End date'\n inputReadOnly={true}\n />\n </Styled.DatePickersContainer>\n <Button\n type='primary'\n htmlType='submit'\n disabled={!(startDate && endDate) || formik.isSubmitting}\n >\n Apply\n </Button>\n </Styled.HeaderDateForm>\n <Styled.ShotTableContainer>\n <Collapse defaultActiveKey={['1']} ghost>\n <Panel header='Shots' key='1'>\n <Table\n columns={SHOT_COLUMNS}\n dataSource={tableShots}\n pagination={false}\n size={'middle'}\n loading={isShotsLoading}\n onChange={handleSortAction(setShotsSortParams)}\n />\n {totalShots > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={requestShotsParams.currentPage}\n total={totalShots}\n onChange={(page: number): void =>\n setRequestShotsParams({ ...requestShotsParams, currentPage: page })\n }\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Panel>\n </Collapse>\n </Styled.ShotTableContainer>\n <Styled.TableContainer>\n <Collapse defaultActiveKey={['2']} ghost>\n <Panel header='Events' key='2'>\n <Table\n columns={EVENT_COLUMNS}\n dataSource={tableEvents}\n pagination={false}\n size={'middle'}\n loading={isEventsLoading}\n onChange={handleSortAction(setEventsSortParams)}\n />\n {totalEvents > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={requestEventsParams.currentPage}\n total={totalEvents}\n onChange={(page: number): void =>\n setRequestEventsParams({ ...requestEventsParams, currentPage: page })\n }\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Panel>\n </Collapse>\n </Styled.TableContainer>\n <Styled.ExportButtonContainer>\n <Button icon={<ExportOutlined />} type='primary' onClick={handleExportButtonClick}>\n Export\n </Button>\n </Styled.ExportButtonContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default BowDetailsPage;\n","import styled from 'styled-components';\nimport { DEVICE } from 'shared/constants/deviceSizes';\nimport { Button, Select } from 'antd';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const CheckboxContainer = styled.div`\n padding-top: 30px;\n padding-left: 5px;\n`;\n\nexport const TableContainer = styled.div`\n flex: 1;\n margin-top: 24px;\n overflow-x: auto;\n\n & table {\n max-width: unset;\n width: unset;\n min-width: 100%;\n }\n\n & tbody tr {\n cursor: pointer;\n }\n\n & thead tr th {\n max-width: 600px;\n\n @media ${DEVICE.tablet} {\n max-width: 600px;\n }\n }\n\n & tbody tr td {\n max-width: 600px;\n\n @media ${DEVICE.tablet} {\n max-width: 600px;\n }\n }\n`;\n\nexport const TypeRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n\nexport const LogActions = styled.div`\n display: flex;\n margin-bottom: 16px;\n`;\n\nexport const LogSelect = styled(Select)`\n width: 300px;\n`;\n\nexport const LogAction = styled(Button)`\n margin-left: 20px;\n background: #ff4f4f;\n border-color: #ff4f4f;\n\n &:hover {\n background: #ff4f4f;\n border-color: #ff4f4f;\n opacity: 0.8;\n }\n`;\n","import { LogType } from '../shared/types';\n\nexport const getLogColor = (type: LogType): string =>\n ({ warning: '#ffa600', error: '#f5222d', debug: '#144a5c', info: 'rgba(0, 0, 0, 0.26)' }[type]);\n","import { ReactNode } from 'react';\nimport { TypeRow } from './styles';\nimport { LogType } from 'shared/types';\nimport { getLogColor } from 'utils/log-utils';\nimport { parseISODateFormat } from '../../utils/date-utils';\n\nexport const ACTIVITY_LOG_COLUMNS = [\n {\n title: 'Timestamp',\n dataIndex: 'timestamp',\n key: 'timestamp',\n ellipsis: true,\n render: (date: string): ReactNode => {\n return <>{parseISODateFormat(date, true)}</>\n }\n },\n {\n title: 'Type',\n dataIndex: 'type',\n key: 'type',\n ellipsis: true,\n render: (type: LogType): ReactNode => {\n return <TypeRow color={getLogColor(type)}>{type.toUpperCase()}</TypeRow>\n },\n },\n {\n title: 'Title',\n dataIndex: 'title',\n key: 'title',\n ellipsis: true,\n },\n {\n title: 'Data',\n dataIndex: 'data',\n key: 'data',\n ellipsis: true,\n },\n {\n title: 'Username',\n dataIndex: ['user', 'username'],\n key: 'username',\n ellipsis: true,\n },\n {\n title: 'Email',\n dataIndex: ['user', 'email'],\n key: 'email',\n ellipsis: true,\n },\n {\n title: 'Brand',\n dataIndex: 'deviceBrand',\n key: 'deviceBrand',\n ellipsis: true,\n },\n {\n title: 'Model',\n dataIndex: 'deviceModel',\n key: 'deviceModel',\n ellipsis: true,\n },\n {\n title: 'System Name',\n dataIndex: 'deviceSystemName',\n key: 'deviceSystemName',\n ellipsis: true,\n },\n {\n title: 'System Version',\n dataIndex: 'deviceSystemVersion',\n key: 'deviceSystemVersion',\n ellipsis: true,\n },\n];\n","import React, { useEffect, useMemo } from 'react';\nimport { useAppDispatch, useLogs, useNotifications } from 'shared/hooks';\nimport { ESnackbarStyle, Log, LogType } from 'shared/types';\nimport { useHistory, useLocation } from 'react-router';\nimport { Input, PageHeader, Pagination, Table, Checkbox } from 'antd';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { LOGS_PAGE_SIZE } from 'shared/constants/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { ACTIVITY_LOG_COLUMNS } from './constants';\nimport _ from 'lodash';\nimport { closeModal, showModal } from '../../services/store/reducers/modalReducer';\nimport { deleteUserLogs } from '../../services/api/logService';\n\ntype LocationState = {\n userId: number;\n};\n\ntype TableLog = Log & { key: number };\n\ntype Option = {\n value: string;\n label: string;\n};\n\ntype RowAction = {\n onClick: () => void;\n};\n\nconst ActivityLogPage = (): JSX.Element => {\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { state: { userId } = {} } = useLocation<LocationState>();\n const { openNotification } = useNotifications();\n\n const {\n items,\n pagination,\n isLogsLoading,\n currentPage,\n inputSearch,\n setType,\n setInputSearch,\n setCurrentPage,\n fetchLogs,\n handleChangeSearch,\n isAutoUpdate,\n setIsAutoUpdate\n } = useLogs({ userId });\n\n useEffect((): void => {\n fetchLogs();\n }, [fetchLogs]);\n\n useEffect((): any => {\n if (isAutoUpdate) {\n const interval = setInterval((): void => {\n fetchLogs(false);\n }, 1000);\n\n return (): void => clearInterval(interval);\n }\n }, [isAutoUpdate, fetchLogs]);\n\n const tableLogs = useMemo(\n (): TableLog[] => items.map((log): TableLog => ({ ...log, key: log.id })),\n [items]\n );\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const handleRowClick = (log: TableLog): void => {\n history.push(`/activity-log/${log.id}`);\n };\n\n const showRemoveUserLogsModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove user logs?'\n confirmAction={async (): Promise<void> => {\n try {\n dispatch(closeModal());\n await deleteUserLogs(`${userId}`);\n history.goBack();\n openNotification(ESnackbarStyle.SUCCESS, 'User logs successfully deleted');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }}\n />\n )\n );\n };\n\n return (\n <ContentContainer containerStyle={{ maxWidth: 'unset', maxHeight: '100vh' }}>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Activity Log' />\n <Styled.LogActions>\n <Styled.LogSelect\n defaultValue=''\n onChange={(value): void => setType((value as LogType) || undefined)}\n options={['', 'warning', 'error', 'debug', 'info'].map(\n (value): Option => ({\n value,\n label: value ? _.capitalize(value) : 'All'\n })\n )}\n />\n <Styled.LogAction type='primary' onClick={showRemoveUserLogsModal} color='#FF4F4F'>\n Remove User Logs\n </Styled.LogAction>\n </Styled.LogActions>\n <Input\n value={inputSearch}\n onChange={(e): void => {\n setInputSearch(e.target.value);\n handleChangeSearch(e.target.value);\n }}\n size='large'\n placeholder='User info'\n />\n <Styled.CheckboxContainer>\n <Checkbox\n checked={isAutoUpdate}\n onChange={(e): void => setIsAutoUpdate(e.target.checked)}\n >\n Auto Update\n </Checkbox>\n </Styled.CheckboxContainer>\n <Styled.TableContainer>\n <Table\n onRow={(log: TableLog): RowAction => ({\n onClick: (): void => handleRowClick(log)\n })}\n columns={ACTIVITY_LOG_COLUMNS}\n dataSource={tableLogs}\n loading={isLogsLoading}\n pagination={false}\n size={'middle'}\n />\n </Styled.TableContainer>\n {pagination.totalItemsCount > LOGS_PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={pagination.totalItemsCount}\n onChange={setCurrentPage}\n pageSize={LOGS_PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default ActivityLogPage;\n","import styled from 'styled-components';\nimport { DEVICE } from 'shared/constants/deviceSizes';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const CheckboxContainer = styled.div`\n padding-top: 30px;\n padding-left: 5px;\n`;\n\nexport const TableContainer = styled.div`\n flex: 1;\n margin-top: 24px;\n overflow-x: auto;\n\n & table {\n max-width: unset;\n width: unset;\n min-width: 100%;\n }\n\n & tbody tr {\n cursor: pointer;\n }\n\n & thead tr th {\n max-width: 600px;\n\n @media ${DEVICE.tablet} {\n max-width: 600px;\n }\n }\n\n & tbody tr td {\n max-width: 600px;\n\n @media ${DEVICE.tablet} {\n max-width: 600px;\n }\n }\n`;\n\nexport const TypeRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n","import { ReactNode } from 'react';\nimport { TypeRow } from './styles';\nimport { LogType } from 'shared/types';\nimport { getLogColor } from 'utils/log-utils';\nimport { parseISODateFormat } from '../../utils/date-utils';\n\nexport const ACTIVITY_LOG_COLUMNS = [\n {\n title: 'Timestamp',\n dataIndex: 'timestamp',\n key: 'timestamp',\n ellipsis: true,\n render: (date: string): ReactNode => {\n return <>{parseISODateFormat(date, true)}</>\n }\n },\n {\n title: 'Type',\n dataIndex: 'type',\n key: 'type',\n ellipsis: true,\n render: (type: LogType): ReactNode => {\n return <TypeRow color={getLogColor(type)}>{type.toUpperCase()}</TypeRow>\n },\n },\n {\n title: 'Title',\n dataIndex: 'title',\n key: 'title',\n ellipsis: true,\n },\n {\n title: 'Data',\n dataIndex: 'data',\n key: 'data',\n ellipsis: true,\n },\n {\n title: 'Username',\n dataIndex: ['username'],\n key: 'username',\n ellipsis: true,\n },\n {\n title: 'Brand',\n dataIndex: 'deviceBrand',\n key: 'deviceBrand',\n ellipsis: true,\n },\n {\n title: 'Model',\n dataIndex: 'deviceModel',\n key: 'deviceModel',\n ellipsis: true,\n },\n {\n title: 'System Name',\n dataIndex: 'deviceSystemName',\n key: 'deviceSystemName',\n ellipsis: true,\n },\n {\n title: 'System Version',\n dataIndex: 'deviceSystemVersion',\n key: 'deviceSystemVersion',\n ellipsis: true,\n },\n];\n","import React, { useEffect, useMemo } from 'react';\nimport { useLogs } from 'shared/hooks';\nimport { Log } from 'shared/types';\nimport { useHistory } from 'react-router';\nimport { Input, PageHeader, Pagination, Table, Checkbox } from 'antd';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { LOGS_PAGE_SIZE } from 'shared/constants/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { ACTIVITY_LOG_COLUMNS } from './constants';\n\ntype TableLog = Log & { key: number };\n\ntype RowAction = {\n onClick: () => void;\n};\n\nconst ExActivityLogPage = (): JSX.Element => {\n const {\n items,\n pagination,\n isLogsLoading,\n currentPage,\n inputSearch,\n setInputSearch,\n setCurrentPage,\n fetchLogs,\n handleChangeSearch,\n isAutoUpdate,\n setIsAutoUpdate\n } = useLogs({logsType: 'ex-'});\n const history = useHistory();\n\n useEffect((): void => {\n fetchLogs();\n }, [fetchLogs]);\n\n useEffect((): any => {\n if (isAutoUpdate) {\n const interval = setInterval((): void => {\n fetchLogs(false);\n }, 1000);\n\n return (): void => clearInterval(interval);\n }\n }, [isAutoUpdate, fetchLogs]);\n\n const tableLogs = useMemo(\n (): TableLog[] => items.map((log): TableLog => ({ ...log, key: log.id })),\n [items]\n );\n\n const handleRowClick = (log: TableLog): void => {\n history.push(`/ex-activity-log/${log.id}`);\n };\n\n return (\n <ContentContainer containerStyle={{ maxWidth: 'unset', maxHeight: '100vh' }}>\n <Styled.PageContainer>\n <PageHeader title='External Activity Log' />\n <Input\n value={inputSearch}\n onChange={(e): void => {\n setInputSearch(e.target.value);\n handleChangeSearch(e.target.value);\n }}\n size='large'\n placeholder='User info'\n />\n <Styled.CheckboxContainer>\n <Checkbox checked={isAutoUpdate} onChange={(e): void => setIsAutoUpdate(e.target.checked)}>\n Auto Update\n </Checkbox>\n </Styled.CheckboxContainer>\n <Styled.TableContainer>\n <Table\n onRow={(log: TableLog): RowAction => ({\n onClick: (): void => handleRowClick(log)\n })}\n columns={ACTIVITY_LOG_COLUMNS}\n dataSource={tableLogs}\n loading={isLogsLoading}\n pagination={false}\n size={'middle'}\n />\n </Styled.TableContainer>\n {pagination.totalItemsCount > LOGS_PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={pagination.totalItemsCount}\n onChange={setCurrentPage}\n pageSize={LOGS_PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default ExActivityLogPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n\n & tbody tr td {\n vertical-align: top;\n }\n`;\n\nexport const TableContainer = styled.div`\n flex: 1;\n margin-top: 24px;\n overflow-y: auto;\n`;\n\nexport const TypeRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n\nexport const DataRow = styled.div`\n max-height: 350px;\n overflow: auto;\n`\n","export const LOG_COLUMNS = [\n {\n title: 'Key',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n },\n {\n title: 'Value',\n dataIndex: 'value',\n key: 'value',\n ellipsis: false,\n },\n];\n","import React, { ReactNode, useEffect, useMemo } from 'react';\nimport { PageHeader, Table } from 'antd';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { useHistory, useParams } from 'react-router';\nimport { useLog } from 'shared/hooks';\nimport { LOG_COLUMNS } from './constants';\nimport { getLogColor } from 'utils/log-utils';\nimport { parseISODateFormat } from '../../utils/date-utils';\n\ntype TableLog = {\n key: string;\n value: string | ReactNode;\n};\n\nconst LogDetailsPage = (): JSX.Element => {\n const { logId } = useParams<{ logId: string }>();\n\n const { log, fetchLog, isLogLoading } = useLog(logId);\n const history = useHistory();\n\n useEffect((): void => {\n fetchLog();\n }, [fetchLog]);\n\n const tableLogs = useMemo((): TableLog[] => {\n if (!log) return [];\n const {\n title,\n data,\n type,\n timestamp,\n user: { username, email },\n deviceBrand,\n deviceModel,\n deviceSystemName,\n deviceSystemVersion\n } = log;\n return [\n { key: 'Timestamp', value: parseISODateFormat(timestamp, true) },\n {\n key: 'Type',\n value: <Styled.TypeRow color={getLogColor(type)}>{type.toUpperCase()}</Styled.TypeRow>\n },\n { key: 'Title', value: title },\n { key: 'Data', value: <Styled.DataRow>{data}</Styled.DataRow> },\n { key: 'Username', value: username },\n { key: 'Email', value: email },\n { key: 'Brand', value: deviceBrand },\n { key: 'Model', value: deviceModel },\n { key: 'System Name', value: deviceSystemName },\n { key: 'System Version', value: deviceSystemVersion }\n ];\n }, [log]);\n\n const goBack = (): void => {\n history.goBack();\n };\n\n return (\n <ContentContainer containerStyle={{ maxHeight: '100vh', minHeight: 'unset' }}>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title={`Log details #${logId}`} />\n <Styled.TableContainer>\n <Table\n columns={LOG_COLUMNS}\n dataSource={tableLogs}\n loading={isLogLoading}\n pagination={false}\n size={'middle'}\n />\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default LogDetailsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n\n & tbody tr td {\n vertical-align: top;\n }\n`;\n\nexport const TableContainer = styled.div`\n flex: 1;\n margin-top: 24px;\n overflow-y: auto;\n`;\n\nexport const TypeRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n\nexport const DataRow = styled.div`\n max-height: 350px;\n overflow: auto;\n`\n","export const LOG_COLUMNS = [\n {\n title: 'Key',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n },\n {\n title: 'Value',\n dataIndex: 'value',\n key: 'value',\n ellipsis: false,\n },\n];\n","import React, { ReactNode, useEffect, useMemo } from 'react';\nimport { PageHeader, Table } from 'antd';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { useHistory, useParams } from 'react-router';\nimport { useLog } from 'shared/hooks';\nimport { LOG_COLUMNS } from './constants';\nimport { getLogColor } from 'utils/log-utils';\nimport { parseISODateFormat } from '../../utils/date-utils';\n\ntype TableLog = {\n key: string;\n value: string | ReactNode;\n};\n\nconst ExLogDetailsPage = (): JSX.Element => {\n const { logId } = useParams<{ logId: string }>();\n\n const { log, fetchLog, isLogLoading } = useLog(logId, 'ex-');\n const history = useHistory();\n\n useEffect((): void => {\n fetchLog();\n }, [fetchLog]);\n\n const tableLogs = useMemo((): TableLog[] => {\n if (!log) return [];\n const {\n title,\n data,\n type,\n username,\n timestamp,\n deviceBrand,\n deviceModel,\n deviceSystemName,\n deviceSystemVersion\n } = log;\n return [\n { key: 'Timestamp', value: parseISODateFormat(timestamp, true) },\n {\n key: 'Type',\n value: <Styled.TypeRow color={getLogColor(type)}>{type.toUpperCase()}</Styled.TypeRow>\n },\n { key: 'Title', value: title },\n { key: 'Username', value: username },\n { key: 'Data', value: <Styled.DataRow>{data}</Styled.DataRow> },\n { key: 'Brand', value: deviceBrand },\n { key: 'Model', value: deviceModel },\n { key: 'System Name', value: deviceSystemName },\n { key: 'System Version', value: deviceSystemVersion }\n ];\n }, [log]);\n\n const goBack = (): void => {\n history.goBack();\n };\n\n return (\n <ContentContainer containerStyle={{ maxHeight: '100vh', minHeight: 'unset' }}>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title={`External Log details #${logId}`} />\n <Styled.TableContainer>\n <Table\n columns={LOG_COLUMNS}\n dataSource={tableLogs}\n loading={isLogLoading}\n pagination={false}\n size={'middle'}\n />\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default ExLogDetailsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","export const COMMENTS_COLUMNS = [\n {\n title: 'ID',\n dataIndex: 'id',\n ellipsis: true,\n width: 50,\n },\n {\n title: 'Content',\n dataIndex: 'content',\n ellipsis: false,\n },\n {\n title: 'Author username',\n dataIndex: ['user', 'username'],\n ellipsis: true,\n width: 155,\n },\n {\n title: 'Author email',\n dataIndex: ['user', 'email'],\n ellipsis: true,\n width: 230,\n },\n {\n title: 'Created',\n dataIndex: 'createdAt',\n ellipsis: true,\n width: 165,\n },\n {\n title: 'Updated',\n dataIndex: 'updatedAt',\n ellipsis: true,\n width: 165,\n },\n];\n","import React, { useEffect, useState } from 'react';\nimport Pagination from 'antd/lib/pagination';\nimport { PageHeader, Table, Typography } from 'antd';\nimport * as Styled from './styles';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { format } from 'date-fns';\nimport { useSessionComments, useAppDispatch, useNotifications } from 'shared/hooks';\nimport { useParams } from 'react-router';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { ESnackbarStyle } from 'shared/types';\nimport { COMMENTS_COLUMNS } from './constants';\nimport { useHistory } from 'react-router-dom';\n\ntype TableComment = {\n id: number;\n content: string;\n createdAt: string;\n updatedAt: string;\n user: {\n email: string;\n username: string;\n }\n}\n\ntype QueryParams = {\n sessionId: string;\n};\n\nconst SessionCommentsPage = (): JSX.Element => {\n const history = useHistory();\n const [tableComments, setTableComments] = useState<TableComment[]>([]);\n const { sessionId } = useParams<QueryParams>();\n const dispatch = useAppDispatch();\n const { openNotification } = useNotifications();\n\n const {\n sessionComments,\n removeSessionComment,\n isSessionLoading,\n totalComments,\n currentPage,\n setCurrentPage,\n fetchSessionComments\n } = useSessionComments();\n\n useEffect((): void => {\n fetchSessionComments(sessionId);\n }, [fetchSessionComments, sessionId]);\n\n useEffect((): void => {\n const modifiedComments = sessionComments.map((comment): TableComment => {\n return {\n id: comment.id,\n content: comment.content,\n createdAt: format(new Date(comment.createdAt), 'yyyy-MM-dd HH:mm:ss'),\n updatedAt: format(new Date(comment.updatedAt), 'yyyy-MM-dd HH:mm:ss'),\n user: {\n username: comment.user.username,\n email: comment.user.email,\n }\n };\n });\n setTableComments(modifiedComments);\n }, [sessionComments, currentPage]);\n\n const handleRemoveComment = (comment: TableComment): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this comment?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeSessionComment(comment.id.toString());\n await fetchSessionComments(sessionId);\n openNotification(ESnackbarStyle.SUCCESS, 'Comment successfully deleted');\n }}\n />\n )\n );\n };\n\n const goBack = (): void => {\n history.goBack();\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title={`Session comments`} />\n <Styled.TableContainer>\n <Table\n columns={[\n ...COMMENTS_COLUMNS,\n {\n title: 'Actions',\n width: 100,\n render: (record): JSX.Element => {\n return (\n <Typography.Link onClick={(): void => handleRemoveComment(record)}>Remove</Typography.Link>\n );\n }\n }]}\n dataSource={tableComments}\n pagination={false}\n loading={isSessionLoading}\n size={'middle'}\n />\n </Styled.TableContainer>\n {totalComments > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={totalComments}\n onChange={setCurrentPage}\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.PageContainer>\n </ContentContainer>\n )\n}\n\nexport default SessionCommentsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","export const SESSIONS_COLUMNS = [\n {\n title: '#',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n width: 50,\n },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n width: 130,\n },\n {\n title: 'Email',\n dataIndex: 'email',\n key: 'email',\n ellipsis: true,\n width: 220\n },\n {\n title: 'Name',\n dataIndex: 'name',\n key: 'name',\n width: 100,\n ellipsis: true,\n },\n {\n title: 'Likes',\n dataIndex: 'likes',\n key: 'likes',\n width: 100,\n ellipsis: true,\n },\n {\n title: 'Comments',\n dataIndex: 'comments',\n key: 'comments',\n width: 100,\n ellipsis: true,\n },\n {\n title: 'Created At',\n dataIndex: 'createdAt',\n key: 'createdAt',\n ellipsis: true,\n width: 155\n },\n];\n","import { useHistory } from 'react-router-dom';\nimport React, { useEffect, useState } from 'react';\nimport { PageHeader, Table, Input } from 'antd';\nimport Pagination from 'antd/lib/pagination';\nimport * as Styled from './styles';\nimport { useSessions } from 'shared/hooks';\nimport { SESSIONS_COLUMNS } from './constants';\nimport { ContentContainer } from 'shared/components';\nimport { PaginationContainer } from 'shared/styles';\nimport { format } from 'date-fns';\n\ntype TableSession = {\n id: string;\n key: number;\n createdAt: string;\n name: string;\n username: string;\n email: string;\n comments: number;\n likes: number;\n}\n\ntype RowAction = {\n onClick: () => void;\n};\n\nconst SessionsCommunityPage = (): JSX.Element => {\n const history = useHistory();\n const [tableSessions, setTableSessions] = useState<TableSession[]>([]);\n\n const {\n sessions,\n pagination: { currentPage, pageSize, totalItemsCount },\n searchValue,\n isSessionsLoading,\n fetchSessions,\n setSearchValue,\n onChangePagination\n } = useSessions();\n\n useEffect((): void => {\n fetchSessions({ withoutShots: true });\n }, [fetchSessions]);\n\n useEffect((): void => {\n let i = (currentPage - 1) * pageSize;\n\n const modifiedSessions = sessions.map(\n (session): TableSession => {\n i += 1;\n\n return {\n id: session.id,\n key: i,\n createdAt: format(new Date(session.createdAt), 'yyyy-MM-dd HH:mm:ss'),\n name: session.sessionName,\n username: session.user.username,\n email: session.user.email,\n comments: session.comments.length,\n likes: session.likes.length,\n }\n }\n );\n setTableSessions(modifiedSessions);\n }, [sessions, currentPage, pageSize]);\n\n const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const handleRowClick = (session: TableSession): void => {\n history.push(`/sessions/${session.id}/comments`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Sessions Community Data' />\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input\n placeholder='Search'\n onChange={handleSearchInputChange}\n value={searchValue}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n onRow={(session): RowAction => ({ onClick: (): void => handleRowClick(session) })}\n columns={SESSIONS_COLUMNS}\n dataSource={tableSessions}\n pagination={false}\n loading={isSessionsLoading}\n size={'middle'}\n />\n </Styled.TableContainer>\n <PaginationContainer>\n <Pagination\n pageSize={pageSize}\n current={currentPage}\n total={totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default SessionsCommunityPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const NewUserButton = styled.div`\n width: 270px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","export const GROUPS_COLUMNS = [\n {\n title: 'ID',\n dataIndex: 'groupId',\n key: 'groupId',\n ellipsis: true,\n width: 50,\n },\n {\n title: 'Group name',\n dataIndex: 'name',\n key: 'name',\n ellipsis: true,\n },\n {\n title: 'Owner Username',\n dataIndex: 'ownerName',\n key: 'ownerName',\n ellipsis: true,\n },\n {\n title: 'Owner Email',\n dataIndex: 'ownerEmail',\n key: 'ownerEmail',\n ellipsis: true,\n },\n {\n title: 'Members',\n dataIndex: 'membersCount',\n key: 'membersCount',\n ellipsis: true,\n width: 90\n }\n];\n\nexport const MEMBERS_COLUMNS = [\n {\n title: 'ID',\n dataIndex: 'id',\n key: 'id',\n ellipsis: true,\n width: 50,\n },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n },\n {\n title: 'Email',\n dataIndex: 'email',\n key: 'email',\n ellipsis: true,\n },\n];\n","import React, { useEffect, useState } from 'react';\nimport * as Styled from './styles';\nimport { ContentContainer } from 'shared/components';\nimport { PageHeader, Table, Input } from 'antd';\nimport { useGroups } from 'shared/hooks';\nimport { GROUPS_COLUMNS } from './constants';\nimport Pagination from 'antd/lib/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { useHistory } from 'react-router-dom';\nimport { User } from 'shared/types';\n\ntype TableGroup = {\n groupId: number;\n name: string;\n ownerName: string;\n ownerEmail: string;\n membersCount: number;\n members: User[];\n};\n\ntype RowAction = {\n onClick: () => void;\n};\n\nconst UserGroupsPage = (): JSX.Element => {\n const history = useHistory();\n const [tableGroups, setTableGroups] = useState<TableGroup[]>([]);\n const {\n groups,\n isGroupsLoading,\n searchValue,\n pagination,\n onChangePagination,\n fetchGroups,\n setSearchValue\n } = useGroups();\n\n useEffect((): void => {\n fetchGroups();\n }, [fetchGroups]);\n\n useEffect((): void => {\n const modifiedGroups = groups.map((group): TableGroup => {\n let ownerName = '';\n let ownerEmail = '';\n\n group.members.forEach((member): void => {\n if (member.isGroupOwner) {\n ownerName = member.username;\n ownerEmail = member.email;\n }\n });\n\n return {\n groupId: group.id,\n name: group.name,\n members: group.members,\n membersCount: group.members.length,\n ownerName,\n ownerEmail\n };\n });\n setTableGroups(modifiedGroups);\n }, [groups, pagination.currentPage]);\n\n const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n const { value } = event.target;\n setSearchValue(value);\n };\n\n const handleRowClick = (group: TableGroup): void => {\n history.push(`/groups/${group.groupId}`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Groups' />\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input\n placeholder='Search'\n onChange={handleSearchInputChange}\n value={searchValue}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n onRow={(group): RowAction => ({ onClick: (): void => handleRowClick(group) })}\n columns={GROUPS_COLUMNS}\n dataSource={tableGroups}\n pagination={false}\n loading={isGroupsLoading}\n size={'middle'}\n // expandable={{\n // expandedRowRender: (record): JSX.Element => (\n // <Table\n // columns={MEMBERS_COLUMNS}\n // dataSource={record.members}\n // pagination={false}\n // loading={isGroupsLoading}\n // />\n // )}}\n />\n </Styled.TableContainer>\n <PaginationContainer>\n <Pagination\n pageSize={pagination.pageSize}\n current={pagination.currentPage}\n total={pagination.totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default UserGroupsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const Form = styled.form`\n max-width: 480px;\n width: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nexport const FormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n\nexport const Img = styled.div`\n height: 350px;\n width: auto;\n padding: 16px 0;\n\n img {\n max-height: 100%;\n }\n`;\n\nexport const FormActions = styled.div`\n margin-top: 20px;\n display: flex;\n justify-content: space-between;\n`;\n\nexport const RemoveButton = styled.div`\n margin-top: 30px;\n width: max-content;\n\n & button {\n background: #f5222d;\n color: #fff;\n border-radius: 4px;\n transition: all .2s;\n }\n\n & button:hover {\n opacity: 0.8;\n background: #f5222d;\n color: #fff;\n border: 1px solid #fff;\n }\n`;\n","import React, { useEffect } from 'react';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { Button, Input, PageHeader, Upload } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport { useFormik } from 'formik';\nimport { validation } from 'services/validation';\nimport { useAppDispatch, useNotifications, useGroup } from 'shared/hooks';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { updateGroup } from 'services/api/groupsService';\nimport { ESnackbarStyle } from 'shared/types';\nimport { DeleteOutlined, UploadOutlined } from '@ant-design/icons';\nimport { getFieldError } from 'utils/error-utils';\nimport { RcFile, UploadChangeParam } from 'antd/lib/upload';\nimport { UploadFile } from 'antd/lib/upload/interface';\n\ntype FormValues = {\n name: string;\n image: RcFile | null;\n};\n\ntype QueryParams = {\n groupId: string;\n}\n\nconst UserGroupPage = (): JSX.Element => {\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { groupId } = useParams<QueryParams>();\n const { openNotification } = useNotifications();\n const { group, isGroupLoading, fetchGroup, removeGroup } = useGroup();\n\n useEffect((): void => {\n fetchGroup(groupId);\n }, [fetchGroup, groupId]);\n\n const initialValues: FormValues = {\n name: group?.name || '',\n image: null,\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n try {\n const formData = new FormData();\n\n formData.append('name', values.name);\n if (values.image) {\n formData.append('image', values.image!);\n }\n\n await updateGroup(groupId, formData);\n history.push('/groups');\n openNotification(ESnackbarStyle.SUCCESS, 'Group successfully updated');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n initialValues,\n validationSchema: validation.EDIT_GROUP,\n enableReinitialize: true\n });\n\n const { values, setFieldValue } = formik;\n\n const handleImageChange = (file: UploadChangeParam<UploadFile<File>>): void => {\n if (file?.fileList[0]) {\n setFieldValue('image', file.fileList[0].originFileObj);\n } else {\n setFieldValue('image', null);\n }\n };\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const showRemoveGroupModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this group?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeGroup(groupId);\n history.push('/groups');\n openNotification(ESnackbarStyle.SUCCESS, 'Group successfully deleted');\n }}\n />\n )\n );\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Edit Group' />\n <Styled.Form onSubmit={formik.handleSubmit}>\n {group?.groupPictureS3Url &&\n <Styled.Img>\n <img src={group?.groupPictureS3Url} alt={''}/>\n </Styled.Img>\n }\n <Styled.FormInputContainer>\n <Upload\n name='image'\n fileList={values.image ? [values.image] : []}\n onChange={handleImageChange}\n beforeUpload={(): boolean => false}\n >\n <Button icon={<UploadOutlined />}>Choose file</Button>\n </Upload>\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Group name'\n size='large'\n value={formik.values.name}\n name='name'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n disabled={isGroupLoading || formik.isSubmitting}\n />\n {getFieldError(formik, 'firstName')}\n </Styled.FormInputContainer>\n <Styled.FormActions>\n <Button\n type='primary'\n htmlType='submit'\n disabled={isGroupLoading || formik.isSubmitting || !formik.dirty}\n loading={formik.isSubmitting}\n >\n Apply\n </Button>\n </Styled.FormActions>\n <Styled.RemoveButton>\n <Button\n icon={<DeleteOutlined />}\n type='default'\n onClick={showRemoveGroupModal}\n disabled={isGroupLoading || formik.isSubmitting}\n >\n Remove group\n </Button>\n </Styled.RemoveButton>\n </Styled.Form>\n </Styled.PageContainer>\n </ContentContainer>\n );\n}\n\nexport default UserGroupPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","export const MESSAGES_COLUMNS = [\n {\n title: 'Message',\n dataIndex: 'message',\n ellipsis: false,\n },\n {\n title: 'Author Username',\n dataIndex: 'authorUsername',\n ellipsis: true,\n width: 200\n },\n {\n title: 'Author Email',\n dataIndex: 'authorEmail',\n ellipsis: true,\n width: 260\n },\n {\n title: 'Created',\n dataIndex: 'createdAt',\n ellipsis: true,\n width: 170,\n },\n];\n","import React, { useEffect, useState } from 'react';\nimport Pagination from 'antd/lib/pagination';\nimport { PageHeader, Table, Button } from 'antd';\nimport * as Styled from './styles';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { ContentContainer, SupportMessageModal } from 'shared/components';\nimport { PaginationContainer } from 'shared/styles';\nimport { format } from 'date-fns';\nimport { useSupportMessages, useAppDispatch } from 'shared/hooks';\nimport { useParams } from 'react-router';\nimport { showModal } from 'services/store/reducers/modalReducer';\nimport { MESSAGES_COLUMNS } from './constants';\n\ntype TableMessage = {\n id: number;\n userId: number;\n message: string;\n createdAt: string;\n authorUsername: string;\n authorEmail: string;\n}\n\ntype QueryParams = {\n userId: string;\n};\n\nconst SupportMessagesPage = (): JSX.Element => {\n const [tableMessages, setTableMessages] = useState<TableMessage[]>([]);\n const { userId } = useParams<QueryParams>();\n const dispatch = useAppDispatch();\n\n const {\n messages,\n fetchMessages,\n isMessagesLoading,\n currentPage,\n setCurrentPage,\n totalMessages\n } = useSupportMessages(userId);\n\n useEffect((): void => {\n fetchMessages(true);\n }, [fetchMessages]);\n\n useEffect((): any => {\n const interval = setInterval((): void => {\n fetchMessages(false);\n }, 2500);\n\n return (): void => clearInterval(interval);\n }, [fetchMessages]);\n\n useEffect((): void => {\n const modifiedMessages = messages.map((message): TableMessage => {\n return {\n id: message.id,\n message: message.content,\n createdAt: format(new Date(message.createdAt), 'yyyy-MM-dd HH:mm:ss'),\n userId: message.userId,\n authorEmail: message.author.email,\n authorUsername: message.author.username || (message.author.role === 'master_admin' ? 'Master Admin' : '')\n };\n });\n setTableMessages(modifiedMessages);\n }, [messages, currentPage]);\n\n const showSupportMessageModal = (): void => {\n dispatch(\n showModal(\n <SupportMessageModal userId={userId} fetchMessages={fetchMessages}/>\n )\n );\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title={`Support messages`} />\n <Button\n htmlType='button'\n type='primary'\n size='middle'\n disabled={isMessagesLoading}\n style={{ width: 150 }}\n onClick={(): void => showSupportMessageModal()}\n >\n New message\n </Button>\n <Styled.TableContainer>\n <Table\n columns={MESSAGES_COLUMNS}\n dataSource={tableMessages}\n pagination={false}\n loading={isMessagesLoading}\n size={'middle'}\n />\n </Styled.TableContainer>\n {totalMessages > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={totalMessages}\n onChange={setCurrentPage}\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.PageContainer>\n </ContentContainer>\n )\n}\n\nexport default SupportMessagesPage;\n","import styled from 'styled-components';\nimport { DEVICE } from 'shared/constants/deviceSizes';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const TableContainer = styled.div`\n flex: 1;\n overflow-x: auto;\n\n & table {\n max-width: unset;\n width: unset;\n min-width: 100%;\n }\n\n & thead tr th {\n max-width: 600px;\n\n @media ${DEVICE.tablet} {\n max-width: 600px;\n }\n }\n\n & tbody tr td {\n max-width: 600px;\n\n @media ${DEVICE.tablet} {\n max-width: 600px;\n }\n }\n`;\n","import React, { useEffect, useState } from 'react';\nimport { PageHeader, Table, Typography } from 'antd';\nimport Pagination from 'antd/lib/pagination';\nimport * as Styled from './styles';\nimport { useUserShots } from 'shared/hooks';\nimport {ContentContainer} from 'shared/components';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { format } from 'date-fns';\nimport { useHistory, useParams } from 'react-router';\nimport { ADVANCED_SHOTS_COLUMN } from './constants';\nimport { DeviceInformation } from '../../shared/types';\n\ntype TableShot = {\n id: string | number;\n name: string;\n shotScoreTotal: number;\n shotScoreAimSteadiness: number;\n shotScoreBowAngle: number;\n shotScoreAimTime: number;\n shotScoreBowTorque: number;\n valid: string;\n timestamp: string;\n userMetadata?: DeviceInformation & {appVersion: string};\n}\n\ntype QueryParams = {\n userId: string;\n};\n\nconst UserShotsPage = (): JSX.Element => {\n const [tableShots, setTableShots] = useState<TableShot[]>([]);\n const { userId } = useParams<QueryParams>();\n\n const history = useHistory();\n\n const {\n shots,\n fetchShots,\n fetchCsvShot,\n isShotsLoading,\n currentPage,\n totalShots,\n setCurrentPage,\n } = useUserShots();\n\n useEffect((): void => {\n fetchShots(userId);\n }, [fetchShots, userId]);\n\n useEffect((): void => {\n const modifiedShots = shots.map((shot): TableShot => {\n return {\n id: shot.id,\n name: shot.name,\n shotScoreTotal: shot.shotScoreTotal,\n shotScoreAimSteadiness: shot.shotScoreAimSteadiness,\n shotScoreBowAngle: shot.shotScoreBowAngle,\n shotScoreAimTime: shot.shotScoreAimTime,\n shotScoreBowTorque: shot.shotScoreBowTorque,\n valid: shot.isShotDetected ? 'True' : 'False',\n timestamp: format(new Date(shot.timestamp), 'yyyy-MM-dd HH:mm:ss'),\n userMetadata: shot.userMetadata,\n };\n });\n setTableShots(modifiedShots);\n }, [shots, currentPage]);\n\n const goBack = (): void => {\n history.goBack();\n };\n\n return (\n <ContentContainer containerStyle={{ maxWidth: 'unset', maxHeight: '100vh' }}>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Shots' />\n <Styled.TableContainer>\n <Table\n columns={[\n ...ADVANCED_SHOTS_COLUMN,\n {\n title: 'Actions',\n width: 100,\n render: (record): JSX.Element => {\n return (\n <Typography.Link onClick={(): Promise<void> => fetchCsvShot(record.id, record.name)}>\n Export CSV\n </Typography.Link>\n );\n }\n }\n ]}\n dataSource={tableShots}\n pagination={false}\n loading={isShotsLoading}\n size={'middle'}\n />\n </Styled.TableContainer>\n {totalShots > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={totalShots}\n onChange={setCurrentPage}\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default UserShotsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const NewBowButton = styled.div`\n width: 270px;\n`;\n\nexport const TableContainer = styled.div`\n flex: 1;\n margin-top: 24px;\n\n & tbody tr {\n cursor: pointer;\n }\n`;\n","export const BOW_COLUMNS = [\n {\n title: 'Model',\n dataIndex: 'modelName',\n key: 'modelName',\n ellipsis: true,\n },\n {\n title: 'Draw Weight',\n dataIndex: 'drawWeight',\n key: 'drawWeight',\n ellipsis: true,\n render: (item: number[]): JSX.Element => {\n return <>{item.join(', ')}</>\n }\n },\n {\n title: 'Draw Length',\n dataIndex: 'drawLength',\n key: 'drawLength',\n ellipsis: true,\n render: (item: number[]): JSX.Element => {\n return <>{Math.min(...item)} - {Math.max(...item)}</>\n }\n },\n {\n title: 'Let-Off',\n dataIndex: 'letOff',\n key: 'letOff',\n ellipsis: true,\n render: (item: number[]): JSX.Element => {\n return <>{item.join(', ')}</>\n }\n },\n {\n title: 'LR/HR',\n dataIndex: 'lr/hr',\n key: 'lr/hr',\n ellipsis: true,\n render: (item: string[]): JSX.Element => {\n return <>{item.join(', ')}</>\n }\n },\n];\n","import React, { useEffect, useState } from 'react';\nimport { NavLink, useHistory } from 'react-router-dom';\nimport * as Styled from './styles';\nimport { ContentContainer } from 'shared/components';\nimport { Button, PageHeader, Table } from 'antd';\nimport { PlusCircleOutlined } from '@ant-design/icons';\nimport { useAppSelector, useBows } from 'shared/hooks';\nimport { EUserRole, User } from 'shared/types';\nimport Pagination from 'antd/lib/pagination';\nimport { PAGE_SIZE } from 'shared/constants/pagination';\nimport { PaginationContainer } from 'shared/styles';\nimport { BOW_COLUMNS } from './constants';\nimport { checkRolePermission } from 'utils/role-utils';\n\ntype TableBow = {\n id: number;\n modelName: string;\n drawWeight: number[];\n drawLength: number[];\n letOff: number[];\n 'lr/hr': string[];\n};\n\ntype RowAction = {\n onClick: () => void;\n};\n\nconst BowsPage = (): JSX.Element => {\n const history = useHistory();\n const [tableBows, setTableBows] = useState<TableBow[]>([]);\n\n const user = useAppSelector((state): User | null => state.auth.user);\n\n const { fetchBows, bows, isBowsLoading, currentPage, totalBows, setCurrentPage } = useBows();\n\n useEffect((): void => {\n fetchBows();\n }, [fetchBows]);\n\n useEffect((): void => {\n const modifiedBows = bows.map(\n (bow): TableBow => ({\n id: bow.id,\n modelName: bow.modelName,\n drawWeight: bow.drawWeight,\n drawLength: bow.drawLength,\n letOff: bow.letOff,\n 'lr/hr': bow['lr/hr']\n })\n );\n setTableBows(modifiedBows);\n }, [bows]);\n\n const handleRowClick = (bow: TableBow): void => {\n history.push(`/bows/${bow.id}`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Bows' />\n <Styled.PageHeader>\n <Styled.NewBowButton>\n <NavLink to='/add-bow'>\n {user?.role &&\n checkRolePermission([EUserRole.master_admin, EUserRole.admin_user], user.role) && (\n <Button icon={<PlusCircleOutlined />}>New bow</Button>\n )}\n </NavLink>\n </Styled.NewBowButton>\n </Styled.PageHeader>\n <Styled.TableContainer>\n <Table\n onRow={(bow): RowAction => ({ onClick: (): void => handleRowClick(bow) })}\n columns={BOW_COLUMNS}\n dataSource={tableBows}\n pagination={false}\n loading={isBowsLoading}\n size={'middle'}\n />\n {totalBows > PAGE_SIZE && (\n <PaginationContainer>\n <Pagination\n current={currentPage}\n total={totalBows}\n onChange={setCurrentPage}\n pageSize={PAGE_SIZE}\n />\n </PaginationContainer>\n )}\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default BowsPage;\n","import styled from 'styled-components';\nimport { Button, Input, Select } from 'antd';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const Form = styled.form`\n max-width: 480px;\n width: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nexport const FormValuesContainer = styled.div`\n width: 100%;\n height: 88px;\n`;\n\nexport const FormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n\nexport const FormRow = styled.div`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n height: 40px;\n`;\n\nexport const FormTags = styled.div`\n margin-top: 5px;\n`;\n\nexport const FormInput = styled(Input)`\n height: 100%;\n margin-right: 20px;\n`;\n\nexport const FormSelect = styled(Select)`\n font-size: 16px;\n width: 100%;\n .ant-select-selector {\n height: 40px;\n }\n`\n\nexport const FormRange = styled.div`\n flex: 1;\n &:last-child {\n margin-left: 20px;\n }\n`;\n\nexport const FormAddButton = styled(Button)`\n height: 100%;\n`;\n","import React from 'react';\nimport { ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { Button, Input, PageHeader, Tag, Upload } from 'antd';\nimport { Redirect, useHistory } from 'react-router';\nimport { useFormik } from 'formik';\nimport { validation } from 'services/validation';\nimport { UploadOutlined } from '@ant-design/icons';\nimport { ESnackbarStyle, EUserRole, User } from 'shared/types';\nimport { useAppSelector, useBow, useNotifications } from 'shared/hooks';\nimport { getFieldError } from 'utils/error-utils';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { RcFile, UploadChangeParam } from 'antd/lib/upload';\nimport { UploadFile } from 'antd/lib/upload/interface';\nimport _ from 'lodash';\n\ntype FormValues = {\n image: RcFile | null;\n modelName: string;\n inputDrawWeight: string;\n drawWeight: number[];\n drawLengthFrom: string;\n drawLengthTo: string;\n inputLetOff: string;\n letOff: number[];\n 'lr/hr': string[];\n};\n\nconst getFieldName = (field: string, arr: number[] | string[]): string => {\n return `${field}${arr.length === 1 ? '[0]' : ''}`;\n};\n\nconst AddBowPage = (): JSX.Element => {\n const user = useAppSelector((state): User | null => state.auth.user);\n\n const history = useHistory();\n const { openNotification } = useNotifications();\n const { isBowLoading, createBow } = useBow();\n\n const initialValues: FormValues = {\n image: null,\n modelName: '',\n inputDrawWeight: '',\n drawWeight: [],\n drawLengthFrom: '',\n drawLengthTo: '',\n inputLetOff: '',\n letOff: [],\n 'lr/hr': []\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n const maxLength = Math.max(\n _.toNumber(values.drawLengthFrom),\n _.toNumber(values.drawLengthTo)\n );\n const minLength = Math.min(\n _.toNumber(values.drawLengthFrom),\n _.toNumber(values.drawLengthTo)\n );\n const formData = new FormData();\n formData.append('image', values.image!);\n formData.append('modelName', values.modelName);\n _.range(minLength, maxLength + 0.5, 0.5).forEach((item): void =>\n formData.append('drawLength', `${item}`)\n );\n values.drawWeight.forEach((item): void =>\n formData.append(getFieldName('drawWeight', values.drawWeight), `${item}`)\n );\n values.letOff.forEach((item): void =>\n formData.append(getFieldName('letOff', values.letOff), `${item}`)\n );\n values['lr/hr'].forEach((item): void =>\n formData.append(getFieldName('lr/hr', values['lr/hr']), `${item}`)\n );\n try {\n await createBow(formData);\n openNotification(ESnackbarStyle.SUCCESS, 'Bow was added successfully');\n history.push('/bows');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n initialValues,\n validationSchema: validation.CREATE_BOW\n });\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const handleImageChange = (file: UploadChangeParam<UploadFile<File>>): void => {\n if (file?.fileList[0]) {\n formik.setFieldValue('image', file.fileList[0].originFileObj);\n } else {\n formik.setFieldValue('image', null);\n }\n };\n\n const addBowValue = (\n value: 'inputDrawWeight' | 'inputLetOff',\n field: 'drawWeight' | 'letOff'\n ): void => {\n const property = formik.values[value];\n const curr = formik.values[field];\n const isExists = curr.some((val: string | number): boolean => val === property);\n if (!isExists) {\n formik.setFieldValue(\n field,\n [...curr, _.toNumber(property)].sort((a, b): number => a - b)\n );\n }\n formik.setFieldValue(value, initialValues[value]);\n };\n\n const removeBowValue = (\n field: 'drawWeight' | 'letOff',\n value: string | number\n ): void => {\n formik.setFieldValue(field, _.difference(formik.values[field], [value]));\n };\n\n if (\n user?.role &&\n !checkRolePermission([EUserRole.master_admin, EUserRole.admin_user], user.role)\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Add a new bow' />\n <Styled.Form onSubmit={formik.handleSubmit}>\n <Styled.FormInputContainer>\n <Upload\n accept='.jpeg,.png'\n name='image'\n fileList={formik.values.image ? [formik.values.image] : []}\n onChange={handleImageChange}\n beforeUpload={(): boolean => false}\n >\n <Button icon={<UploadOutlined />}>Choose image</Button>\n </Upload>\n {getFieldError(formik, 'image')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Model'\n size='large'\n value={formik.values.modelName}\n name='modelName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n />\n {getFieldError(formik, 'modelName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Styled.FormRow>\n <Styled.FormRange>\n <Styled.FormInput\n placeholder='Draw Length'\n size='large'\n value={formik.values.drawLengthFrom}\n name='drawLengthFrom'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n {getFieldError(formik, 'drawLengthFrom')}\n </Styled.FormRange>\n <Styled.FormRange>\n <Styled.FormInput\n placeholder='Draw Length'\n size='large'\n value={formik.values.drawLengthTo}\n name='drawLengthTo'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n {getFieldError(formik, 'drawLengthTo')}\n </Styled.FormRange>\n </Styled.FormRow>\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Styled.FormSelect\n value={formik.values['lr/hr']}\n mode='multiple'\n placeholder='Please select'\n onChange={(val): void => {\n formik.setFieldValue('lr/hr', val);\n }}\n options={[\n { value: 'lr', label: 'LR' },\n { value: 'hr', label: 'HR' }\n ]}\n />\n {getFieldError(formik, 'lr/hr')}\n </Styled.FormInputContainer>\n <Styled.FormValuesContainer>\n <Styled.FormRow>\n <Styled.FormInput\n placeholder='Draw Weight'\n size='large'\n value={formik.values.inputDrawWeight}\n name='inputDrawWeight'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n <Styled.FormAddButton\n type='primary'\n onClick={(): void => addBowValue('inputDrawWeight', 'drawWeight')}\n disabled={!formik.values.inputDrawWeight}\n >\n Add\n </Styled.FormAddButton>\n </Styled.FormRow>\n <Styled.FormTags>\n {formik.values.drawWeight.map(\n (value): JSX.Element => (\n <Tag\n key={value}\n closable\n onClose={(): void => removeBowValue('drawWeight', value)}\n >\n {value}\n </Tag>\n )\n )}\n </Styled.FormTags>\n {getFieldError(formik, 'drawWeight')}\n </Styled.FormValuesContainer>\n <Styled.FormValuesContainer>\n <Styled.FormRow>\n <Styled.FormInput\n placeholder='Let-Off'\n size='large'\n value={formik.values.inputLetOff}\n name='inputLetOff'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n <Styled.FormAddButton\n type='primary'\n onClick={(): void => addBowValue('inputLetOff', 'letOff')}\n disabled={!formik.values.inputLetOff}\n >\n Add\n </Styled.FormAddButton>\n </Styled.FormRow>\n <Styled.FormTags>\n {formik.values.letOff.map(\n (value): JSX.Element => (\n <Tag key={value} closable onClose={(): void => removeBowValue('letOff', value)}>\n {value}\n </Tag>\n )\n )}\n </Styled.FormTags>\n {getFieldError(formik, 'letOff')}\n </Styled.FormValuesContainer>\n <Button type='primary' htmlType='submit' loading={isBowLoading}>\n Add\n </Button>\n </Styled.Form>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default AddBowPage;\n","import { Button, Input, Select } from 'antd';\nimport styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const Form = styled.form`\n max-width: 480px;\n width: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nexport const FormValuesContainer = styled.div`\n width: 100%;\n height: 88px;\n`;\n\nexport const FormInputContainer = styled.div`\n width: 100%;\n height: 68px;\n`;\n\nexport const FormRow = styled.div`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n height: 40px;\n`;\n\nexport const FormTags = styled.div`\n margin-top: 5px;\n`;\n\nexport const FormInput = styled(Input)`\n height: 100%;\n margin-right: 20px;\n`;\n\nexport const FormSelect = styled(Select)`\n font-size: 16px;\n width: 100%;\n .ant-select-selector {\n height: 40px;\n }\n`\n\nexport const FormRange = styled.div`\n flex: 1;\n &:last-child {\n margin-left: 20px;\n }\n`;\n\nexport const FormAddButton = styled(Button)`\n height: 100%;\n`;\n\n\nexport const FormImg = styled.div`\n height: 350px;\n width: auto;\n padding: 16px 0;\n\n img {\n max-height: 100%;\n }\n`;\n\nexport const FormActions = styled.div`\n margin-top: 20px;\n display: flex;\n justify-content: space-between;\n`;\n\nexport const RemoveButton = styled.div`\n & button {\n background: #f5222d;\n color: #fff;\n border-radius: 4px;\n transition: all .2s;\n }\n\n & button:hover {\n opacity: 0.8;\n background: #f5222d;\n color: #fff;\n border: 1px solid #fff;\n }\n`;\n","import React, { useEffect } from 'react';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\nimport * as Styled from './styles';\nimport { Button, Input, PageHeader, Tag, Upload } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport { useFormik } from 'formik';\nimport { validation } from 'services/validation';\nimport { useAppDispatch, useAppSelector, useBow, useNotifications } from 'shared/hooks';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport { ESnackbarStyle, EUserRole, User } from 'shared/types';\nimport { DeleteOutlined, UploadOutlined } from '@ant-design/icons';\nimport { getFieldError } from 'utils/error-utils';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { Redirect } from 'react-router-dom';\nimport { RcFile, UploadChangeParam } from 'antd/lib/upload';\nimport { UploadFile } from 'antd/lib/upload/interface';\nimport _ from 'lodash';\n\ntype FormValues = {\n image: RcFile | null;\n modelName: string;\n inputDrawWeight: string;\n drawWeight: number[];\n drawLengthFrom: string;\n drawLengthTo: string;\n inputLetOff: string;\n letOff: number[];\n 'lr/hr': string[];\n};\n\ntype QueryParams = {\n bowId: string;\n};\n\nconst getFieldName = (field: string, arr: number[] | string[]): string => {\n return `${field}${arr.length === 1 ? '[0]' : ''}`;\n};\n\nconst EditBowPage = (): JSX.Element => {\n const user = useAppSelector((state): User | null => state.auth.user);\n\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { bowId } = useParams<QueryParams>();\n const { openNotification } = useNotifications();\n const { bow, isBowLoading, fetchBow, removeBow, editBow } = useBow();\n\n useEffect((): void => {\n fetchBow(bowId);\n }, [fetchBow, bowId]);\n\n const initialValues: FormValues = {\n image: null,\n modelName: bow?.modelName || '',\n inputDrawWeight: '',\n drawWeight: bow?.drawWeight || [],\n drawLengthFrom: bow ? `${Math.min(...bow.drawLength)}` : '',\n drawLengthTo: bow ? `${Math.max(...bow.drawLength)}` : '',\n inputLetOff: '',\n letOff: bow?.letOff || [],\n 'lr/hr': bow ? bow['lr/hr'] : []\n };\n\n const formik = useFormik({\n onSubmit: async (values): Promise<void> => {\n const maxLength = Math.max(\n _.toNumber(values.drawLengthFrom),\n _.toNumber(values.drawLengthTo)\n );\n const minLength = Math.min(\n _.toNumber(values.drawLengthFrom),\n _.toNumber(values.drawLengthTo)\n );\n const formData = new FormData();\n if (values.image) {\n formData.append('image', values.image!);\n }\n formData.append('modelName', values.modelName);\n _.range(minLength, maxLength + 0.5, 0.5).forEach((item): void =>\n formData.append('drawLength', `${item}`)\n );\n values.drawWeight.forEach((item): void =>\n formData.append(getFieldName('drawWeight', values.drawWeight), `${item}`)\n );\n values.letOff.forEach((item): void =>\n formData.append(getFieldName('letOff', values.letOff), `${item}`)\n );\n values['lr/hr'].forEach((item): void =>\n formData.append(getFieldName('lr/hr', values['lr/hr']), `${item}`)\n );\n try {\n await editBow(bowId, formData);\n openNotification(ESnackbarStyle.SUCCESS, 'Bow successfully updated');\n history.push('/bows');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n },\n initialValues,\n validationSchema: validation.EDIT_BOW,\n enableReinitialize: true\n });\n\n const handleImageChange = (file: UploadChangeParam<UploadFile<File>>): void => {\n if (file?.fileList[0]) {\n formik.setFieldValue('image', file.fileList[0].originFileObj);\n } else {\n formik.setFieldValue('image', null);\n }\n };\n\n const addBowValue = (\n value: 'inputDrawWeight' | 'inputLetOff',\n field: 'drawWeight' | 'letOff'\n ): void => {\n const property = formik.values[value];\n const curr = formik.values[field];\n const isExists = curr.some((val: string | number): boolean => val === property);\n if (!isExists) {\n formik.setFieldValue(\n field,\n [...curr, _.toNumber(property)].sort((a, b): number => a - b)\n );\n }\n formik.setFieldValue(value, initialValues[value]);\n };\n\n const removeBowValue = (field: 'drawWeight' | 'letOff', value: string | number): void => {\n formik.setFieldValue(field, _.difference(formik.values[field], [value]));\n };\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const showRemoveBowModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this bow?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await removeBow(bowId);\n history.push('/bows');\n openNotification(ESnackbarStyle.SUCCESS, 'Bow successfully deleted');\n }}\n />\n )\n );\n };\n\n if (\n user?.role &&\n !checkRolePermission(\n [EUserRole.master_admin, EUserRole.admin_user, EUserRole.support_user],\n user.role\n )\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Edit bow' />\n <Styled.Form onSubmit={formik.handleSubmit}>\n {bow?.bowPictureS3Url && (\n <Styled.FormImg>\n <img src={bow.bowPictureS3Url} alt={''} />\n </Styled.FormImg>\n )}\n <Styled.FormInputContainer>\n <Upload\n accept='.jpeg,.png'\n name='image'\n fileList={formik.values.image ? [formik.values.image] : []}\n onChange={handleImageChange}\n beforeUpload={(): boolean => false}\n >\n <Button icon={<UploadOutlined />}>Choose image</Button>\n </Upload>\n {getFieldError(formik, 'image')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Input\n placeholder='Model'\n size='large'\n value={formik.values.modelName}\n name='modelName'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n />\n {getFieldError(formik, 'modelName')}\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Styled.FormRow>\n <Styled.FormRange>\n <Styled.FormInput\n placeholder='Draw Length'\n size='large'\n value={formik.values.drawLengthFrom}\n name='drawLengthFrom'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n {getFieldError(formik, 'drawLengthFrom')}\n </Styled.FormRange>\n <Styled.FormRange>\n <Styled.FormInput\n placeholder='Draw Length'\n size='large'\n value={formik.values.drawLengthTo}\n name='drawLengthTo'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n {getFieldError(formik, 'drawLengthTo')}\n </Styled.FormRange>\n </Styled.FormRow>\n </Styled.FormInputContainer>\n <Styled.FormInputContainer>\n <Styled.FormSelect\n mode='multiple'\n placeholder='Please select'\n value={formik.values['lr/hr']}\n onChange={(val): void => {\n formik.setFieldValue('lr/hr', val);\n }}\n options={[\n { value: 'lr', label: 'LR' },\n { value: 'hr', label: 'HR' }\n ]}\n />\n {getFieldError(formik, 'lr/hr')}\n </Styled.FormInputContainer>\n <Styled.FormValuesContainer>\n <Styled.FormRow>\n <Styled.FormInput\n placeholder='Draw Weight'\n size='large'\n value={formik.values.inputDrawWeight}\n name='inputDrawWeight'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n <Styled.FormAddButton\n type='primary'\n onClick={(): void => addBowValue('inputDrawWeight', 'drawWeight')}\n disabled={!formik.values.inputDrawWeight}\n >\n Add\n </Styled.FormAddButton>\n </Styled.FormRow>\n <Styled.FormTags>\n {formik.values.drawWeight.map(\n (value): JSX.Element => (\n <Tag\n key={value}\n closable\n onClose={(): void => removeBowValue('drawWeight', value)}\n >\n {value}\n </Tag>\n )\n )}\n </Styled.FormTags>\n {getFieldError(formik, 'drawWeight')}\n </Styled.FormValuesContainer>\n <Styled.FormValuesContainer>\n <Styled.FormRow>\n <Styled.FormInput\n placeholder='Let-Off'\n size='large'\n value={formik.values.inputLetOff}\n name='inputLetOff'\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n type='number'\n />\n <Styled.FormAddButton\n type='primary'\n onClick={(): void => addBowValue('inputLetOff', 'letOff')}\n disabled={!formik.values.inputLetOff}\n >\n Add\n </Styled.FormAddButton>\n </Styled.FormRow>\n <Styled.FormTags>\n {formik.values.letOff.map(\n (value): JSX.Element => (\n <Tag key={value} closable onClose={(): void => removeBowValue('letOff', value)}>\n {value}\n </Tag>\n )\n )}\n </Styled.FormTags>\n {getFieldError(formik, 'letOff')}\n </Styled.FormValuesContainer>\n <Styled.FormActions>\n <Button\n type='primary'\n htmlType='submit'\n disabled={isBowLoading || !formik.dirty}\n loading={formik.isSubmitting}\n >\n Apply\n </Button>\n <Styled.RemoveButton>\n <Button\n icon={<DeleteOutlined />}\n type='default'\n onClick={showRemoveBowModal}\n disabled={isBowLoading}\n >\n Remove bow\n </Button>\n </Styled.RemoveButton>\n </Styled.FormActions>\n </Styled.Form>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default EditBowPage;\n","import styled from 'styled-components';\nimport { Select, Typography } from 'antd';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n\nexport const TypeRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n\nexport const ReportSelect = styled(Select)`\n width: 300px;\n`;\n\nexport const ReportAction = styled(Typography.Link)`\n & + & {\n margin-left: 10px;\n }\n`;\n","import { ReportCategory, ReportObjectType, ReportStatus } from '../types';\n\nexport const REPORT_TITLES: {[key in ReportCategory]: string} = {\n harassment_or_bullying: 'HARASSMENT OR BULLYING',\n commercial_content_or_spam: 'UNWANTED COMMERCIAL CONTENT OR SPAM',\n hate_speech: 'HATE SPEECH',\n offensive_language: 'OFFENSIVE LANGUAGE',\n personal_information: 'SHARING PERSONAL INFORMATION',\n harmful_or_dangerous: 'HARMFUL OR DANGEROUS ACTS',\n offensive_imagery: 'OFFENSIVE IMAGERY',\n copyright_violation: 'COPYRIGHT VIOLATION',\n pornography: 'PORNOGRAPHY OR SEXUALLY EXPLICIT MATERIAL',\n violent_or_repulsive: 'VIOLENT OR REPULSIVE CONTENT',\n other: 'OTHER'\n};\n\nexport const REPORT_TYPES: {[key in ReportObjectType]: string} = {\n picture_session: 'Picture',\n picture_shot: 'Picture',\n session: 'Comment (Session)',\n shot: 'Comment (Shot)',\n};\n\nexport const REPORT_STATUSES: {[key in ReportStatus]: string} = {\n pending: 'PENDING',\n valid: 'APPROVED',\n invalid: 'DECLINED',\n};\n","import { ReportCategory, ReportObjectType, ReportStatus } from 'shared/types';\nimport { ReactNode } from 'react';\nimport { TypeRow } from './styles';\nimport { getReportColor } from 'utils/report-utils';\nimport { REPORT_STATUSES, REPORT_TITLES, REPORT_TYPES } from 'shared/constants/reports';\nimport { parseISODateFormat } from '../../utils/date-utils';\n\nexport const REPORT_COLUMNS = [\n {\n title: 'Type',\n dataIndex: 'reportObjectType',\n key: 'reportObjectType',\n ellipsis: true,\n render: (type: ReportObjectType): ReactNode => {\n return <>{REPORT_TYPES[type]}</>;\n }\n },\n {\n title: 'Category',\n dataIndex: 'category',\n key: 'category',\n ellipsis: true,\n render: (category: ReportCategory): ReactNode => {\n return <>{REPORT_TITLES[category]}</>;\n }\n },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n ellipsis: true,\n width: 100,\n render: (status: ReportStatus): ReactNode => {\n return <TypeRow color={getReportColor(status)}>{REPORT_STATUSES[status]}</TypeRow>;\n }\n },\n {\n title: 'Description',\n dataIndex: 'description',\n key: 'description',\n ellipsis: true\n },\n {\n title: 'Created',\n dataIndex: 'createdAt',\n key: 'createdAt',\n width: 190,\n ellipsis: true,\n render: (date: string): ReactNode => {\n return <>{parseISODateFormat(date, true)}</>;\n }\n }\n];\n","import React, { useEffect, useMemo } from 'react';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { EUserRole, Report, User } from 'shared/types';\nimport { Redirect } from 'react-router';\nimport { useAppSelector, useReports } from 'shared/hooks';\nimport * as Styled from './styles';\nimport { PageHeader, Table } from 'antd';\nimport { PaginationContainer } from 'shared/styles';\nimport Pagination from 'antd/lib/pagination';\nimport { ContentContainer } from 'shared/components';\nimport { useHistory } from 'react-router-dom';\nimport { REPORT_COLUMNS } from './constants';\nimport _ from 'lodash';\nimport { ColumnType } from 'antd/lib/table/interface';\n\ntype TableReport = Report & { key: number };\n\ntype Option = {\n value: string;\n label: string;\n disabled: boolean;\n};\n\nconst ReportsPage = (): JSX.Element => {\n const history = useHistory();\n const user = useAppSelector((state): User | null => state.auth.user);\n\n const {\n status,\n pagination,\n items,\n isReportsLoading,\n setStatus,\n fetchReports,\n onChangePagination\n } = useReports();\n\n useEffect((): void => {\n fetchReports();\n }, [fetchReports]);\n\n const tableReports = useMemo(\n (): TableReport[] => items.map((report): TableReport => ({ ...report, key: report.id })),\n [items]\n );\n\n const handleRowClick = (report: TableReport): void => {\n history.push(`/reports/${report.id}`);\n };\n\n const handleOpenUser = (userId: number): void => history.push(`/bow-users/${userId}`);\n\n if (\n user?.role &&\n !checkRolePermission(\n [EUserRole.moderator, EUserRole.admin_user, EUserRole.master_admin],\n user.role\n )\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Reports' />\n <Styled.ReportSelect\n defaultValue=''\n onChange={(value): void => setStatus(value as string)}\n options={['', 'pending', 'valid', 'invalid'].map(\n (value): Option => ({\n value,\n label: value ? _.capitalize(value) : 'All',\n disabled: status === value\n })\n )}\n />\n <Styled.TableContainer>\n <Table\n columns={[\n ...REPORT_COLUMNS.map((column): ColumnType<TableReport> => {\n return {\n ...column,\n onCell: (record: TableReport): { onClick: () => void } => {\n return {\n onClick: (): void => handleRowClick(record)\n };\n }\n };\n }),\n {\n title: 'Users',\n width: 180,\n render: (record: TableReport): JSX.Element => {\n return (\n <>\n <Styled.ReportAction onClick={(): void => handleOpenUser(record.accusedId)}>\n Reported User\n </Styled.ReportAction>\n <Styled.ReportAction onClick={(): void => handleOpenUser(record.reporterId)}>\n Creator\n </Styled.ReportAction>\n </>\n );\n }\n }\n ]}\n dataSource={tableReports}\n pagination={false}\n loading={isReportsLoading}\n size={'middle'}\n />\n <PaginationContainer>\n <Pagination\n pageSize={pagination.pageSize}\n current={pagination.currentPage}\n total={pagination.totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default ReportsPage;\n","import styled from 'styled-components';\nimport { Button, Typography } from 'antd';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const ReportDetails = styled.div`\n width: 800px;\n`\n\nexport const TableContainer = styled.div`\n margin-top: 24px;\n overflow-y: auto;\n`;\n\nexport const StatusRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n\nexport const ReportLink = styled(Typography.Link)`\n & + & {\n margin-left: 10px;\n }\n`;\n\nexport const ReportActions = styled.div`\n display: flex;\n`;\n\nexport const ReportAction = styled(Button)<{ color: string }>`\n background: ${({ color }): string => color};\n border-color: ${({ color }): string => color};\n\n & + &:not(:last-child) {\n margin-left: 10px;\n }\n\n &:last-child:not(:first-child) {\n margin-left: auto;\n }\n\n &:hover {\n background: ${({ color }): string => color};\n border-color: ${({ color }): string => color};\n opacity: 0.8;\n }\n`;\n\nexport const MobileContainer = styled.div`\n display: flex;\n justify-content: space-between;\n margin-top: 20px;\n overflow-y: scroll;\n`\n\nexport const MobileView = styled.div`\n padding: 63px 20px 20px 20px;\n width: 390px;\n background-color: #363636;\n max-height: 650px;\n overflow-y: scroll;\n`;\n","export const REPORT_COLUMNS = [\n {\n title: 'Key',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n },\n {\n title: 'Value',\n dataIndex: 'value',\n key: 'value',\n ellipsis: false,\n },\n];\n","import React, { ReactNode, useCallback, useEffect, useMemo } from 'react';\nimport {\n Comment,\n ConfirmModal,\n ContentContainer,\n SessionDetails,\n ShotDetails,\n Title\n} from 'shared/components';\nimport * as Styled from './styles';\nimport { PageHeader, Table } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport { useAppDispatch, useAppSelector, useNotifications, useReport } from 'shared/hooks';\nimport { closeModal, showModal } from 'services/store/reducers/modalReducer';\nimport {\n ESnackbarStyle,\n EUserRole,\n PostedShot,\n ReportStatus,\n Session,\n SessionComment,\n ShotComment,\n User\n} from 'shared/types';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { Redirect } from 'react-router-dom';\nimport { REPORT_STATUSES, REPORT_TITLES, REPORT_TYPES } from 'shared/constants/reports';\nimport { parseISODateFormat } from 'utils/date-utils';\nimport { REPORT_COLUMNS } from './constants';\nimport { getReportColor } from 'utils/report-utils';\nimport { deleteReport, updateReport } from '../../services/api/reportsService';\n\ntype QueryParams = {\n reportId: string;\n};\n\ntype TableRow = {\n key: string;\n value: string | ReactNode;\n};\n\nconst REPORT_BUTTONS: { status: ReportStatus; color: string; title: string }[] = [\n { status: 'valid', color: '#52C41A', title: 'Approve' },\n { status: 'invalid', color: '#FF4F4F', title: 'Decline' },\n { status: 'pending', color: '#1677ff', title: 'Pending' }\n];\n\nconst ReportPage = (): JSX.Element => {\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { reportId } = useParams<QueryParams>();\n const { openNotification } = useNotifications();\n const { report, reportedObject, isReportLoading, fetchReport } = useReport();\n\n const user = useAppSelector((state): User | null => state.auth.user);\n\n useEffect((): void => {\n fetchReport(reportId, true);\n }, [fetchReport, reportId]);\n\n const handleOpenUser = useCallback(\n (userId: number): void => history.push(`/bow-users/${userId}`),\n [history]\n );\n\n const tableRows = useMemo(\n (): TableRow[] =>\n report\n ? [\n { key: 'Type', value: REPORT_TYPES[report.reportObjectType] },\n { key: 'Category', value: REPORT_TITLES[report.category] },\n {\n key: 'Status',\n value: (\n <Styled.StatusRow color={getReportColor(report.status)}>\n {REPORT_STATUSES[report.status]}\n </Styled.StatusRow>\n )\n },\n { key: 'Created At', value: parseISODateFormat(report.createdAt, true) },\n { key: 'Description', value: report.description || '--' },\n {\n key: 'Creator',\n value: (\n <Styled.ReportLink onClick={(): void => handleOpenUser(report.reporterId)}>\n Creator\n </Styled.ReportLink>\n )\n },\n {\n key: 'Reported User',\n value: (\n <Styled.ReportLink onClick={(): void => handleOpenUser(report.accusedId)}>\n Reported User\n </Styled.ReportLink>\n )\n }\n ]\n : [],\n [report, handleOpenUser]\n );\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const showRemoveUserModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this report?'\n confirmAction={async (): Promise<void> => {\n try {\n dispatch(closeModal());\n await deleteReport(reportId);\n history.push('/reports');\n openNotification(ESnackbarStyle.SUCCESS, 'Report successfully deleted');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }}\n />\n )\n );\n };\n\n const showChangeStatusModal = (reportId: string, status: ReportStatus): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title={`${\n status === 'valid'\n ? 'You agree that the comment or image does not comply with the rules. After changing the status to Approved, the image or comment will be hidden'\n : 'You do not agree that the comment or image does not comply with the rules. After changing the status to Decline, the image or comment will continue to be displayed in the application'\n }. The status can be changed only once.`}\n modalTitle={`Change status to ${status === 'valid' ? 'Approved' : 'Decline'}?`}\n confirmAction={async (): Promise<void> => {\n try {\n dispatch(closeModal());\n await updateReport(reportId, { status });\n history.push('/reports');\n openNotification(ESnackbarStyle.SUCCESS, 'Report successfully updated');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }}\n />\n )\n );\n };\n\n const buttons = useMemo(\n (): typeof REPORT_BUTTONS =>\n report ? REPORT_BUTTONS.filter((button): boolean => button.status !== report.status) : [],\n [report]\n );\n\n if (\n user?.role &&\n !checkRolePermission(\n [EUserRole.master_admin, EUserRole.admin_user, EUserRole.moderator],\n user.role\n )\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Report Details' />\n {report && reportedObject && (\n <Styled.ReportDetails>\n <Styled.TableContainer>\n <Table\n columns={REPORT_COLUMNS}\n dataSource={[\n ...tableRows,\n {\n key: 'Actions',\n value: (\n <Styled.ReportActions>\n {report.status === 'pending' &&\n buttons.map(\n (button): JSX.Element => (\n <Styled.ReportAction\n type='primary'\n onClick={(): void =>\n showChangeStatusModal(`${report.id}`, button.status)\n }\n loading={isReportLoading}\n disabled={isReportLoading}\n color={button.color}\n >\n {button.title}\n </Styled.ReportAction>\n )\n )}\n <Styled.ReportAction\n type='primary'\n onClick={showRemoveUserModal}\n disabled={isReportLoading}\n loading={isReportLoading}\n color='#FF4F4F'\n >\n Remove Report\n </Styled.ReportAction>\n </Styled.ReportActions>\n )\n }\n ]}\n loading={isReportLoading}\n pagination={false}\n size={'middle'}\n showHeader={false}\n />\n </Styled.TableContainer>\n <Styled.MobileContainer>\n <Styled.MobileView>\n {['picture_session', 'session'].includes(report.reportObjectType) ? (\n <SessionDetails\n session={reportedObject as Session}\n reportObjectType={report.reportObjectType}\n />\n ) : (\n <ShotDetails\n shot={reportedObject as PostedShot}\n reportObjectType={report.reportObjectType}\n />\n )}\n </Styled.MobileView>\n <Styled.MobileView>\n {reportedObject.comments.length ? (\n (reportedObject.comments as (SessionComment | ShotComment)[]).map(\n (comment, index): JSX.Element => {\n const isLastComment = index === reportedObject.comments.length - 1;\n const isReportedComment =\n report.reportedShotCommentId === comment.id ||\n report.reportedSessionCommentId === comment.id;\n\n return (\n <Comment\n key={comment.id}\n comment={comment}\n containerStyles={{\n margin: '0 -20px',\n padding: `${!!index ? 15 : 0}px 20px ${!isLastComment ? 15 : 0}px`,\n borderBottom: !isLastComment ? '1px solid #707070' : 'unset',\n ...(isReportedComment && { border: '3px solid #1677FF' })\n }}\n />\n );\n }\n )\n ) : (\n <Title title='No Comments Yet' variant='title' centered />\n )}\n </Styled.MobileView>\n </Styled.MobileContainer>\n </Styled.ReportDetails>\n )}\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default ReportPage;\n","import ApiService from './api';\nimport { AxiosResponse } from 'axios';\nimport { Statistics, UserDeviceStatistics } from 'shared/types';\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `statistics`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nconst getGenerateStatisticsURL = (...rest: string[]): string => {\n const mainUrl = `generate-statistics`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getStatistics = async (): Promise<AxiosResponse<{ data: any }>> => {\n return await ApiService.get(getURL());\n};\n\nexport const getUserStatistics = async (): Promise<AxiosResponse<{ data: Statistics }>> => {\n return await ApiService.get(getURL('user-stats'));\n};\n\nexport const getUserDeviceStatistics = async (): Promise<\n AxiosResponse<{ data: UserDeviceStatistics }>\n> => {\n return await ApiService.get(getURL('user-device-stats'));\n};\n\nexport const generateStatistics = async (): Promise<AxiosResponse<any>> =>\n await ApiService.get<any>(getGenerateStatisticsURL());\n","import { useCallback, useState } from 'react';\nimport { ESnackbarStyle, Statistics } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { getUserStatistics } from 'services/api/statisticsService';\n\ntype Result = {\n statistics: Statistics | null;\n isStatisticsLoading: boolean;\n fetchStatistics: () => Promise<void>;\n};\n\nconst useStatistics = (): Result => {\n const [statistics, setStatistics] = useState<Statistics | null>(null);\n const [isStatisticsLoading, setIsStatisticsLoading] = useState<boolean>(true);\n const { openNotification } = useNotifications();\n\n const fetchStatistics = useCallback(async (): Promise<void> => {\n setIsStatisticsLoading(true);\n try {\n const response = await getUserStatistics();\n setStatistics(response.data.data);\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsStatisticsLoading(false);\n }\n }, [openNotification]);\n\n return {\n statistics,\n isStatisticsLoading,\n fetchStatistics\n };\n};\n\nexport default useStatistics;\n","import { useCallback, useState } from 'react';\nimport { ESnackbarStyle, UserDeviceStatistics } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { getUserDeviceStatistics } from 'services/api/statisticsService';\n\ntype Result = {\n statistics: UserDeviceStatistics | null;\n isStatisticsLoading: boolean;\n fetchStatistics: () => Promise<void>;\n};\n\nconst useUserDeviceStatistics = (): Result => {\n const [statistics, setStatistics] = useState<UserDeviceStatistics | null>(null);\n const [isStatisticsLoading, setIsStatisticsLoading] = useState<boolean>(true);\n const { openNotification } = useNotifications();\n\n const fetchStatistics = useCallback(async (): Promise<void> => {\n setIsStatisticsLoading(true);\n try {\n const response = await getUserDeviceStatistics();\n setStatistics(response.data.data);\n } catch (e: any) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsStatisticsLoading(false);\n }\n }, [openNotification]);\n\n return {\n statistics,\n isStatisticsLoading,\n fetchStatistics\n };\n};\n\nexport default useUserDeviceStatistics;\n","import { StatisticsUser } from 'shared/types';\nimport { AppVersionStatistics, DeviceStatistics } from './types';\n\nexport const categorizeUsersByDevice = (users: StatisticsUser[]): DeviceStatistics => {\n const categorizedUsers: DeviceStatistics = {\n iOS: [],\n Android: [],\n Unknown: []\n };\n\n users.forEach((user) => {\n const deviceSystemName = user.deviceInfo?.deviceSystemName?.toLowerCase();\n if (deviceSystemName === 'ios') {\n categorizedUsers.iOS.push(user);\n } else if (deviceSystemName === 'android') {\n categorizedUsers.Android.push(user);\n } else {\n categorizedUsers.Unknown.push(user);\n }\n });\n\n return categorizedUsers;\n};\n\nexport const categorizeUsersByAppVersion = (users: StatisticsUser[]): AppVersionStatistics => {\n const categorizedUsers: AppVersionStatistics = {};\n\n // Extract unique app versions from users\n const appVersions = Array.from(\n new Set(users.map((user) => user.deviceInfo?.appVersion || 'unknown'))\n );\n\n // Initialize categories for each app version\n appVersions.forEach((version) => {\n categorizedUsers[version] = [];\n });\n\n users.forEach((user) => {\n const appVersion: string | undefined = user.deviceInfo?.appVersion;\n if (!!appVersion && categorizedUsers.hasOwnProperty(appVersion)) {\n categorizedUsers[appVersion].push(user);\n } else {\n categorizedUsers.unknown.push(user);\n }\n });\n\n return categorizedUsers;\n};\n","import { Tag } from 'antd';\nimport { ColumnsType } from 'antd/lib/table';\nimport { renderStatusTag } from 'pages/bow-users-page/constants';\nimport { EUserStatus, StatisticsUser } from 'shared/types';\n\nexport const defaultModalState = {\n title: '',\n search: '',\n data: [],\n visible: false\n};\n\nexport const defaultDeviceStatistics = {\n iOS: [],\n Android: [],\n Unknown: []\n};\n\n// Define the columns for the parent table (user information)\nexport const columns: ColumnsType<StatisticsUser> = [\n { title: 'User ID', dataIndex: 'id', key: 'id', width: 100 },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n render: (username) => <span>{username || '-'}</span>\n },\n {\n title: 'Full name',\n key: 'fullname',\n ellipsis: true,\n render: (__, record) => (\n <span>{[record.first_name, record.last_name].filter(Boolean).join(' ') || '-'}</span>\n )\n },\n { title: 'Email', dataIndex: 'email', key: 'email' },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n render: renderStatusTag,\n filters: [\n { text: 'Active', value: EUserStatus.Active },\n { text: 'Disabled', value: EUserStatus.Disabled },\n { text: 'Pending Confirmation', value: EUserStatus.Created },\n { text: 'Deleted', value: EUserStatus.Deleted }\n ],\n onFilter: (value: string | number | boolean, record: StatisticsUser) => record.status === value\n },\n { title: 'Total Shots', dataIndex: 'total_shots', key: 'total_shots' },\n {\n title: 'Active User',\n dataIndex: 'isActiveUser',\n key: 'isActiveUser',\n render: (isActive: boolean) =>\n isActive ? <Tag color='green'>Yes</Tag> : <Tag color='red'>No</Tag>,\n filters: [\n { text: 'Yes', value: true },\n { text: 'No', value: false }\n ],\n onFilter: (value: string | number | boolean, record: StatisticsUser) =>\n record.isActiveUser === value\n },\n {\n title: 'Has Shots',\n dataIndex: 'hasShots',\n key: 'hasShots',\n render: (hasShots: boolean) =>\n hasShots ? <Tag color='green'>Yes</Tag> : <Tag color='red'>No</Tag>,\n filters: [\n { text: 'Yes', value: true },\n { text: 'No', value: false }\n ],\n onFilter: (value: string | number | boolean, record: StatisticsUser) =>\n record.hasShots === value\n }\n];\n\n// Define the columns for the nested table (device information)\nexport const expandedRowColumns = [\n { title: 'App Version', dataIndex: 'appVersion', key: 'appVersion' },\n { title: 'Device Brand', dataIndex: 'deviceBrand', key: 'deviceBrand' },\n { title: 'Device Model', dataIndex: 'deviceModel', key: 'deviceModel' },\n { title: 'Device System Name', dataIndex: 'deviceSystemName', key: 'deviceSystemName' },\n { title: 'Device System Version', dataIndex: 'deviceSystemVersion', key: 'deviceSystemVersion' }\n];\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { pick, isUndefined } from 'lodash';\nimport { Card, Modal, Statistic, Table, Spin, Row, Col, Tooltip, Input } from 'antd';\nimport { QuestionCircleOutlined } from '@ant-design/icons';\nimport { useStatistics } from 'shared/hooks/data-hooks/statistics';\nimport { categorizeUsersByAppVersion, categorizeUsersByDevice } from './helper';\nimport {\n columns,\n expandedRowColumns,\n defaultDeviceStatistics,\n defaultModalState\n} from './constants';\nimport { DeviceInfo, StatisticsUser } from 'shared/types';\nimport { AppVersionStatistics, DeviceStatistics, ModalState } from './types';\n\nconst StatisticsPage = () => {\n const [modalState, setModalState] = useState<ModalState>(defaultModalState);\n const { fetchStatistics, statistics, isStatisticsLoading } = useStatistics();\n\n // @ts-ignore\n const searchInputRef = useRef<Input>(null);\n\n useEffect(() => {\n fetchStatistics();\n }, [fetchStatistics]);\n\n const deviceStatistics: DeviceStatistics = useMemo(() => {\n if (!statistics) return defaultDeviceStatistics;\n return categorizeUsersByDevice(statistics.users);\n }, [statistics]);\n\n const appVersionStatistics: AppVersionStatistics = useMemo(() => {\n if (!statistics) return {};\n return categorizeUsersByAppVersion(statistics.users);\n }, [statistics]);\n\n const defaultExpandedRowKeys = useMemo(\n () => modalState.data.map((record: StatisticsUser) => record.id),\n [modalState.data]\n );\n\n const handleDeviceCardClick = (deviceSystemName: keyof DeviceStatistics): void => {\n const data = deviceStatistics[deviceSystemName];\n if (data) {\n setModalState({\n title: `${deviceSystemName} Device users`,\n search: '',\n visible: true,\n data\n });\n }\n };\n\n const handleAppVersionCardClick = (appVersion: keyof AppVersionStatistics): void => {\n const data = appVersionStatistics[appVersion];\n if (data) {\n setModalState({\n title: `${appVersion} version users`,\n search: '',\n visible: true,\n data\n });\n }\n };\n\n const handleModalCancel = (): void => {\n setModalState(defaultModalState);\n if (searchInputRef.current) {\n searchInputRef.current.setValue(''); // Reset input value using ref\n }\n };\n\n const handleSearch = (search: string): void => {\n setModalState((prevState) => ({ ...prevState, search }));\n };\n\n const filteredData = useMemo(() => {\n if (!modalState.search) return modalState.data;\n return modalState.data.filter((record: StatisticsUser) =>\n Object.values(pick(record, ['username', 'email', 'first_name', 'last_name'])).some(\n (value) =>\n !isUndefined(value) &&\n String(value).toLowerCase().includes(modalState.search.toLowerCase())\n )\n );\n }, [modalState.search, modalState.data]);\n\n const renderTooltipIcon = (title: string) => (\n <Tooltip title={title}>\n <QuestionCircleOutlined style={{ position: 'absolute', top: 10, right: 10, fontSize: 16 }} />\n </Tooltip>\n );\n\n return (\n <Spin spinning={isStatisticsLoading} size='large' tip='Loading...'>\n <Row gutter={[16, 16]} style={{ padding: '16px 24px' }}>\n {/* Activity */}\n <Col span={8}>\n <h1>Activity</h1>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Total number of users who have used the app')}\n <Statistic title='Total app users' value={statistics?.statistics.appUserCount || 0} />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon(\n 'Number of users who have posted at least one shot in the last month'\n )}\n <Statistic title='Active users' value={statistics?.statistics.activeUsersCount || 0} />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Number of users who have not posted any shot in the last month')}\n <Statistic\n title='Not active users'\n value={statistics?.statistics.notActiveUsersCount || 0}\n />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Number of users who have published at least one shot')}\n <Statistic\n title='Users with shots'\n value={statistics?.statistics.userWithShotsCount || 0}\n />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Number of users who have not published any shot')}\n <Statistic\n title='Users without shots'\n value={statistics?.statistics.userWithoutShotsCount || 0}\n />\n </Card>\n </Col>\n\n {/* Device */}\n <Col span={8}>\n <h1>Device</h1>\n <Card\n onClick={() => deviceStatistics.iOS.length > 0 && handleDeviceCardClick('iOS')}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n >\n {renderTooltipIcon('Number of users using iOS devices')}\n <Statistic title='iOS users' value={statistics?.statistics.iosCount || 0} />\n </Card>\n <Card\n onClick={() => deviceStatistics.Android.length > 0 && handleDeviceCardClick('Android')}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n >\n {renderTooltipIcon('Number of users using Android devices')}\n <Statistic title='Android users' value={statistics?.statistics.androidCount || 0} />\n </Card>\n <Card\n onClick={() => deviceStatistics.Unknown.length > 0 && handleDeviceCardClick('Unknown')}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n >\n {renderTooltipIcon('Number of users with unknown devices')}\n <Statistic\n title='Unknown device users'\n value={statistics?.statistics.unknownCount || 0}\n />\n </Card>\n </Col>\n\n {/* App version */}\n <Col span={8}>\n <h1>App version</h1>\n {Object.keys(appVersionStatistics).map((appVersion) => (\n <Card\n key={appVersion}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n onClick={() => handleAppVersionCardClick(appVersion)}\n >\n {renderTooltipIcon(`Number of users using ${appVersion} app version`)}\n <Statistic\n title={`${appVersion} version`}\n value={appVersionStatistics[appVersion].length}\n />\n </Card>\n ))}\n </Col>\n </Row>\n\n <Modal\n title={modalState.title}\n visible={modalState.visible}\n onOk={handleModalCancel}\n onCancel={handleModalCancel}\n width={'80%'}\n cancelButtonProps={{ hidden: true }}\n >\n <Input.Search\n ref={searchInputRef}\n placeholder='Search by username, first name, last name, or email'\n onSearch={(value) => handleSearch(value)}\n style={{ width: 440, marginBottom: 16, marginLeft: 24 }}\n />\n\n <Table\n dataSource={filteredData}\n columns={columns}\n expandable={{\n expandedRowRender: (record: StatisticsUser) =>\n Boolean(record.deviceInfo) ? (\n <Table\n columns={expandedRowColumns}\n dataSource={[record.deviceInfo as DeviceInfo]}\n pagination={false}\n />\n ) : null,\n rowExpandable: (record) => !!record.deviceInfo,\n defaultExpandedRowKeys\n }}\n rowKey={'id'}\n scroll={{ x: 850 }}\n />\n </Modal>\n </Spin>\n );\n};\n\nexport default StatisticsPage;\n","import styled from 'styled-components';\nimport { Typography } from 'antd';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n\nexport const Group = styled(Typography.Link)`\n display: flex;\n align-items: center;\n`;\n\nexport const GroupImageContainer = styled.div`\n width: 40px;\n height: 40px;\n border-radius: 50%;\n overflow: hidden;\n`;\n\nexport const GroupImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nexport const GroupName = styled.div`\n margin-left: 10px;\n`;\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { PageHeader, Table, Typography } from 'antd';\nimport * as Styled from './styles';\nimport { ContentContainer } from 'shared/components';\nimport { ESnackbarStyle, User } from 'shared/types';\nimport { useNotifications } from 'shared/hooks';\nimport { AxiosResponse } from 'axios';\nimport ApiService from 'services/api/api';\nimport GroupPlaceholder from '../../assets/images/bow-ava.png';\nimport { useHistory } from 'react-router-dom';\n\nexport type CommunityGroup = {\n id: number;\n name: string;\n ownerId: number;\n groupPictureId: string | null;\n groupPictureS3Url: string | null;\n owner?: User;\n members?: User[];\n};\n\nexport type GroupRequest = {\n accepted: boolean;\n id: number;\n userId: number;\n groupId: number;\n group: CommunityGroup;\n};\n\ntype TableGroupRequests = GroupRequest & { key: number };\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `groups`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getGroupRequests = async (): Promise<AxiosResponse<GroupRequest[]>> => {\n return await ApiService.get<GroupRequest[]>(`${getURL('all/requests')}`);\n};\n\nexport const acceptRequests = async (\n groupRequestId: string\n): Promise<AxiosResponse<CommunityGroup>> => {\n return await ApiService.post(getURL('acceptGroup'), { groupRequestId });\n};\n\nconst GroupRequestsPage = (): JSX.Element => {\n const [groupRequests, setGroupRequests] = useState<GroupRequest[]>([]);\n const [isGroupRequestsLoading, setIsGroupRequestsLoading] = useState<boolean>(true);\n\n const history = useHistory();\n const { openNotification } = useNotifications();\n\n const tableGroupRequests = useMemo(\n (): TableGroupRequests[] =>\n groupRequests.map((request): TableGroupRequests => ({ ...request, key: request.id })),\n [groupRequests]\n );\n\n const fetchGroupRequests = useCallback(async (): Promise<void> => {\n setIsGroupRequestsLoading(true);\n try {\n const response = await getGroupRequests();\n setGroupRequests(response.data);\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsGroupRequestsLoading(false);\n }\n }, [openNotification]);\n\n const acceptGroupRequest = useCallback(\n async (groupRequestId: number): Promise<void> => {\n setIsGroupRequestsLoading(true);\n try {\n await acceptRequests(`${groupRequestId}`);\n await fetchGroupRequests();\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n } finally {\n setIsGroupRequestsLoading(false);\n }\n },\n [openNotification, fetchGroupRequests]\n );\n\n useEffect((): void => {\n fetchGroupRequests();\n }, [fetchGroupRequests]);\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Group Requests' />\n <Styled.TableContainer>\n <Table\n columns={[\n {\n title: 'Group',\n dataIndex: 'group',\n key: 'group',\n ellipsis: true,\n render: (group: CommunityGroup): JSX.Element => {\n return (\n <Styled.Group onClick={(): void => history.push(`groups/${group.id}`)}>\n <Styled.GroupImageContainer>\n <Styled.GroupImage src={group.groupPictureS3Url || GroupPlaceholder} />\n </Styled.GroupImageContainer>\n <Styled.GroupName>{group.name}</Styled.GroupName>\n </Styled.Group>\n );\n }\n },\n {\n title: 'Status',\n dataIndex: 'accepted',\n key: 'accepted',\n ellipsis: true,\n render: (accepted: boolean): JSX.Element => {\n return <>{accepted ? 'ACCEPTED' : 'PENDING'}</>;\n }\n },\n {\n title: 'User Info',\n dataIndex: 'userId',\n key: 'userId',\n ellipsis: true,\n render: (userId: string): JSX.Element => {\n return (\n <Typography.Link onClick={(): void => history.push(`bow-users/${userId}`)}>\n User\n </Typography.Link>\n );\n }\n },\n {\n title: 'Actions',\n width: 150,\n render: (record: TableGroupRequests): JSX.Element => {\n return (\n <Typography.Link onClick={(): Promise<void> => acceptGroupRequest(record.id)}>\n Accept Request\n </Typography.Link>\n );\n }\n }\n ]}\n dataSource={tableGroupRequests}\n pagination={false}\n loading={isGroupRequestsLoading}\n size={'middle'}\n />\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default GroupRequestsPage;\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n\nexport const TypeRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n","import { PublicGroupStatus } from '../types';\n\nexport const PUBLIC_GROUPS_STATUSES: {[key in PublicGroupStatus]: string} = {\n pending: 'PENDING',\n accepted: 'ACCEPTED',\n rejected: 'REJECTED',\n};\n","import { PublicGroupStatus } from '../shared/types';\n\nexport const getPublicGroupColor = (type: PublicGroupStatus): string =>\n ({ rejected: '#FF4D4F', accepted: '#52C41A', pending: '#1677FF' }[type]);\n","import { PublicGroupStatus } from 'shared/types';\nimport { ReactNode } from 'react';\nimport { TypeRow } from './styles';\nimport { parseISODateFormat } from '../../utils/date-utils';\nimport { PUBLIC_GROUPS_STATUSES } from '../../shared/constants/publicGroups';\nimport { getPublicGroupColor } from '../../utils/public-groups';\n\nexport const PUBLIC_GROUPS_COLUMNS = [\n {\n title: 'Group Name',\n dataIndex: 'name',\n key: 'name',\n ellipsis: true\n },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n ellipsis: true,\n render: (status: PublicGroupStatus): ReactNode => {\n return (\n <TypeRow color={getPublicGroupColor(status)}>{PUBLIC_GROUPS_STATUSES[status]}</TypeRow>\n );\n }\n },\n {\n title: 'Type',\n dataIndex: 'isNew',\n key: 'isNew',\n ellipsis: true,\n render: (isNew: boolean): ReactNode => {\n return (\n <>{isNew ? 'New group' : 'Existing group'}</>\n );\n }\n },\n {\n title: 'Date',\n dataIndex: 'moderationDate',\n key: 'moderationDate',\n ellipsis: true,\n render: (date: string): ReactNode => {\n return <>{parseISODateFormat(date, true)}</>;\n }\n }\n];\n","import React, { useEffect, useMemo } from 'react';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { EUserRole, PublicGroup, User } from 'shared/types';\nimport { Redirect } from 'react-router';\nimport { useAppSelector, usePublicGroups } from 'shared/hooks';\nimport * as Styled from './styles';\nimport { PageHeader, Table } from 'antd';\nimport { PaginationContainer } from 'shared/styles';\nimport Pagination from 'antd/lib/pagination';\nimport { ContentContainer } from 'shared/components';\nimport { useHistory } from 'react-router-dom';\nimport { PUBLIC_GROUPS_COLUMNS } from './constants';\nimport { ColumnType } from 'antd/lib/table/interface';\n\ntype TablePublicGroup = PublicGroup & { key: number };\n\nconst PublicGroupsPage = (): JSX.Element => {\n const history = useHistory();\n const user = useAppSelector((state): User | null => state.auth.user);\n\n const {\n items,\n pagination: { currentPage, pageSize, totalItemsCount },\n isPublicGroupsLoading,\n fetchPublicGroups,\n onChangePagination\n } = usePublicGroups();\n\n useEffect((): void => {\n fetchPublicGroups();\n }, [fetchPublicGroups]);\n\n const tablePublicGroups = useMemo(\n (): TablePublicGroup[] =>\n items.map((publicGroup): TablePublicGroup => ({ ...publicGroup, key: publicGroup.id })),\n [items]\n );\n\n const handleRowClick = (publicGroup: TablePublicGroup): void => {\n history.push(`/public-groups/${publicGroup.id}`);\n };\n\n if (\n user?.role &&\n !checkRolePermission(\n [EUserRole.moderator, EUserRole.admin_user, EUserRole.master_admin],\n user.role\n )\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Public Groups' />\n <Styled.TableContainer>\n <Table\n columns={PUBLIC_GROUPS_COLUMNS.map((column): ColumnType<TablePublicGroup> => {\n return {\n ...column,\n onCell: (record: TablePublicGroup): { onClick: () => void } => {\n return {\n onClick: (): void => handleRowClick(record)\n };\n }\n };\n })}\n dataSource={tablePublicGroups}\n pagination={false}\n loading={isPublicGroupsLoading}\n size={'middle'}\n />\n <PaginationContainer>\n <Pagination\n pageSize={pageSize}\n current={currentPage}\n total={totalItemsCount}\n onChange={onChangePagination}\n />\n </PaginationContainer>\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default PublicGroupsPage;\n","import styled from 'styled-components';\nimport { Button } from 'antd';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PublicGroupDetails = styled.div`\n width: 800px;\n`\n\nexport const TableContainer = styled.div`\n margin-top: 24px;\n overflow-y: auto;\n`;\n\nexport const StatusRow = styled.div<{ color: string }>`\n color: ${({ color }): string => color};\n`;\n\nexport const PublicGroupActions = styled.div`\n display: flex;\n`;\n\nexport const PublicGroupAction = styled(Button)<{ color: string }>`\n background: ${({ color }): string => color};\n border-color: ${({ color }): string => color};\n\n & + & {\n margin-left: 10px;\n }\n\n &:hover, &:focus {\n background: ${({ color }): string => color};\n border-color: ${({ color }): string => color};\n opacity: 0.8;\n }\n`;\n\nexport const Group = styled.div`\n position: relative;\n margin-top: 20px;\n padding: 20px 0 30px;\n height: 205px;\n width: 390px;\n background-color: #363636;\n`;\n\nexport const GroupImg = styled.img`\n height: 100%;\n width: 100%;\n`;\n\nexport const GroupName = styled.div`\n position: absolute;\n bottom: 15px;\n left: 20px\n`;\n\nexport const RadioTitle = styled.div`\n margin-bottom: 5px;\n`\n\n","export const REPORT_COLUMNS = [\n {\n title: 'Key',\n dataIndex: 'key',\n key: 'key',\n ellipsis: true,\n },\n {\n title: 'Value',\n dataIndex: 'value',\n key: 'value',\n ellipsis: false,\n },\n];\n","export default __webpack_public_path__ + \"static/media/group-ava.1ab6cd3c.jpg\";","import React, { ReactNode, useEffect, useMemo, useState } from 'react';\nimport { ConfirmModal, ContentContainer, Title } from 'shared/components';\nimport * as Styled from './styles';\nimport { Modal, PageHeader, Radio, Table } from 'antd';\nimport { useHistory, useParams } from 'react-router';\nimport {\n useAppDispatch, useAppSelector, useNotifications, usePublicGroup,\n} from 'shared/hooks';\nimport { ESnackbarStyle, EUserRole, User } from 'shared/types';\nimport { checkRolePermission } from 'utils/role-utils';\nimport { Redirect } from 'react-router-dom';\nimport { parseISODateFormat } from 'utils/date-utils';\nimport { REPORT_COLUMNS } from './constants';\nimport { getPublicGroupColor } from 'utils/public-groups';\nimport { PUBLIC_GROUPS_STATUSES } from 'shared/constants/publicGroups';\nimport GroupImg from 'assets/images/group-ava.jpg';\nimport {\n closeModal, showModal,\n} from '../../services/store/reducers/modalReducer';\n\ntype QueryParams = {\n publicGroupId: string;\n};\n\ntype TableRow = {\n key: string;\n value: string | ReactNode;\n};\n\nconst PublicGroupPage = (): JSX.Element => {\n const history = useHistory();\n const dispatch = useAppDispatch();\n const { publicGroupId } = useParams<QueryParams>();\n\n const {\n publicGroup,\n isPublicGroupLoading,\n fetchPublicGroup,\n rejectPublicGroup,\n acceptPublicGroup\n } = usePublicGroup();\n\n const { openNotification } = useNotifications();\n\n const [rejectModal, setRejectModal] = useState(false);\n const [type, setType] = useState<'name' | 'image'>('name');\n\n const user = useAppSelector((state): User | null => state.auth.user);\n\n useEffect((): void => {\n fetchPublicGroup(publicGroupId);\n }, [fetchPublicGroup, publicGroupId]);\n\n const tableRows = useMemo(\n (): TableRow[] =>\n publicGroup\n ? [\n {\n key: 'Name',\n value: publicGroup.name\n },\n {\n key: 'Status',\n value: (\n <Styled.StatusRow color={getPublicGroupColor(publicGroup.status)}>\n {PUBLIC_GROUPS_STATUSES[publicGroup.status]}\n </Styled.StatusRow>\n )\n },\n {\n key: 'Type',\n value: publicGroup.isNew ? 'New group' : 'Existing group'\n },\n { key: 'Date', value: parseISODateFormat(publicGroup.moderationDate, true) }\n ]\n : [],\n [publicGroup]\n );\n\n const goBack = (): void => {\n history.goBack();\n };\n\n const showApproveModal = (publicGroupId: string): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title={'By clicking the \"Accept\" button, you confirm that the content of the group complies with the rules. After clicking the \"Accept\" button, the group became public.'}\n modalTitle={'Confirmation of the request to create a public group.'}\n confirmAction={async (): Promise<void> => {\n try {\n dispatch(closeModal());\n await acceptPublicGroup(publicGroupId);\n history.push('/public-groups');\n openNotification(ESnackbarStyle.SUCCESS, 'Request confirmed!');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }}\n />\n )\n );\n };\n\n if (\n user?.role &&\n !checkRolePermission(\n [EUserRole.master_admin, EUserRole.admin_user, EUserRole.moderator],\n user.role\n )\n ) {\n return <Redirect to={'/'} />;\n }\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={goBack} title='Public Group Details' />\n {publicGroup && (\n <Styled.PublicGroupDetails>\n <Styled.TableContainer>\n <Table\n columns={REPORT_COLUMNS}\n dataSource={[\n ...tableRows,\n ...(publicGroup.status === 'pending'\n ? [\n {\n key: 'Actions',\n value: (\n <Styled.PublicGroupActions>\n <Styled.PublicGroupAction\n type='primary'\n color='#52C41A'\n onClick={(): void => showApproveModal(publicGroupId)}\n >\n Accept\n </Styled.PublicGroupAction>\n <Styled.PublicGroupAction\n type='primary'\n color='#FF4D4F'\n onClick={(): void => setRejectModal(true)}\n >\n Reject\n </Styled.PublicGroupAction>\n </Styled.PublicGroupActions>\n )\n }\n ]\n : [])\n ]}\n loading={isPublicGroupLoading}\n pagination={false}\n size={'middle'}\n showHeader={false}\n />\n </Styled.TableContainer>\n <Styled.Group>\n <Styled.GroupImg src={publicGroup.imageUrl || GroupImg} />\n <Styled.GroupName>\n <Title\n title={publicGroup.name}\n variant='title'\n titleStyles={{ lineHeight: '23px' }}\n />\n <Title title='GROUP' variant='light' titleStyles={{ lineHeight: '18px' }} />\n </Styled.GroupName>\n </Styled.Group>\n </Styled.PublicGroupDetails>\n )}\n <Modal\n visible={rejectModal}\n title='Rejecting a request to create a public group.'\n onCancel={(): void => setRejectModal(false)}\n onOk={async (): Promise<void> => {\n try {\n await rejectPublicGroup(publicGroupId, type);\n history.push('/public-groups');\n openNotification(ESnackbarStyle.SUCCESS, 'Request rejected!');\n } catch (e) {\n openNotification(ESnackbarStyle.ERROR, e.message);\n }\n }}\n >\n <>\n <Styled.RadioTitle>Choose the reason:</Styled.RadioTitle>\n <Radio.Group\n options={[\n { label: 'INAPPROPRIATE NAME', value: 'name' },\n { label: 'INAPPROPRIATE IMAGE', value: 'image' }\n ]}\n onChange={(e): void => setType(e.target.value)}\n value={type}\n optionType='button'\n />\n </>\n </Modal>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default PublicGroupPage;\n","import { AxiosResponse } from 'axios';\nimport ApiService from './api';\nimport { Event, EventGroup, EventUser } from 'shared/types';\n\nconst getURL = (...rest: string[]): string => {\n const mainUrl = `events`;\n return rest.reduce((resultUrl: string, item: string): string => resultUrl + `/${item}`, mainUrl);\n};\n\nexport const getGroupsWithEvents = async (): Promise<AxiosResponse<EventGroup[]>> => {\n return ApiService.get(getURL('groups', 'groups-with-events'));\n};\n\nexport const getGroupEvents = async (groupId: string): Promise<AxiosResponse<Event[]>> => {\n return ApiService.get(getURL(groupId, 'list-admin'));\n};\n\nexport const getEventById = async (eventId: string): Promise<AxiosResponse<Event>> => {\n return ApiService.get(getURL(eventId));\n};\n\nexport const getEventUsers = async (eventId: string): Promise<AxiosResponse<EventUser[]>> => {\n return ApiService.get(getURL(eventId, 'users-with-shots'));\n};\n\nexport const deleteEvent = async (eventId: string): Promise<AxiosResponse<Event>> => {\n return ApiService.delete(getURL(eventId));\n}\n","import { Tag } from 'antd';\nimport { ColumnsType } from 'antd/lib/table';\nimport { EventGroup, EventStatus } from 'shared/types';\n\nexport const COLUMNS: ColumnsType<EventGroup> = [\n {\n title: 'Group Name',\n dataIndex: 'name',\n key: 'name',\n ellipsis: true\n },\n {\n title: 'Upcoming',\n key: 'created',\n dataIndex: 'created',\n ellipsis: true,\n sorter: (a: EventGroup, b: EventGroup) =>\n a.eventCountByStatus.created - b.eventCountByStatus.created,\n render: (__, record: EventGroup) => (\n <span>{renderStatusTag('created', record.eventCountByStatus.created) ?? '-'}</span>\n )\n },\n {\n title: 'Past',\n key: 'finished',\n dataIndex: 'finished',\n ellipsis: true,\n sorter: (a: EventGroup, b: EventGroup) =>\n a.eventCountByStatus.finished - b.eventCountByStatus.finished,\n render: (__, record: EventGroup) => (\n <span>{renderStatusTag('finished', record.eventCountByStatus.finished) ?? '-'}</span>\n )\n },\n {\n title: 'Ongoing',\n key: 'active',\n dataIndex: 'active',\n ellipsis: true,\n sorter: (a: EventGroup, b: EventGroup) =>\n a.eventCountByStatus.active - b.eventCountByStatus.active,\n render: (__, record: EventGroup) => (\n <span>{renderStatusTag('active', record.eventCountByStatus.active) ?? '-'}</span>\n )\n }\n];\n\nexport function renderStatusTag(status: EventStatus, count: number): JSX.Element {\n switch (status) {\n case 'created':\n return (\n <Tag color='blue' style={{ minWidth: 30, textAlign: 'center' }}>\n {count}\n </Tag>\n );\n case 'finished':\n return (\n <Tag color='volcano' style={{ minWidth: 30, textAlign: 'center' }}>\n {count}\n </Tag>\n );\n case 'active':\n return (\n <Tag color='green' style={{ minWidth: 30, textAlign: 'center' }}>\n {count}\n </Tag>\n );\n default:\n return <span>{status || '-'}</span>;\n }\n}\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","// Libs\nimport React, { useEffect, useMemo, useState } from 'react';\nimport _ from 'lodash';\n\n// Components\nimport { Input, PageHeader, Table } from 'antd';\nimport { ContentContainer } from 'shared/components';\n\n// Services\nimport { getGroupsWithEvents } from 'services/api/eventsService';\n\n// Hooks\nimport { useHistory } from 'react-router-dom';\n\n// Constants\nimport { COLUMNS } from './constants';\n\n// Types\nimport { EventGroup } from 'shared/types';\n\n// Styles\nimport * as Styled from './styles';\n\nconst EventsPage = (): JSX.Element => {\n const [groups, setGroups] = useState<EventGroup[]>([]);\n const [loading, setLoading] = useState<boolean>(false);\n const [searchValue, setSearchValue] = useState<string>('');\n\n const history = useHistory();\n\n useEffect(() => {\n fetchGroupsWithEvents();\n // eslint-disable-next-line\n }, []);\n\n const filteredGroups = useMemo(() => {\n return groups.filter((record: EventGroup) =>\n Object.values(_.pick(record, ['id', 'name'])).some(\n (value) =>\n !_.isUndefined(value) && String(value).toLowerCase().includes(searchValue.toLowerCase())\n )\n );\n }, [groups, searchValue]);\n\n const fetchGroupsWithEvents = async (): Promise<void> => {\n try {\n setLoading(true);\n const response = await getGroupsWithEvents();\n setGroups(response.data);\n } catch (err: any) {\n // tslint:disable-next-line:no-console\n console.error('[fetchGroupsWithEvents] ', err);\n } finally {\n setLoading(false);\n }\n };\n\n const handleRowClick = (record: EventGroup): void => {\n history.push(`/group-events/${record.id}`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader title='Group Events' />\n\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input.Search\n placeholder='Search by group'\n onSearch={(value) => setSearchValue(value)}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n\n <Styled.TableContainer>\n <Table\n columns={COLUMNS}\n dataSource={filteredGroups}\n pagination={false}\n loading={loading}\n size={'middle'}\n rowKey='id'\n onRow={(record) => ({\n onClick: () => handleRowClick(record)\n })}\n />\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default EventsPage;\n","import { format } from 'date-fns';\nimport { Tag } from 'antd';\nimport { ColumnsType } from 'antd/lib/table';\nimport { Event, EventStatus } from 'shared/types';\n\nconst statusTitleMap: Record<EventStatus, string> = {\n created: 'Upcoming',\n finished: 'Past',\n active: 'Ongoing'\n};\n\nconst getStatusTitle = (status: EventStatus): string => statusTitleMap[status] || status;\n\nexport const COLUMNS: ColumnsType<Event> = [\n {\n title: 'Event Name',\n dataIndex: 'name',\n key: 'name',\n ellipsis: true\n },\n {\n title: 'Start date',\n dataIndex: 'startDate',\n key: 'startDate',\n ellipsis: true,\n render: (timestamp: number) => <>{format(new Date(timestamp), 'yyyy-MM-dd hh:mm:ss a')}</>,\n sorter: (a, b) => a.startDate - b.startDate\n },\n {\n title: 'End date',\n dataIndex: 'endDate',\n key: 'endDate',\n ellipsis: true,\n render: (timestamp: number) => <>{format(new Date(timestamp), 'yyyy-MM-dd hh:mm:ss a')}</>,\n sorter: (a, b) => a.endDate - b.endDate\n },\n {\n title: 'Shots Per Day',\n dataIndex: 'shotsPerDay',\n key: 'shotsPerDay',\n ellipsis: true\n },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n ellipsis: true,\n render: renderStatusTag,\n filters: [\n { text: getStatusTitle('created'), value: 'created' },\n { text: getStatusTitle('finished'), value: 'finished' },\n { text: getStatusTitle('active'), value: 'active' }\n ] as { text: string; value: EventStatus }[],\n onFilter: (value, record) => record.status === value\n }\n];\n\nexport function renderStatusTag(status: EventStatus): JSX.Element {\n switch (status) {\n case 'created':\n return <Tag color='blue'>{getStatusTitle('created')}</Tag>;\n case 'finished':\n return <Tag color='volcano'>{getStatusTitle('finished')}</Tag>;\n case 'active':\n return <Tag color='green'>{getStatusTitle('active')}</Tag>;\n default:\n return <span>{status || '-'}</span>;\n }\n}\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n justify-content: space-between;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","// Libs\nimport React, { useEffect, useMemo, useState } from 'react';\nimport _ from 'lodash';\n\n// Components\nimport { Input, PageHeader, Table } from 'antd';\nimport { ContentContainer } from 'shared/components';\n\n// Services\nimport { getGroup } from 'services/api/groupsService';\nimport { getGroupEvents } from 'services/api/eventsService';\n\n// Hooks\nimport { useHistory, useParams } from 'react-router-dom';\n\n// Constants\nimport { COLUMNS } from './constants';\n\n// Types\nimport { Event, UserGroup } from 'shared/types';\n\n// Styles\nimport * as Styled from './styles';\n\ntype QueryParams = {\n groupId: string;\n};\n\nconst GroupEventsPage = (): JSX.Element => {\n const [group, setGroup] = useState<UserGroup | null>(null);\n const [events, setEvents] = useState<Event[]>([]);\n const [loading, setLoading] = useState<boolean>(false);\n const [searchValue, setSearchValue] = useState<string>('');\n\n const history = useHistory();\n const { groupId } = useParams<QueryParams>();\n\n const filteredEvents = useMemo(() => {\n return events.filter((record: Event) =>\n Object.values(_.pick(record, ['id', 'name'])).some(\n (value) =>\n !_.isUndefined(value) && String(value).toLowerCase().includes(searchValue.toLowerCase())\n )\n );\n }, [events, searchValue]);\n\n useEffect(() => {\n initialize();\n // eslint-disable-next-line\n }, []);\n\n const initialize = async () => {\n try {\n setLoading(true);\n await fetchGroup(groupId);\n await fetchGroupEvents(groupId);\n } finally {\n setLoading(false);\n }\n };\n\n const fetchGroup = async (groupId: string): Promise<void> => {\n try {\n const response = await getGroup(groupId);\n setGroup(response.data);\n } catch (err) {\n // tslint:disable-next-line:no-console\n console.error('[fetchGroup] ', err);\n }\n };\n\n const fetchGroupEvents = async (groupId: string): Promise<void> => {\n try {\n const response = await getGroupEvents(groupId);\n setEvents(response.data);\n } catch (err: any) {\n // tslint:disable-next-line:no-console\n console.error('[fetchGroupEvents] ', err);\n }\n };\n\n const handleRowClick = (record: Event): void => {\n history.push(`/group-events/${groupId}/event/${record.id}`);\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={() => history.push('/group-events')} title={`Group - ${group?.name ?? ''} events`} />\n\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input.Search\n placeholder='Search by event'\n onSearch={(value) => setSearchValue(value)}\n allowClear\n />\n </Styled.SearchInput>\n </Styled.PageHeader>\n\n <Styled.TableContainer>\n <Table\n columns={COLUMNS}\n dataSource={filteredEvents}\n pagination={false}\n loading={loading}\n size={'middle'}\n rowKey='id'\n onRow={(record) => ({\n onClick: () => handleRowClick(record)\n })}\n />\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default GroupEventsPage;\n","import { format } from 'date-fns';\nimport { ColumnsType } from 'antd/lib/table';\nimport { EventUser } from 'shared/types';\n\nexport const COLUMNS: ColumnsType<EventUser> = [\n { title: 'User ID', dataIndex: 'id', key: 'id', width: 100 },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n render: (username) => <span>{username || '-'}</span>\n },\n {\n title: 'Full name',\n key: 'fullname',\n ellipsis: true,\n render: (__, record) => (\n <span>{[record.firstName, record.lastName].filter(Boolean).join(' ') || '-'}</span>\n )\n },\n { title: 'Email', dataIndex: 'email', key: 'email' },\n {\n title: 'Total score',\n key: 'totalScore',\n dataIndex: 'leaderboard',\n ellipsis: true,\n render: (leaderboard) => <span>{leaderboard?.totalScore ?? '-'}</span>,\n defaultSortOrder: 'descend',\n sorter: (a, b) => (a.leaderboard?.totalScore ?? 0) - (b.leaderboard?.totalScore ?? 0)\n },\n {\n title: 'Shots',\n key: 'shotsCount',\n dataIndex: 'shotsCount',\n ellipsis: true,\n render: (__, record: EventUser) => <span>{record.shots?.length ?? 0}</span>,\n sorter: (a, b) => (a.shots?.length ?? 0) - (b.shots?.length ?? 0)\n },\n {\n title: 'Average Score',\n key: 'averageScore',\n dataIndex: 'leaderboard',\n ellipsis: true,\n render: (leaderboard) => <span>{leaderboard?.averageScore ?? '-'}</span>,\n sorter: (a, b) => (a.leaderboard?.averageScore ?? 0) - (b.leaderboard?.averageScore ?? 0)\n }\n];\n\nexport const EXPANDED_ROW_COLUMNS: ColumnsType<EventUser['shots'][0]> = [\n {\n title: 'Ordinal number',\n dataIndex: 'ordinalNumber',\n key: 'ordinalNumber',\n width: 150,\n sorter: (a, b) => a.ordinalNumber - b.ordinalNumber\n },\n { title: 'Shot id', dataIndex: 'shotId', key: 'shotId', ellipsis: true },\n {\n title: 'Timestamp',\n dataIndex: 'timestamp',\n key: 'timestamp',\n render: (timestamp: number) => <>{format(new Date(timestamp), 'yyyy-MM-dd hh:mm:ss a')}</>,\n sorter: (a, b) => a.timestamp - b.timestamp\n },\n {\n title: 'Score',\n dataIndex: 'score',\n key: 'score',\n width: 200,\n defaultSortOrder: 'ascend',\n sorter: (a, b) => a.score - b.score\n }\n];\n","import styled from 'styled-components';\n\nexport const PageContainer = styled.div`\n width: 100%;\n height: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n\n .ant-page-header {\n padding: 16px 0;\n }\n`;\n\nexport const PageHeader = styled.div`\n display: flex;\n`;\n\nexport const SearchInput = styled.div`\n width: 300px;\n`;\n\nexport const RemoveButton = styled.div`\n margin-left: 30px;\n\n & button {\n background: #f5222d;\n color: #fff;\n border-radius: 4px;\n transition: all .2s;\n }\n\n & button:hover, button:focus {\n opacity: 0.8;\n background: #f5222d;\n color: #fff;\n border: 1px solid #fff;\n }\n`;\n\n\nexport const TableContainer = styled.div`\n margin-top: 30px;\n overflow: auto;\n\n & tbody tr {\n cursor: pointer;\n }\n\n & .ant-collapse-header {\n font-weight: bold;\n font-size: 20px;\n }\n`;\n","// Libs\nimport React, { useEffect, useMemo, useState } from 'react';\nimport _ from 'lodash';\n\n// Components\nimport { Button, Input, PageHeader, Table } from 'antd';\nimport { ConfirmModal, ContentContainer } from 'shared/components';\n\n// Services\nimport {\n deleteEvent, getEventById, getEventUsers,\n} from 'services/api/eventsService';\n\n// Hooks\nimport { useHistory, useParams } from 'react-router-dom';\n\n// Constants\nimport { COLUMNS, EXPANDED_ROW_COLUMNS } from './constants';\n\n// Types\nimport { ESnackbarStyle, Event, EventUser } from 'shared/types';\n\n// Styles\nimport * as Styled from './styles';\nimport { DeleteOutlined } from '@ant-design/icons';\nimport {\n closeModal, showModal,\n} from '../../services/store/reducers/modalReducer';\nimport { useAppDispatch, useNotifications } from '../../shared/hooks';\n\ntype QueryParams = {\n groupId: string;\n eventId: string;\n};\n\nconst GroupEventPage = (): JSX.Element => {\n const [event, setEvent] = useState<Event | null>(null);\n const [users, setUsers] = useState<EventUser[]>([]);\n const [loading, setLoading] = useState<boolean>(false);\n const [searchValue, setSearchValue] = useState<string>('');\n\n const history = useHistory();\n const { eventId, groupId } = useParams<QueryParams>();\n const dispatch = useAppDispatch();\n const { openNotification } = useNotifications();\n\n const filteredUsers = useMemo(() => {\n return users.filter((record: EventUser) =>\n Object.values(_.pick(record, ['id', 'username', 'email', 'firstName', 'lastName'])).some(\n (value) =>\n !_.isUndefined(value) && String(value).toLowerCase().includes(searchValue.toLowerCase())\n )\n );\n }, [users, searchValue]);\n\n useEffect(() => {\n initialize();\n // eslint-disable-next-line\n }, []);\n\n const initialize = async () => {\n try {\n setLoading(true);\n await fetchEvent(eventId);\n await fetchEventUsers(eventId);\n } finally {\n setLoading(false);\n }\n };\n\n const fetchEvent = async (eventId: string): Promise<void> => {\n try {\n const response = await getEventById(eventId);\n setEvent(response.data);\n } catch (err: any) {\n // tslint:disable-next-line:no-console\n console.error('[fetchEventUsers] ', err);\n }\n };\n\n const fetchEventUsers = async (eventId: string): Promise<void> => {\n try {\n const response = await getEventUsers(eventId);\n setUsers(response.data);\n } catch (err: any) {\n // tslint:disable-next-line:no-console\n console.error('[fetchEventUsers] ', err);\n }\n };\n\n const showRemoveEventModal = (): void => {\n dispatch(\n showModal(\n <ConfirmModal\n title='Do you really want to remove this event?'\n confirmAction={async (): Promise<void> => {\n dispatch(closeModal());\n await deleteEvent(eventId);\n history.push(`/group-events/${groupId}`);\n openNotification(ESnackbarStyle.SUCCESS, 'Event successfully deleted');\n }}\n />\n )\n );\n };\n\n return (\n <ContentContainer>\n <Styled.PageContainer>\n <PageHeader onBack={() => history.goBack()} title={`Event - ${event?.name ?? eventId}`} />\n\n <Styled.PageHeader>\n <Styled.SearchInput>\n <Input.Search\n placeholder='Search by user'\n onSearch={(value): void => setSearchValue(value)}\n allowClear\n />\n </Styled.SearchInput>\n <Styled.RemoveButton>\n <Button\n icon={<DeleteOutlined />}\n type='default'\n onClick={showRemoveEventModal}\n >\n Remove event\n </Button>\n </Styled.RemoveButton>\n </Styled.PageHeader>\n\n <Styled.TableContainer>\n <Table\n rowKey='id'\n size={'middle'}\n pagination={false}\n loading={loading}\n dataSource={filteredUsers}\n columns={COLUMNS}\n expandable={{\n expandedRowRender: (record: EventUser) => (\n <Table\n columns={EXPANDED_ROW_COLUMNS}\n dataSource={record.shots}\n pagination={false}\n />\n ),\n rowExpandable: (record) => record.shots.length > 0\n }}\n />\n </Styled.TableContainer>\n </Styled.PageContainer>\n </ContentContainer>\n );\n};\n\nexport default GroupEventPage;\n","import { UserDeviceStatisticsUser, UserDeviceInfo } from 'shared/types';\nimport { AppVersionStatistics, DeviceStatistics } from './types';\n\nexport const categorizeUsersByDevice = (users: UserDeviceStatisticsUser[]): DeviceStatistics => {\n const categorizedUsers: DeviceStatistics = {\n iOS: [],\n Android: [],\n Unknown: []\n };\n\n users.forEach((user) => {\n if (user.devices.length > 0) {\n const categorizedDevices = user.devices.reduce(\n (acc, device) => {\n const deviceSystemName = device.deviceSystemName?.toLowerCase();\n if (deviceSystemName === 'ios') {\n acc.iOS.push(device);\n } else if (deviceSystemName === 'android') {\n acc.Android.push(device);\n } else {\n acc.Unknown.push(device);\n }\n return acc;\n },\n {\n iOS: [] as UserDeviceInfo[],\n Android: [] as UserDeviceInfo[],\n Unknown: [] as UserDeviceInfo[]\n }\n );\n\n if (categorizedDevices.iOS.length > 0) {\n categorizedUsers.iOS.push({ ...user, devices: categorizedDevices.iOS });\n }\n if (categorizedDevices.Android.length > 0) {\n categorizedUsers.Android.push({ ...user, devices: categorizedDevices.Android });\n }\n if (categorizedDevices.Unknown.length > 0) {\n categorizedUsers.Unknown.push({ ...user, devices: categorizedDevices.Unknown });\n }\n } else {\n categorizedUsers.Unknown.push(user);\n }\n });\n\n return categorizedUsers;\n};\n\nexport const categorizeUsersByAppVersion = (\n users: UserDeviceStatisticsUser[]\n): AppVersionStatistics => {\n const categorizedUsers: AppVersionStatistics = {};\n const UNKNOWN_VERSION_KEY = 'unknown';\n\n users.forEach((user) => {\n if (user.devices.length > 0) {\n const categorizedDevicesByAppVersion = user.devices.reduce((acc, device) => {\n const appVersion = device.appVersion || UNKNOWN_VERSION_KEY;\n if (!acc[appVersion]) {\n acc[appVersion] = [];\n }\n acc[appVersion].push(device);\n return acc;\n }, {} as Record<string, UserDeviceInfo[]>);\n\n Object.keys(categorizedDevicesByAppVersion).forEach((appVersion) => {\n if (!categorizedUsers[appVersion]) {\n categorizedUsers[appVersion] = [];\n }\n\n if (!categorizedUsers[appVersion].some((u) => u.id === user.id)) {\n categorizedUsers[appVersion].push({\n ...user,\n devices: categorizedDevicesByAppVersion[appVersion]\n });\n }\n });\n } else {\n if (!categorizedUsers[UNKNOWN_VERSION_KEY]) {\n categorizedUsers[UNKNOWN_VERSION_KEY] = [];\n }\n categorizedUsers[UNKNOWN_VERSION_KEY].push(user);\n }\n });\n\n return categorizedUsers;\n};\n","import { Tag } from 'antd';\nimport { ColumnsType } from 'antd/lib/table';\nimport { renderStatusTag } from 'pages/bow-users-page/constants';\nimport { EUserStatus, UserDeviceStatisticsUser } from 'shared/types';\n\nexport const defaultModalState = {\n title: '',\n search: '',\n data: [],\n visible: false\n};\n\nexport const defaultDeviceStatistics = {\n iOS: [],\n Android: [],\n Unknown: []\n};\n\n// Define the columns for the parent table (user information)\nexport const columns: ColumnsType<UserDeviceStatisticsUser> = [\n { title: 'User ID', dataIndex: 'id', key: 'id', width: 100 },\n {\n title: 'Username',\n dataIndex: 'username',\n key: 'username',\n ellipsis: true,\n render: (username) => <span>{username || '-'}</span>\n },\n {\n title: 'Full name',\n key: 'fullname',\n ellipsis: true,\n render: (__, record) => (\n <span>{[record.first_name, record.last_name].filter(Boolean).join(' ') || '-'}</span>\n )\n },\n { title: 'Email', dataIndex: 'email', key: 'email' },\n {\n title: 'Status',\n dataIndex: 'status',\n key: 'status',\n render: renderStatusTag,\n filters: [\n { text: 'Active', value: EUserStatus.Active },\n { text: 'Disabled', value: EUserStatus.Disabled },\n { text: 'Pending Confirmation', value: EUserStatus.Created },\n { text: 'Deleted', value: EUserStatus.Deleted }\n ],\n onFilter: (value: string | number | boolean, record: UserDeviceStatisticsUser) =>\n record.status === value\n },\n { title: 'Total Shots', dataIndex: 'total_shots', key: 'total_shots' },\n {\n title: 'Active User',\n dataIndex: 'isActiveUser',\n key: 'isActiveUser',\n render: (isActive: boolean) =>\n isActive ? <Tag color='green'>Yes</Tag> : <Tag color='red'>No</Tag>,\n filters: [\n { text: 'Yes', value: true },\n { text: 'No', value: false }\n ],\n onFilter: (value: string | number | boolean, record: UserDeviceStatisticsUser) =>\n record.isActiveUser === value\n },\n {\n title: 'Has Shots',\n dataIndex: 'hasShots',\n key: 'hasShots',\n render: (hasShots: boolean) =>\n hasShots ? <Tag color='green'>Yes</Tag> : <Tag color='red'>No</Tag>,\n filters: [\n { text: 'Yes', value: true },\n { text: 'No', value: false }\n ],\n onFilter: (value: string | number | boolean, record: UserDeviceStatisticsUser) =>\n record.hasShots === value\n }\n];\n\n// Define the columns for the nested table (device information)\nexport const expandedRowColumns = [\n { title: 'App Version', dataIndex: 'appVersion', key: 'appVersion' },\n { title: 'Device Id', dataIndex: 'uniqueDeviceId', key: 'uniqueDeviceId' },\n { title: 'Device Brand', dataIndex: 'deviceBrand', key: 'deviceBrand' },\n { title: 'Device Model', dataIndex: 'deviceModel', key: 'deviceModel' },\n { title: 'Device System Name', dataIndex: 'deviceSystemName', key: 'deviceSystemName' },\n { title: 'Device System Version', dataIndex: 'deviceSystemVersion', key: 'deviceSystemVersion' }\n];\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { pick, isUndefined } from 'lodash';\nimport { Card, Modal, Statistic, Table, Spin, Row, Col, Tooltip, Input } from 'antd';\nimport { QuestionCircleOutlined } from '@ant-design/icons';\nimport { useUserDeviceStatistics } from 'shared/hooks/data-hooks/statistics';\nimport { categorizeUsersByAppVersion, categorizeUsersByDevice } from './helper';\nimport {\n columns,\n expandedRowColumns,\n defaultDeviceStatistics,\n defaultModalState\n} from './constants';\nimport { UserDeviceStatisticsUser } from 'shared/types';\nimport { AppVersionStatistics, DeviceStatistics, ModalState } from './types';\n\nconst UserDeviceStatisticsPage = () => {\n const [modalState, setModalState] = useState<ModalState>(defaultModalState);\n const { fetchStatistics, statistics, isStatisticsLoading } = useUserDeviceStatistics();\n\n // @ts-ignore\n const searchInputRef = useRef<Input>(null);\n\n useEffect(() => {\n fetchStatistics();\n }, [fetchStatistics]);\n\n const deviceStatistics: DeviceStatistics = useMemo(() => {\n if (!statistics) return defaultDeviceStatistics;\n return categorizeUsersByDevice(statistics.users);\n }, [statistics]);\n\n const appVersionStatistics: AppVersionStatistics = useMemo(() => {\n if (!statistics) return {};\n return categorizeUsersByAppVersion(statistics.users);\n }, [statistics]);\n\n const defaultExpandedRowKeys = useMemo(\n () => modalState.data.map((record: UserDeviceStatisticsUser) => record.id),\n [modalState.data]\n );\n\n const handleDeviceCardClick = (deviceSystemName: keyof DeviceStatistics): void => {\n const data = deviceStatistics[deviceSystemName];\n if (data) {\n setModalState({\n title: `${deviceSystemName} Device users`,\n search: '',\n visible: true,\n data\n });\n }\n };\n\n const handleAppVersionCardClick = (appVersion: keyof AppVersionStatistics): void => {\n const data = appVersionStatistics[appVersion];\n if (data) {\n setModalState({\n title: `${appVersion} version users`,\n search: '',\n visible: true,\n data\n });\n }\n };\n\n const handleModalCancel = (): void => {\n setModalState(defaultModalState);\n if (searchInputRef.current) {\n searchInputRef.current.setValue(''); // Reset input value using ref\n }\n };\n\n const handleSearch = (search: string): void => {\n setModalState((prevState) => ({ ...prevState, search }));\n };\n\n const filteredData = useMemo(() => {\n if (!modalState.search) return modalState.data;\n return modalState.data.filter((record: UserDeviceStatisticsUser) =>\n Object.values(pick(record, ['username', 'email', 'first_name', 'last_name'])).some(\n (value) =>\n !isUndefined(value) &&\n String(value).toLowerCase().includes(modalState.search.toLowerCase())\n )\n );\n }, [modalState.search, modalState.data]);\n\n const renderTooltipIcon = (title: string) => (\n <Tooltip title={title}>\n <QuestionCircleOutlined style={{ position: 'absolute', top: 10, right: 10, fontSize: 16 }} />\n </Tooltip>\n );\n\n return (\n <Spin spinning={isStatisticsLoading} size='large' tip='Loading...'>\n <Row gutter={[16, 16]} style={{ padding: '16px 24px' }}>\n {/* Activity */}\n <Col span={8}>\n <h1>Activity</h1>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Total number of users who have used the app')}\n <Statistic title='Total app users' value={statistics?.statistics.appUserCount || 0} />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon(\n 'Number of users who have posted at least one shot in the last month'\n )}\n <Statistic title='Active users' value={statistics?.statistics.activeUsersCount || 0} />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Number of users who have not posted any shot in the last month')}\n <Statistic\n title='Not active users'\n value={statistics?.statistics.notActiveUsersCount || 0}\n />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Number of users who have published at least one shot')}\n <Statistic\n title='Users with shots'\n value={statistics?.statistics.userWithShotsCount || 0}\n />\n </Card>\n <Card style={{ marginBottom: 16 }}>\n {renderTooltipIcon('Number of users who have not published any shot')}\n <Statistic\n title='Users without shots'\n value={statistics?.statistics.userWithoutShotsCount || 0}\n />\n </Card>\n </Col>\n\n {/* Device */}\n <Col span={8}>\n <h1>Device</h1>\n <Card\n onClick={() => deviceStatistics.iOS.length > 0 && handleDeviceCardClick('iOS')}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n >\n {renderTooltipIcon('Number of users using iOS devices')}\n <Statistic title='iOS users' value={deviceStatistics.iOS.length || 0} />\n </Card>\n <Card\n onClick={() => deviceStatistics.Android.length > 0 && handleDeviceCardClick('Android')}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n >\n {renderTooltipIcon('Number of users using Android devices')}\n <Statistic title='Android users' value={deviceStatistics?.Android.length || 0} />\n </Card>\n <Card\n onClick={() => deviceStatistics.Unknown.length > 0 && handleDeviceCardClick('Unknown')}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n >\n {renderTooltipIcon('Number of users with unknown devices')}\n <Statistic title='Unknown device users' value={deviceStatistics?.Unknown.length || 0} />\n </Card>\n </Col>\n\n {/* App version */}\n <Col span={8}>\n <h1>App version</h1>\n {Object.keys(appVersionStatistics).map((appVersion) => (\n <Card\n key={appVersion}\n style={{\n cursor: 'pointer',\n border: '1px solid #1890ff',\n marginBottom: 16\n }}\n onClick={() => handleAppVersionCardClick(appVersion)}\n >\n {renderTooltipIcon(`Number of users using ${appVersion} app version`)}\n <Statistic\n title={`${appVersion} version`}\n value={appVersionStatistics[appVersion].length}\n />\n </Card>\n ))}\n </Col>\n </Row>\n\n <Modal\n title={modalState.title}\n visible={modalState.visible}\n onOk={handleModalCancel}\n onCancel={handleModalCancel}\n width={'80%'}\n cancelButtonProps={{ hidden: true }}\n >\n <Input.Search\n ref={searchInputRef}\n placeholder='Search by username, first name, last name, or email'\n onSearch={(value) => handleSearch(value)}\n style={{ width: 440, marginBottom: 16, marginLeft: 24 }}\n />\n\n <Table\n dataSource={filteredData}\n columns={columns}\n expandable={{\n expandedRowRender: (record: UserDeviceStatisticsUser) =>\n record.devices.length > 0 ? (\n <Table\n columns={expandedRowColumns}\n dataSource={record.devices}\n pagination={false}\n />\n ) : null,\n rowExpandable: (record) => record.devices.length > 0,\n defaultExpandedRowKeys\n }}\n rowKey={'id'}\n scroll={{ x: 850 }}\n />\n </Modal>\n </Spin>\n );\n};\n\nexport default UserDeviceStatisticsPage;\n","import {\n ActivityLogPage,\n ExActivityLogPage,\n AddUserPage,\n BowDetailsPage,\n BowUsersPage,\n BowUserSessionsPage,\n CheckBowPage,\n EditBowUserPage,\n EditUserPage,\n FirmwareRelease,\n FirmwareTesting,\n LogDetailsPage,\n ExLogDetailsPage,\n LoginPage,\n MainPage,\n NotFoundPage,\n SessionCommentsPage,\n SessionsCommunityPage,\n SessionsPage,\n UserGroupPage,\n UserGroupsPage,\n UsersPage,\n SupportMessagesPage,\n UserShotsPage,\n BowsPage,\n AddBowPage,\n EditBowPage,\n ReportsPage,\n ReportPage,\n StatisticsPage,\n UserDeviceStatisticsPage,\n PublicGroupsPage,\n PublicGroupPage,\n EventsPage,\n GroupEventsPage,\n GroupEventPage\n} from 'pages';\nimport { ERouteType, RouteItem } from 'shared/types';\n\nexport const ROUTES: RouteItem[] = [\n {\n type: ERouteType.DEFAULT,\n path: '/',\n component: MainPage\n },\n {\n type: ERouteType.NOT_GUARDED,\n path: '/login',\n component: LoginPage\n },\n {\n type: ERouteType.DEFAULT,\n path: '/not-found',\n component: NotFoundPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/check-a-bow',\n component: CheckBowPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/firmware/release',\n component: FirmwareRelease\n },\n {\n type: ERouteType.GUARDED,\n path: '/firmware/testing',\n component: FirmwareTesting\n },\n {\n type: ERouteType.GUARDED,\n path: '/add-user',\n component: AddUserPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/users',\n component: UsersPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/bow-users',\n component: BowUsersPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/users/:userId',\n component: EditUserPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/bow-users/:userId',\n component: EditBowUserPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/bow-users/:userId/sessions',\n component: BowUserSessionsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/bows',\n component: BowsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/add-bow',\n component: AddBowPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/bows/:bowId',\n component: EditBowPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/sessions',\n component: SessionsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/sessions/community',\n component: SessionsCommunityPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/sessions/:sessionId/comments',\n component: SessionCommentsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/bows/:bowSerialNumber',\n component: BowDetailsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/activity-log',\n component: ActivityLogPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/activity-log/:logId',\n component: LogDetailsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/ex-activity-log',\n component: ExActivityLogPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/ex-activity-log/:logId',\n component: ExLogDetailsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/groups',\n component: UserGroupsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/groups/:groupId',\n component: UserGroupPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/support/:userId',\n component: SupportMessagesPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/shots/:userId',\n component: UserShotsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/reports',\n component: ReportsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/reports/:reportId',\n component: ReportPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/statistics',\n component: StatisticsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/user-device-statistics',\n component: UserDeviceStatisticsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/public-groups',\n component: PublicGroupsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/public-groups/:publicGroupId',\n component: PublicGroupPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/group-events',\n component: EventsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/group-events/:groupId',\n component: GroupEventsPage\n },\n {\n type: ERouteType.GUARDED,\n path: '/group-events/:groupId/event/:eventId',\n component: GroupEventPage\n }\n];\n","import React from 'react';\nimport { Switch, Route, Redirect } from 'react-router-dom';\nimport * as Styled from './styles';\nimport { GuardedRoute, NotGuardedRoute } from 'routes';\nimport { ERouteType, ModalState, RouteItem } from 'shared/types';\nimport { ROUTES } from './routes';\nimport { useAppDispatch, useAppSelector } from 'shared/hooks';\nimport { Sidebar } from 'shared/components';\nimport { MenuOutlined } from '@ant-design/icons';\nimport { openSidebar } from 'services/store/reducers/sidebarReducer';\n\nconst MainRoutes = (): JSX.Element => {\n const isAuth = useAppSelector((state): boolean => state.auth.isAuth);\n const { isModalOpened, modalWindow } = useAppSelector((state): ModalState => state.modal);\n const dispatch = useAppDispatch();\n\n const handleMenuButtonClick = (): void => {\n dispatch(openSidebar());\n };\n\n const getRoute = (route: RouteItem): JSX.Element => {\n switch (route.type) {\n case ERouteType.GUARDED:\n return (\n <GuardedRoute key={route.path} exact path={route.path} component={route.component} />\n );\n case ERouteType.NOT_GUARDED:\n return (\n <NotGuardedRoute key={route.path} exact path={route.path} component={route.component} />\n );\n default:\n return <Route key={route.path} exact path={route.path} component={route.component} />;\n }\n };\n\n return (\n <Styled.RootContainer isAuth={isAuth}>\n {isAuth && (\n <>\n <Styled.MenuButton onClick={handleMenuButtonClick}>\n <MenuOutlined style={{ fontSize: '30px' }} />\n </Styled.MenuButton>\n <Sidebar />\n </>\n )}\n <Switch>\n {ROUTES.map((item): JSX.Element => {\n return getRoute(item);\n })}\n <Route path='*'>\n <Redirect to='/not-found' />\n </Route>\n </Switch>\n {isModalOpened && <>{modalWindow}</>}\n </Styled.RootContainer>\n );\n};\n\nexport default MainRoutes;\n","import React from 'react';\nimport { Route, Redirect, RouteProps } from 'react-router-dom';\nimport { useAppSelector } from 'shared/hooks';\n\nconst GuardedRoute: React.FC<RouteProps> = ({ ...routeProps }): JSX.Element => {\n const isAuth = useAppSelector((state): boolean => state.auth.isAuth);\n\n if (!isAuth) {\n return (\n <Redirect\n to={{\n pathname: '/',\n state: { from: routeProps.location }\n }}\n />\n );\n }\n\n return <Route {...routeProps} />;\n};\n\nexport default GuardedRoute;\n","import React from 'react';\nimport { Redirect, Route, RouteProps } from 'react-router-dom';\nimport { useAppSelector } from 'shared/hooks';\nimport { AuthState, EUserRole } from 'shared/types';\n\nconst NotGuardedRoute: React.FC<RouteProps> = ({ ...routeProps }): JSX.Element => {\n const { isAuth, user } = useAppSelector((state): AuthState => state.auth);\n\n if (isAuth && user)\n return <Redirect to={user.role === EUserRole.moderator ? 'reports' : '/sessions'} />;\n\n return <Route {...routeProps} />;\n};\n\nexport default NotGuardedRoute;\n","import React from 'react';\nimport './App.css';\nimport { MainRoutes } from 'routes';\nimport { BrowserRouter } from 'react-router-dom';\nimport { Provider } from 'react-redux';\nimport { store } from 'services/store';\nimport { SocketProvider } from 'shared/providers';\n\nconst App = (): JSX.Element => {\n return (\n <Provider store={store}>\n <BrowserRouter>\n <SocketProvider>\n <MainRoutes />\n </SocketProvider>\n </BrowserRouter>\n </Provider>\n );\n};\n\nexport default App;\n","import { ReportHandler } from 'web-vitals';\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n <React.StrictMode>\n <App />\n </React.StrictMode>,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}