{"version":3,"sources":["services/router/router.restate.ts","theme/colors.tsx","services/utils/goTo.ts","config/config.ts","routes.ts","model/UserRole.ts","components/AppDrawer/AppDrawer.state.tsx","I18N/I18N.state.tsx","pages/AcceptInvitation.tsx/AcceptInvitation.state.tsx","model/Locale.ts","pages/GlobalSettings/GlobalSettings.state.tsx","model/User.base.ts","pages/Institute/Institute.state.tsx","pages/Me/Me.state.tsx","pages/SharingObject/SharingObject.state.tsx","services/session/session.state.ts","components/Reminder/Reminder.state.tsx","pages/Dashboard/Dashboard.state.tsx","pages/Trainees/Trainees.state.tsx","pages/TraineeShares/TraineeShares.state.tsx","services/logout/logout.service.ts","state/state.ts","pages/AdminInvite/AdminInvite.state.tsx","pages/Admins/Admins.state.tsx","pages/Course/Course.state.tsx","pages/Courses/Courses.state.tsx","pages/Export/Export.state.tsx","pages/InstituteAdminShares/InstituteAdminShares.state.tsx","pages/Institutes/Institutes.state.tsx","pages/Login/Login.state.tsx","pages/LoginPasswordForgot/LoginPasswordForgot.state.ts","pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.state.tsx","pages/Register/Register.state.ts","pages/Settings/Settings.state.tsx","pages/SingleTrainings/SingleTrainings.state.ts","pages/TrainerInvite/TrainerInvite.state.tsx","pages/Trainers/Trainers.state.tsx","pages/Trainings/Trainings.state..tsx","pages/TrainingsTablePage/TrainingsTablePage.state.tsx","pages/UserChangeEmail/UserChangeEmail.state.tsx","pages/UserChangePassword/UserChangePassword.state.tsx","pages/UserDetails/UserDetails.state.tsx","services/network/network.state.tsx","components/UserMenu/UserMenu.state.tsx","services/router/router.service.ts","services/utils/clearStorage.ts","services/utils/onAction.ts","services/utils/onChange.ts","services/utils/onLogin.ts","services/utils/onLogout.ts","services/utils/onPageEnter.ts","services/utils/onPageLeave.ts","services/utils/hasUserRole.ts","services/utils/snackBar.ts","services/utils/pageParams.ts","services/utils/onLoginPageEnter.ts","services/utils/intl.ts","services/utils/tools.ts","services/utils/http.ts","I18N/connectLanguageQueryParam.tsx","model/ctrl/routes.ts","pages/AdminInvite/AdminInvite.messages.ts","pages/Courses/Courses.messages.ts","pages/Export/Export.page-service.ts","pages/Institute/Institute.messages.ts","pages/Institute/Institute.page-service.ts","pages/Institutes/Institutes.page-service.ts","pages/Register/Register.page-service.ts","I18N/general.messages.ts","pages/Me/Me.messages.ts","pages/Register/Register.messages.ts","services/institutes/institutes.service.ts","pages/SharingObject/SharingObject.messages.ts","pages/Shop/Shop.page-service.ts","pages/TraineeShares/TraineeShares.messages.ts","pages/TrainerInvite/TrainerInvite.messages.ts","pages/Trainers/Trainers.messages.ts","pages/UserChangeEmail/UserChangeEmail.messages.ts","pages/UserChangePassword/UserChangePassword.messages.ts","pages/UserDetails/UserDetails.messages.ts","machines/pageState.machine.ts","pages/Institutes/Institutes.messages.ts","services/logger/logger.service.ts","pages/ValidateLogin/ValidateLogin.messages.ts","services/login/login.service.ts","services/network/network.service.ts","services/session/session.service.ts","services/routeGuard/routeGuard.service.ts","components/ChangeUserRole/ChangeUserRole.messages.ts","I18N/AppIntlProvider.tsx","pages/Dashboard/Dashboard.page-service.ts","pages/Trainees/Trainees.messages.ts","state/store.ts","services/axios/axios.service.ts","components/AppDrawer/AppDrawer.service.ts","services/ecwidLocale/ecwidLocale.service.ts","pages/AcceptInvitation.tsx/AcceptInvitation.page-service.ts","pages/AdminInvite/AdminInvite.page-service.ts","pages/UserChangePassword/UserChagnePassword.service.ts","pages/Course/Course.page-service.ts","pages/Courses/Courses.page-service.ts","pages/GlobalSettings/GlobalSettings.page-service.ts","pages/InstituteAdminShares/InstituteAdminShares.page-service.ts","pages/LoginPasswordForgot/LoginPasswordForgot.service.ts","pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.service.ts","pages/Me/Me.service.ts","components/Reminder/Reminder.page-service.ts","pages/Settings/Settings.page-service.tsx","pages/SharingObject/SharingObject.page-service.ts","pages/SingleTrainings/SingleTrainings.page-service.ts","pages/Trainees/Trainees.page-service.ts","pages/TraineeShares/TraineesShares.page-service.ts","pages/TrainerInvite/TrainerInvite.page-service.ts","pages/Trainers/Trainers.page-service.ts","pages/Trainings/Trainings.page-service.ts","components/TranslationMenu/TranslationMenu.page-service.ts","pages/UserChangeEmail/UserChangeEmail.service.ts","pages/UserDetails/UserDetails.page-service.ts","state/connector/userMenu.connector.tsx","state/connector/userChangeEmail.connector.tsx","components/ChangeUserRole/ChangeUserRole.component-service.ts","components/AppSnackBar/AppSnackBar.tsx","services/router/useGoTo.hook.ts","theme/constants.tsx","theme/Images.tsx","theme/theme.tsx","components/AppDrawer/AppDrawer.messages.ts","components/AppDrawer/AppDrawer.restate.tsx","components/AppDrawer/DrawerListItem.tsx","components/AppDrawer/AppDrawer.tsx","components/Footer/Footer.messages.ts","components/Footer/Footer.tsx","components/UserMenu/UserMenu.restate.tsx","components/UserMenu/userMenu.messages.ts","components/UserMenu/UserMenu.tsx","services/utils/useLogout.hook.ts","components/ChangeUserRole/ChangeUserRole.tsx","components/TranslationMenu/TranslationMenu.tsx","components/TranslationMenu/TranslationMenu.restate.tsx","components/NavBar/NavBar.messages.ts","components/NavBar/NavBar.tsx","styles/styles.tsx","components/Spinner/Spinner.tsx","components/layouts/useLayoutStyles.hook.tsx","components/layouts/useTitle.hook.tsx","components/layouts/MainPageLayout.tsx","components/layouts/AppPageLayout.tsx","components/TermsOfUse/TermsOfUse.tsx","components/TermsOfUse/terms_of_use.ts","components/Imprint/Imprint.messages.ts","components/Imprint/Imprint.tsx","components/ImageCard/ImageCard.tsx","components/ChangePassword/ChangePassword.messages.ts","components/InviteSetPassword/InviteSetPassword.tsx","components/layouts/PublicPageLayout.tsx","components/PageNotFound/PageNotFound.tsx","pages/AcceptInvitation.tsx/AcceptInvitation.restate.tsx","pages/AcceptInvitation.tsx/AcceptInvitation.messages.ts","pages/AcceptInvitation.tsx/AcceptInvitation.tsx","utils/isEmail.ts","components/Invite/Invite.messages.ts","components/Invite/Invite.tsx","services/router/useGoBack.hook.ts","pages/AdminInvite/AdminInvite.restate.tsx","pages/AdminInvite/AdminInvite.tsx","components/CircularTrainingProgress/CircularTrainingProgress.tsx","pages/Course/Course.messages.ts","pages/Course/Course.tsx","components/GenericTable/GenericTable.messages.ts","components/GenericTable/components/EnhancedTableHead.tsx","utils/useRTL.ts","components/GenericTable/components/EnhancedTableToolbar.tsx","components/GenericTable/GenericTable.tsx","components/CourseTable/CourseTable.messages.ts","components/CourseTable/CourseTable.tsx","pages/Courses/Courses.restate.tsx","pages/Courses/Courses.tsx","pages/Export/Export.restate.tsx","pages/Export/Export.messages.ts","pages/Export/Export.tsx","pages/Institute/components/useStyles.ts","pages/Institute/components/InstituteAdminTable.messages.ts","components/YesNoDialog/GenericConfirmDeletionDialog.tsx","components/dialogs/Dialog.messages.ts","components/dialogs/ConfirmDeletionDialog.tsx","pages/Institute/components/InstituteAdminTable.tsx","pages/Institute/Institute.restate.tsx","pages/Institute/components/InstituteForm.messages.ts","pages/Institute/components/InstituteForm.tsx","pages/Institute/components/InstituteTrainerTable.messages.ts","pages/Institute/components/InstituteTrainerTable.tsx","components/layouts/TabsPageLayout.tsx","pages/InstituteAdminShares/InstituteAdminShares.messages.ts","pages/Institute/components/InstituteSharingObject.tsx","pages/Institute/Institute.tsx","pages/Institutes/InstitutesTable.messages.ts","pages/Institutes/Institutes.restate.tsx","pages/Institutes/Institutes.tsx","pages/InternalServerError/InternalServerError.messages.ts","pages/InternalServerError/InternalServerError.tsx","pages/Login/Login.restate.tsx","pages/LoginPasswordForgot/LoginPasswordForrgot.messages.ts","pages/LoginPasswordForgot/LoginPasswordForgot.tsx","pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.messages.ts","pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.restate.tsx","pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.tsx","pages/Logout/Logout.messages.ts","pages/Logout/Logout.tsx","pages/Me/Me.restate.tsx","pages/Me/Me.tsx","pages/NetworkError/NetworkError.messages.ts","pages/NetworkError/NetworkError.tsx","utils/range.ts","pages/Settings/Settings.messages.ts","pages/Settings/Settings.restate.tsx","pages/Settings/Settings.tsx","pages/Shop/Shop.tsx","pages/TrainerInvite/TrainerInvite.restate.tsx","pages/TrainerInvite/TrainerInvite.tsx","pages/Trainers/Trainers.restate.tsx","pages/Trainers/Trainers.tsx","pages/Trainings/Trainings.messages.ts","pages/Trainings/Trainings.tsx","pages/UserChangeEmail/UserChangeEmail.restate.tsx","pages/UserChangeEmail/UserChangeEmail.tsx","components/ChangePassword/ChangePassword.tsx","pages/UserChangePassword/UserChangePassword.restate.tsx","pages/UserChangePassword/UserChangePassword.tsx","pages/UserDetails/UserDetails.restate.tsx","pages/UserDetails/UserDetails.tsx","components/Reminder/ReminderTile.tsx","components/Reminder/Reminder.messages.ts","components/Reminder/Reminder.tsx","pages/Login/Login.messages.ts","pages/Login/LoginForm.tsx","pages/Login/Login.tsx","pages/Dashboard/Dashboard.messages.ts","pages/Dashboard/Dashboard.restate.tsx","pages/Dashboard/DashboardTile.tsx","pages/Dashboard/Dashboard.tsx","pages/Trainees/Trainees.restate.tsx","pages/Trainees/DownloadTraineeData.tsx","components/Config/CptConfig/CptConfig.restate.tsx","components/Config/CptConfig/CptConfig.tsx","pages/GlobalSettings/GlobalSettings.restate.tsx","pages/GlobalSettings/GlobalSettings.tsx","pages/Trainees/Trainees.tsx","pages/Register/Register.restate.ts","pages/Register/RegisterForm.tsx","pages/Register/Register.tsx","pages/EmailValidation/Emailvalidation.messages.ts","pages/EmailValidation/EmailValidation.tsx","pages/SingleTrainings/SingleTrainings.messages.ts","pages/SingleTrainings/SingleTrainings.restate.ts","pages/SingleTrainings/SingleTrainings.tsx","pages/ValidateLogin/ValidateLogin.tsx","pages/SharingObject/SharingObject.restate.tsx","pages/SharingObject/SharingObject.tsx","pages/TraineeShares/TraineeShares.restate.tsx","pages/TraineeShares/TraineeShares.tsx","pages/InstituteAdminShares/InstituteAdminShares.restate.tsx","pages/InstituteAdminShares/InstituteAdminShares.tsx","App.tsx","index.tsx"],"names":["RouterMessageType","Colors","goMessage","path","type","GO","payload","goTo","store","route","params","routeParser","RouteParser","fqRoute","reverse","dispatch","console","error","config","api","process","REACT_APP_API_SERVER_URL","apiAbsolute","window","location","origin","passwordMinLen","APPLE_APP_STORE_CPS_URL","GOOGLE_PLAY_STORE_CPS_URL","AppRoutes","USERROLES","CorPatchAdmin","InstituteAdmin","Trainer","Trainee","Researcher","Unknown","defaultAppDrawerState","open","variant","ALL_FRONTEND_LOCALES","defaultI18NState","locale","localStorage","getItem","code","value","includes","startsWith","warn","toFrontendLocale","navigator","Array","isArray","languages","userLanguage","language","browserLanguage","getNavigatorLanguage","Locale","defaultAcceptInvitationPageState","meta","loading","notFound","success","userInfo","defaultGlobalSettingsState","feedbackConfig","averageCountDepth","averageCountFreq","averageCountRecoil","maxDepth","maxDepthLimit","maxFreq","maxFreqLimit","maxRecoil","minDepth","minDepthLimit","minFreq","minFreqLimit","minRecoil","minRecoilLimit","noFlow","ventilationTime","resultConfig","simple","thresholdGood","thresholdGreat","sessionConfig","audioFeedbackDebounceTime","SignUpStatus","defaultInstituteState","id","name","address","street","nr","co1","co2","city","state","zip","country","settings","en","admins","trainers","sharingObjects","defaultInstituteResultConfigState","defaultMeState","firstName","familyName","gender","ready","defaultSharingObjectsState","data","_id","version","instituteId","invitationCode","pullApiSecret","webHook","active","createdAt","Date","deletedAt","updatedAt","defaultSessionState","user","email","role","availableRoles","signUpStatus","pending","token","defaultOnboardingState","onboarding","userLoggedIn","tutorialCompleted","testTrainingCompleted","selfAssessmentCompleted","legalConditionsAccepted","cpsConnected","emailAddressVerified","defaultDashboardState","usersCount","mobilesCount","cpsCount","trainingsCount","usersCountRecently","mobilesCountRecently","cpsCountRecently","defaultTraineesState","LogoutService","defaultState","services","institutes","pages","acceptInvitation","adminInvite","send","course","courses","dashboard","export","globalSettings","institute","instituteAdminShares","instituteResultConfig","entries","login","password","showProgress","loginPasswordForgot","loginPasswordForgotSetPassword","me","register","lastName","termsOfUseAccepted","appConfig","singleTrainings","traineeSharingObjects","share","selectedTrainingId","selectedTraineeSharingObject","trainees","traineeShares","sharingTrainee","addDialogOpen","addDialogCode","trainerInvite","trainings","idx","trainingsTable","userChangeEmail","nextEmail","errorNextEmail","errorNextEmailMessage","userChangePassword","userDetails","network","online","session","components","appDrawer","userMenu","avatarUrl","userName","eMail","document","title","defaultRouterState","i18n","routerExtension","embeddedMode","clearStorage","clear","sessionStorage","cookies","cookie","split","i","length","eqPos","indexOf","substr","deleteAllCookies","onAction","actionType","state$","pipe","observeOn","animationFrameScheduler","filter","update","message","onChange","selector","map","distinctUntilChanged","onLogin","hasToken","onLogout","Logout","onPageEnter","parser","pathname","match","onPageLeave","pairwise","oldPage","currPage","oldPageIsPage","currPageIsPage","hasUserRole","roles","currentUserRole","snackBar","msg","pageParams","defaultOnLoginPageEnterProps","onLoginPageEnter","props","enterEvent","loginEvent","hasRole","combineLatest","arr","pageEnter","translations","de","require","da","fi","it","es","cache","createIntlCache","intl","messages","createIntl","tools","http","_store","conf","url","Observable","observable","log","axios","then","response","next","complete","catch","err","redirect","status","errMsg","errorMessage","LangReg","routes","validateLogin","changeRole","signup","delete","traineeSignUp","validate","validateEmail","initialPassword","sendEmail","resetPassword","checkCode","globalConfig","resultConfigInstituteAdmin","deletedData","notifyUser","testNotifications","csv","json","allCPS","allMobiles","changeEmail","changePassword","changeMe","pushToken","userSingleTrainings","resendVerificationEmail","trainee","deactivateInvitation","postSingleTraining","admin","deleteSharingObject","instituteAdmin","pullRequest","sharingObject","dummy","defineMessages","inviteCardTitle","defaultMessage","successSnackbar","errorSnackbar","roleInstituteAdmin","roleTrainee","pageTitle","pageNotFoundTitle","pageNotFoundMessage","tabsBase","tabsAdmins","tabsTrainers","institutePageNotFoundTitle","institutePageNotFoundMessage","instituteSuccessSnackbar","instituteErrorSnackbar","institutePageTabIndex","setInstitutePageTabIndex","newPageIndex","RegisterService","institutePageSnackbarSuccess","institutePageSnackbarError","tableRowName","emailAllreadySentSnackbar","notFoundTitle","genderMale","genderFemale","genderOther","save","snackBarSaved","snackBarError","deleteOwnButtonRequest","deleteOwnContent","deleteOwnButtonConfirm","firstnameField","lastnameField","emailField","passwordField","acceptTermsOfUse","create","newToShortError","InstituteServiceMessageType","invitationLink","pullUrl","apiAccess","enabled","disabled","saveButton","deleteButton","confirmDeleteDialogTitle","confirmDeleteDialogYes","confirmDeleteDialogNo","confirmDeleteDialogMessage1","confirmDeleteDialogMessage2","snackBarSaveError","snackBarDeleted","snackBarDeleteError","start","now","args","delta","pageTitleNotFound","inactive","addShare","noActiveItemsMessage","noInactiveItemsMessage","startDate","endDate","deactivateTooltip","addDialogTitle","addDialogDescription","addDialogDescription2","addDialogCancel","addDialogAdd","deactivateDialogTitle","deactivateDialogDescription","deactivateDialogNo","deactivateDialogYes","snackBarInvalidCode","snackBarInvitationAdded","snackBarErrorAddingInvitation","snackBarSharingDeactivated","snackBarErrorDeactivatingSharing","trainerInviteTitle","trainerSuccessSnackbar","trainerErrorSnackbar","trainersNotFoundTitle","trainersNotFoundMessage","trainersNotAvailableTitle","trainersNotAvailableMessage","trainersNotAvailableButton","trainersTitle","selected","tableRowEmail","inviteTrainer","deleteLabel","newEmail","cancelButton","emailChangedSnackbar","emailErrorSnackbar","verifyEmailTitle","verifyEmailContent","verifyEmailButton","ok","loadingTitle","wrongPasswordSnackbar","notChangedPasswordSnackbar","invitation","sendInvitation","signUpAccepted","signUpPending","userDetailsEmail","pageStateMachine","fetchData","setLoading","m","Machine","initial","context","states","init","entry","on","LOGIN","PAGE_ENTER","waitingForPageEnter","LOGOUT","target","actions","assign","ctx","waitingForLogin","PAGE_LEAVE","fetching","RESOLVE","REJECT","interpret","addInstituteButton","formatStack","stack","URL_REG","lines","line","trim","test","exec","formatGroupName","JSON","stringify","substring","MAX_LEN","formatPatches","patches","forEach","patch","join","op","groupCollapsed","groupEnd","LoginService","validationTitle","validationContent","validationButton","successTitle","successContent","errorTitle","errorContent","NetworkServiceMessageType","SessionServiceMessageType","PUBLIC_PAGES","selectLabel","fr","ar","AppIntlProvider","useAppState","children","tableName","tableEmail","tableCreated","tableSelected","mobileButton","cpsButton","singleTrainee","multipleTrainees","warningSnackbar","createStore","options","storeName","history","createBrowserHistory","appStore","color","backgroundColor","subscribe","connectLogger","defaults","responseType","headers","undefined","connectAxios","addEventListener","Offline","Online","onLine","connectNetwork","parse","s","Restored","e","Done","skip","setItem","connectDevTools","connectReactRouter","subs","pack","push","BACK","goBack","connectRouter","search","matches","lang","setLocale","connectLanguageQueryParam","Login","event","post","Boolean","verificationToken","LoginSuccess","LoginValidate","validationToken","method","removeItem","formatMessage","validationMessages","connectLogin","connectLogout","Register","RegisterSuccess","connectRegister","machine","Update","Clear","Create","Edit","Delete","connectInstituteService","debounceTime","connectAppDrawer","token$","location$","session$","some","page","isPublicPage","connectRouteGuard","connectTranslationSwitch","delay","reload","connectEcwidLocaleService","fullRoute","newPassword","key","connectAcceptInvitationPageService","getInstituteId","_err","connectAdminInvitePageService","oldPassword","connectChangePasswordPageService","_error","connectCoursePageService","fetchCourses","isSelectionEnabled","date","trainer","trainerEmail","identifier","traineeCount","deleteReq","connectCoursesPageService","connectDashboardPage","connectExportPageService","res","locked","notificationType","connectGlobalSettingsPage","connectInstituteAdminSharesPage","fetchResultConfig","model","viewModel","_success","connectInstitutePage","setTimeout","connectInstitutesPage","request","connectLoginPasswordForgot","pck","connectLoginPasswordForgotSetPasswordService","connectMePage","connectReminderPageService","connectSettingsPage","_params","_","connectSharingObjectPage","ecwidAvailable$","interval","Ecwid","setSsoProfile","xProductBrowser","startWith","available","ctx$","ecwidAvailable","login$","logout$","shopData","ecwidSsoProfile","connectShopPage","sharingTrainingDto","singleTrainingId","sharingObjectIds","connectSingleTrainingsPage","t","firstnameInvalid","familyNameInvalid","displayName","ids","errorResponses","successfulResponses","index","splice","nextTraineeData","connectTraineesPage","fetchSharingTrainees","sharingTraineeId","connectTraineesSharePage","connectTrainerInvitePageService","nextTrainersData","connectTrainersPage","connectTrainingsPageService","connectTranslationMenuPage","msgEmailChanged","msgEmailError","connectUserChangeEmailPageService","getUserId","connectUserPageService","emailHash","md5","imgUrl","connectUserMenu","connectUserChangePassword","requestedRole","rootState","Object","keys","connectChangeUserRoleComponentService","AppStoreProvider","createProvider","createStateHook","useNextAppState","createNextHook","useStoreHook","createStoreHook","useDispatchHook","createDispatchHook","StyledMaterialDesignContent","styled","MaterialDesignContent","SnackBarListener","enqueueSnackbar","useSnackbar","useEffect","subSuccess","subError","unsubscribe","AppSnackBar","maxSnack","Components","warning","info","useGoToHook","IMG_DIR","Images","bugFix","celebration","confirmation","detailedExamination","doctors","emailValidation","empty","femaleAvatar","otherAvatar","forgotPassword","logoSmallUrl","logout","mail","maleAvatar","medicine","missingUrl","mobileApp","productTearDown","questions","securityOn","teacher","qrCodeAppStoreCPS","qrCodePlayStoreCPS","newsletter","theme","createTheme","palette","main","background","paper","default","primary","light","dark","secondary","text","hint","overrides","MuiTable","root","MuiToolbar","MuiPaper","drawerShop","drawerTrainers","drawerCourses","drawerSingleTrainings","drawerExport","drawerSettings","drawerInstitutes","drawerTrainees","drawerImprint","drawerShares","useNextAppDrawerState","useAppDrawerState","useClasses","makeStyles","listItem","display","flexDirection","justifyContent","alignItems","fontSize","typography","height","width","DrawerListItem","classes","ListItem","style","button","className","onClick","useStyles","drawer","drawerContent","logo","paddingTop","spacing","marginTop","paddingBottom","deco","ShopItem","useIntl","Typography","TrainersItem","CoursesItem","SingleTrainingsItem","ExportItem","SettingsItem","GlobalSettingsItem","InstitutesItem","TraineesItem","ImprintItem","SharesItem","USER_ROLES_to_Entries","List","AppDrawerContent","Entries","src","alt","cursor","CustomDrawer","withStyles","border","boxShadow","shadows","Drawer","MobileDrawer","AppDrawer","closeDrawer","Hidden","mdUp","implementation","anchor","onClose","smDown","elevation","rightsReserved","footer","padding","breakpoints","down","link","textDecoration","Footer","currentYear","getFullYear","textAlign","href","stateSelector","useUserMenuState","Password","EMail","avatarListItem","minWidth","avatar","UserMenu","handleClose","anchorEl","handleLogout","handleAccount","handleEmail","handlePassword","keepMounted","MenuItem","ListItemIcon","ListItemText","Divider","ConnectedUserMenu","go","useLogout","handleMaker","anchorRef","React","useRef","ref","current","ChangeUserRole","SelectLabel","useHistory","handleRoleChange","a","FormControl","InputLabel","whiteSpace","Select","labelId","TranslationMenu","changeLanguage","menuLabel","menuButton","marginRight","flexGrow","appBar","drawerSpacer","up","TranslationButton","showTranslationSwitch","handleOpen","IconButton","UserMenuButton","NavBar","showBackButton","useState","openUserMenu","setOpenUserMenu","openTranslationMenu","setOpenTranslationMenu","nextAppDrawer","AppBar","position","Toolbar","edge","aria-label","noWrap","align","center","CARD_DEFAULTS","maxWidth","minHeight","borderRadius","spinnerBackdrop","zIndex","top","left","spinnerContainer","Spinner","visible","CircularProgress","useLayoutStyles","margin","flex","useTitle","MainPageLayout","isOpen","setIsOpen","scroller","overflow","safariScroller","container","marginLeft","direction","content","AppPageLayout","isSafari","safari","TermsOfUseText","__html","dangerouslySetInnerHTML","TermsOfUse","Card","cardStyle","CardContent","Imprint","card","imgContainer","alignSelf","img","cardContent","useImgCardContentClasses","imgCardContent","ImageCardContent","useImgCardActionsClasses","imgCardActions","ImageCardActions","ImageCard","aria-hidden","passwordRequired","passwordEqual","newPasswordRequired","passwordDontMatch","currentPassword","newPasswordRepeat","changePasswordButton","setPasswordButton","PASSWORD_MIN_LEN","inputField1","inputField","marginBottom","InviteSetPassword","requiredError","matchError","onSend","newPassword0","setNewPassword0","errorNewPassword0","setErrorNewPassword0","errorNewPasswordMessage0","setErrorNewPasswordMessage0","newPassword1","setNewPassword1","errorNewPassword1","setErrorNewPassword1","errorNewPasswordMessage1","setErrorNewPasswordMessage1","valid","setValid","resetNewPassword0Validation","validateNewPassword0","resetNewPassword1Validation","validateNewPassword1","TextField","label","onBlur","helperText","placeholder","Button","header","logoImg","PublicPageLayout","txt","PageNotFound","action","Title","Img","Message","Action","Layout","useAcceptInvitationState","inviteSuccessTitle","inviteSuccessMessage","inviteLoginButton","inviteAcceptedWelcome","welcome","AcceptInvitationLoading","AcceptInvitationNotFound","Success","goToLogin","AcceptInvitation","EMailRegEx","isEmail","inviteCardSubheader","inviteFirstNameLabel","inviteSurnameLabel","inviteSendButton","inviteCancelButton","inviteInvalidEmail","inviteEmailSend","inviteEmailSent","inviteOk","inviteEmailRequired","submitButton","form","innerContainer","h6","grey","cardContainer","cardImg","cardForm","checkCircleIcon","LoadingInvite","InviteCard","inviteSubheader","invalidEmail","eMailRequired","onCancel","imgSrc","setFirstName","setLastName","setEmail","setError","touched","setTouched","Grid","isValidEmail","autoComplete","Send","emailSend","emailSent","OK","onOk","Invite","adminInviteLoading","trainerInviteLoading","useGoBack","useAdminInviteState","useNextAdminInviteState","AdminInvite","box","circleBackground","circleForeground","CircularTrainingProgress","size","thickness","styles","showLabel","sizeStyle","labelStyle","fontWeight","lineHeight","rowFlow","rowDepth","rowRecoil","rowFrequency","cellDate","cellDuration","cellFeedback","cellName","circle","CoursesLoading","Course","instituteName","gutterBottom","year","month","day","comment","result","flowPercent","cprCorrectDepthPercent","cprCorrectRecoilPercent","cprCorrectFrequencyPercent","Table","TableHead","TableRow","TableCell","training","hour","minute","sessionDuration","feedbackMode","navigateToTrainingPage","emptyMessage","previousPage","nextPage","multiSelect","searchPlaceholder","rowsPerPageLabel","createStyles","visuallyHidden","clip","EnhancedTableHead","checkboxEnabled","onSelectAllClick","order","orderBy","numSelected","rowCount","onRequestSort","singleSelect","cellHeaders","Checkbox","indeterminate","checked","inputProps","headCell","numeric","disablePadding","sortDirection","TableSortLabel","property","useRTL","useToolbarStyles","paddingLeft","paddingRight","gridTemplateColumns","highlight","selectedMessage","DefaultTools","EnhancedTableToolbar","searchTerm","setSearchTerm","clearSearchTerm","setSelected","selectedItemsMessage","subTitle","originalSearchString","setOriginalSearchString","SelectedItemsMessage","Tools","isRTL","count","Input","escapedString","replace","endAdornment","InputAdornment","startAdornment","ROWS_PER_PAGE_OPTIONS","table","tableWrapper","overflowX","maxHeight","isScrollable","srollableTableBody","GenericTable","rows","checkboxVisible","initialSortProperty","initialSortDirection","setOrder","setOrderBy","setPage","rowsPerPage","setRowsPerPage","searchFn","filteredRows","sorted","sort","b","propertyA","propertyB","localeCompare","valueOf","displayRows","slice","RowComponent","rowRender","Paper","term","aria-labelledby","stickyHeader","newSelected","n","_event","TableBody","colSpan","row","isItemSelected","hover","aria-checked","tabIndex","selectedIndex","concat","handleClick","TablePagination","rowsPerPageOptions","component","labelRowsPerPage","backIconButtonProps","nextIconButtonProps","onPageChange","newPage","onRowsPerPageChange","tableRowAssociatedTrainer","tableRowProvider","tableRowIdentifier","tableRowDate","tableRowLocation","tableRowTraineeCount","tableRowValue","downloadMessage","downloadCSVTitle","CourseTable","onCourseClick","showInstituteCol","showAssociatedTrainerCol","tableMessages","userRole","CellHeaderAssociatedTrainer","splits","every","searchReg","RegExp","conditionalSortMatch","Number","parseInt","values","Tooltip","useCoursesState","CoursesNotFound","Courses","useExportState","Provider","Identifier","Location","TraineeCount","ExportTable","tableRowIndetifier","download","Export","find","fileName","toISOString","onDownloadProgress","URL","createObjectURL","Blob","createElement","setAttribute","body","appendChild","click","field","flexWrap","secondaryButton","cardHeader","adminsTableTitle","adminsTableSubtitle","adminsTableInviteButton","adminsTableEmail","deleteAdminMessage","YesNoDialog","dialogTitle","yesButtonTitle","noButtonTitle","onYesButtonClick","onNoButtonClick","Dialog","DialogTitle","DialogContent","DialogActions","confirmDeleteDialogContentDescription","confirmDeleteDialogContentConclusion","deleteDialogButtonPrimary","deleteDialogButtonSecondary","ConfirmDeletionDialog","userRoles","onPositiveButtonClick","onNegativeButtonClick","deleteDialogTitle","deleteDialogContentDescription","deleteDialogContentConclusion","InstituteAdminTable","tableTitle","tableSubtitle","inviteButton","selectedIdsToDelete","setSelectedIdsToDelete","selectedIds","clearSelection","getAdminRoles","useInstituteState","useInstituteResultConfigState","useNextInstituteResultConfigState","useInstituteActions","createActionsHook","setName","nextName","setCity","nextCity","setPlz","nextPlz","setStreet1","nextStreet1","setCo1","nextCo1","setState","nextState","setCountry","nextCountry","nextLocale","instituteAddress","instituteStreet","instituteStreetAdditional","instituteState","instituteZIP","instituteCity","instituteCountry","instituteSaveButton","instituteResultConfigBtn","instituteResultConfigLabelGood","instituteResultConfigLabelGreat","instituteResultConfigSave","instituteResultConfigInfo","localeLabel","localeEnglish","localeGerman","localeDanish","localeFinish","localeItalian","localeFrench","localeSpanish","modal","InstituteForm","instituteActions","nextResultConfig","isResultConfigOpen","setResultConfigOpen","setThresholdGood","setThresholdGreat","CardHeader","subheader","FormGroup","required","Modal","trainerTableName","trainerTableTitle","trainerTableSubtitle","trainerTableButton","tableRowsStreet","trainerEmptyMessage","deleteTrainerMessage","InstituteTrainerTable","Street","Name","getTrainerRoles","TabsPageLayout","tabs","tabIdx","onTabChange","Tabs","newTabIndex","indicatorColor","textColor","tab","Tab","deleted","noActiveSharingObjectsMessage","noDeletedSharingObjectsMessage","fab","bottom","right","InstituteSharingObjects","activeSharingObjects","deactivatedSharingObjects","hasActiveSharingObjects","hasDeactivatedSharingObjects","SharingObjectRow","formatDate","AddButton","Fab","TabPanel","hidden","Institute","Base","Admins","Trainers","setTabIndex","_props","newInstitute","tableRowStreet","tableRowCity","tableRowZIP","tableRowCountry","institutesLowercase","instituteLowercase","deleteWarning","instituteCard","instituteEntryActions","CreateInstituteActions","City","ZIP","Country","Institutes","deleteInstitute","serverErrorTitle","serverErrorMessage","serverErrorButton","InternalServerError","useLoginState","useLoginActions","setPassword","loginState","signIn","preventDefault","loginMessage","passwordForgotConfirmationMessage","passwordForgotConfirmationMessage2","passwordForgotConfirmationTitle","passwordForgotConfirmationSent","passwordForgotBackToLogin","passwordForgotConfirmationSendMessage","passwordForgotTitle","placeItems","EmailForm","ConfirmationMessage","ConfirmationMessage2","ConfirmationTitle","ConfirmationSent","onSubmit","htmlFor","CardActions","ConfirmationSendMessage","Sending","LoginPasswordForgot","isSend","isSending","isInput","isError","successMessage","loginButton","useLoginPasswordForgotSetPasswordState","ChangePassword","newRequiredError","buttonDisabled","LoadingPage","NotFoundPage","SetPasswordPage","SuccessPage","LoginPasswordForgotSetPassword","logoutTitle","logoutMessage","useMeState","input","Me","genderLabel","genderFemaleLabel","genderMaleLabel","genderOtherLabel","saveLabel","firstNameLabel","familyNameLabel","modalIsOpen","setModalisOpen","pageNotFoundButton","NetworkError","range","x","SettingsPageTitle","TableRowProperty","TableRowValue","TableRowLocked","TableRowTrainees","TableRowDuration","TableRowFeedback","TableRowType","TableRowCompression","TableRowFrequency","TableRowResult","TableRowERC","TableRowSaveButton","FeedbackModeMenuItemNone","FeedbackModeMenuItemExpert","FeedbackModeMenuItemSimple","ResultTypeMenuItemNone","ResultTypeMenuItemSimple","ResultTypeMenuItemStandard","ResultTypeMenuItemExpert","MenuItemThresholdGood","MenuItemThresholdGreat","TableRowResultConfigSaveButton","useSettingsState","SettingsLoading","settingsTitle","Settings","Property","Value","Locked","Trainees","Duration","Feedback","Type","Compression","Frequency","Result","ERC","SaveButton","nextInstituteResultConfig","numberOfTrainees","sec","minutes","Math","floor","seconds","secFormated","formatSessionDuration","sessionType","targetFrequency","resultType","showErcRoutine","renderShop","ToggleShop","ShopPageLayout","hash","Shop","Component","useTrainerInviteState","useNextTrainerInviteState","TrainerInvite","useTrainersState","TrainersLoading","TrainersNotFound","TrainersTableEmpty","goToTrainerInvitePage","TrainersTable","trainerPage","searchExp","navigateToUserDetailsPage","trainingsNotFoundTitle","trainingsNotFoundMessage","trainingsTrainee","trainingsFlow","trainingsDepth","trainingsRecoil","trainingsFrequency","trainingNumber","time","dateTime","duration","TrainingsLoading","TrainingsNotFound","Trainings","trainingTitle","trainingsPage","sessions","useUserChangeEmailState","useUserChangeEmailActions","setNextEmail","sendChangeEmailRequest","UserChangeEmailLoading","UserChangeEmailNotFound","EMailForm","onboardingState","gap","EMailSend","UserChangeEmail","equalError","setOldPassword","errorOldPassword","setErrorOldPassword","errorOldPasswordMessage","setErrorOldPasswordMessage","resetOldPasswordValidation","validateOldPassword","autoFocus","useUserChangePasswordState","UserChangePasswordLoading","UserChangePasswordNotFound","UserChangePassword","useUserDetailsState","UserDetailsLoading","UserDetailsNotFound","UserDetails","generalMessages","cancelCardButton","float","cardTitle","cardImage","cardButton","ReminderTile","images","buttonText","secondaryButtonText","clickHandlerPrimary","clickHandlerSecondary","appTitle","appContent","appPlayStoreButton","appAppStoreButton","reminderContainer","Loading","Reminder","userOrPasswordNotFound","userNewlyRegisteredLabel1","userNewlyRegisteredLabel2","passwordForgot","registerButton","loginInstitutesTitle","termsOfUseButton","formItem","EmailAndPasswordForm","userOrPasswordNotFoundLabel","registerSuccess","Busy","SignInForm","borderTop","titleBg","lastMonth","useDashboardState","Tile","DashboardTile","item","xs","amount","description","wrapper","numberBox","materialIcon","Dashboard","useTraineesState","DownloadTraineeData","toLocaleDateString","downloadMobileAncCpsData","dataType","useGlobalSettingsState","dialogContent","textTransform","A700","cell","fontFamily","select","CptConfig","setAverageCountDepth","setAverageCountFreq","setAverageCountRecoil","setMaxDepth","setMaxDepthLimit","setMaxFreq","setMaxFreqLimit","setMaxRecoil","setMinDepth","setMinDepthLimit","setMinFreq","setMinFreqLimit","setMinRecoil","setMinRecoilLimit","setNoFlow","setVentilationTime","setDebounceTime","Cell","Row","AvgCountDepth","AvgCountFreq","MaxDepth","MaxDepthLimit","MaxFreq","MaxRecoil","AvgCountRecoil","MinDepth","MinDepthLimit","MinFrequency","MinFrequencyLimit","MaxFrequencyLimit","MinRecoil","MinRecoilLimit","NoFlow","VentilationTime","DebounceTime","GlobalSettingsLoading","NotificationSelectCard","handleSubmit","showClose","setNotificationType","GlobalSettings","cptConfigLoading","created","selectedIdsToNotify","setSelectedIdsToNotify","getTraineeRoles","useRegisterActions","setfirstName","registerState","setlastName","setTermsOfUseAccepted","accepted","registerMessage","RegisterForm","errorPassword","setErrorPassword","errorPasswordMessage","setErrorPasswordMessage","isValid","validatePasswordInput","validationText","placeContent","EmailValidation","get","singleTraining","multipleTrainings","tableRowOrigin","tableRowFlow","tableRowDepth","tableRowRecoil","tableRowFrequency","tableShareTrainingTooltip","shareDialogTitle","shareDialogContent","shareDialogTooltip","sharedDialogTooltip","shareDialogCancelButton","shareDialogShareButton","useSingleTrainingsState","ShareDialog","onShare","shareButtonDisabled","trainingHasBeenSharedAlready","trainingId","trainingSharedDate","traineeSharingObject","sharedAt","visibleTraineeSharingObjects","sharingObjectId","disableRipple","SingleTrainings","shareDialogOpen","setShareDialogOpen","tableShare","shareButtonColor","isShared","toString","frequency","openSharedDialog","ValidateLogin","useParams","isNetworkInitialized","isLoggedInAllready","useSharingObjectsState","SharingObjectsLoading","SharingObjectsNotFound","SharingObjectForm","isInstituteAdmin","isCorPatchAdmin","confirmDeleteDialogOpen","setConfirmDeleteDialogOpen","protocol","host","SharingObject","useTraineeSharesState","TraineeSharesLoading","TraineeSharesNotFound","isActive","NoActiveItems","NoDeActiveItems","SharingTraineeCard","deactivateDialogOpen","setDeactivateDialogOpen","DeactivateDialog","AddDialog","addButtonDisabled","dateStr","toLocaleString","TraineeShares","activeSharingTrainee","deactivatedSharingTrainee","useInstituteAdminSharesState","InstituteAdminShares","UserMenuPages","exact","CorPatchAdminPages","SharingObjects","TrainerPages","to","TraineePages","InstituteAdminPages","PublicPages","useLocation","useMemo","query","URLSearchParams","useLocalizedTheme","deDE","enUS","fiFI","itIT","frFR","esES","localization","App","RTL","dir","ThemeProvider","ReactDOM","render","getElementById"],"mappings":"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","file":"static/js/main.ca1c0a00.chunk.js","sourcesContent":["import { Message } from '@restate/core'\n\nexport enum RouterMessageType {\n GO = 'Service/Router/Go',\n BACK = 'Service/Router/Back',\n}\n\nexport interface GoMessage extends Message {\n type: RouterMessageType\n payload: {\n path: string\n }\n}\n\nexport const goMessage: (path: string) => GoMessage = path => ({\n type: RouterMessageType.GO,\n payload: { path },\n})\n\nexport const goBackMessage: () => GoMessage = () => ({\n type: RouterMessageType.BACK,\n payload: { path: '' },\n})\n","//\n// Pallet #6 from Refactoring UI / Color Palettes v 1.01\n//\n\n// These are the splashes of color that should appear the most in your UI,\n// and are the ones that determine the overall \"look\" of the site. Use these\n// for things like primary actions, links, navigation items, icons, accent\n// borders, or text you want to emphasize.\nconst primary = [\n 'hsl(338, 78%, 28%)',\n 'hsl(338, 78%, 33%)',\n // dark red => darker accent color for borders, error notifications etc.\n 'hsl(338, 78%, 38%)',\n 'hsl(338, 78%, 43%)',\n // main => main accent color for buttons etc.\n 'hsl(338, 78%, 48%)',\n 'hsl(338, 78%, 52%)',\n 'hsl(338, 78%, 58%)',\n // light red\n 'hsl(338, 78%, 62%)',\n 'hsl(338, 78%, 68%)',\n 'hsl(338, 78%, 72%)',\n]\n\n// vivid\n\nconst vivid = [\n 'hsl(47, 72%, 56%)',\n 'hsl(47, 72%, 61%)',\n 'hsl(47, 72%, 66%)',\n // special color for icons / warnings\n 'hsl(47, 72%, 71%)',\n 'hsl(47, 72%, 76%)',\n 'hsl(47, 72%, 81%)',\n 'hsl(47, 72%, 83%)',\n 'hsl(47, 72%, 85%)',\n 'hsl(47, 72%, 87%)',\n 'hsl(47, 72%, 89%)',\n]\n\n// These are the colors you will use the most and will make up the majority\n// of your UI. Use them for most of your text, backgrounds, and borders,\n// as well as for things like secondary buttons and links\nconst neutrals = [\n 'hsl(42, 15%, 13%)',\n 'hsl(40, 13%, 23%)',\n 'hsl(37, 11%, 28%)',\n 'hsl(41, 9%, 35%)',\n 'hsl(41, 8%, 48%)',\n 'hsl(41, 8%, 61%)',\n 'hsl(39, 11%, 69%)',\n 'hsl(40, 15%, 80%)',\n 'hsl(43, 13%, 90%)',\n // constrast background for cards etc.\n 'hsl(40, 23%, 97%)',\n]\n\n// These colors should be used fairly conservatively throughout your UI to\n// avoid overpowering your primary colors. Use them when you need an\n// element to stand out, or to reinforce things like error states or positive\n// trends with the appropriate semantic color.\nconst supportingCyan = [\n // dark\n 'hsl(178, 53%, 59%)',\n 'hsl(178, 53%, 64%)',\n // main secondary color => secondary buttons, etc.\n 'hsl(178, 53%, 69%) ',\n 'hsl(178, 53%, 74%)',\n // light\n 'hsl(178, 53%, 79%)',\n 'hsl(178, 53%, 81%)',\n 'hsl(178, 53%, 83%)',\n 'hsl(178, 53%, 85%)',\n 'hsl(178, 53%, 87%)',\n 'hsl(178, 53%, 89%)',\n]\n\nconst supportingLime = [\n 'hsl(81, 86%, 14%)',\n 'hsl(81, 78%, 21%)',\n 'hsl(83, 74%, 27%)',\n // Primary success colors => success notifications, etc.\n 'hsl(83, 70%, 34%)',\n 'hsl(83, 64%, 42%)',\n 'hsl(83, 55%, 52%)',\n 'hsl(83, 63%, 61%)',\n 'hsl(83, 68%, 74%)',\n 'hsl(84, 77%, 86%)',\n 'hsl(83, 88%, 94%)',\n]\n\nexport const background = ['hsl(0, 0%, 100%)']\nexport const black = 'rgba(0, 0, 0, 0.87)'\n\nexport const Colors = {\n primary,\n vivid,\n neutrals,\n supportingCyan,\n supportingLime,\n background,\n black,\n}\n","import { RxStore } from '@restate/core'\nimport RouteParser from 'route-parser'\nimport { AppMessages } from 'state/appMessages'\nimport { State } from 'state/state'\nimport { goMessage } from 'services/router/router.restate'\n\ninterface RouteParams {\n id?: string\n}\n\nexport const goTo = (store: RxStore) => (\n route: string,\n params: RouteParams = {}\n) => {\n const routeParser = new RouteParser(route)\n const fqRoute = routeParser.reverse(params)\n if (fqRoute) {\n store.dispatch(goMessage(fqRoute))\n } else {\n console.error(`Cannot parse route ${route} with params ${params}`)\n }\n}\n","export const config = () => ({\n api: process.env.REACT_APP_API_SERVER_URL || '',\n\n apiAbsolute:\n process.env.REACT_APP_API_SERVER_URL || window.location.origin || '',\n\n passwordMinLen: 8,\n\n APPLE_APP_STORE_CPS_URL:\n 'https://apps.apple.com/us/app/corpatch/id1570110910',\n GOOGLE_PLAY_STORE_CPS_URL:\n 'https://play.google.com/store/apps/details?id=com.corpatch.app.cps',\n})\n","export const AppRoutes = {\n AcceptInvitation: '/invite/:id',\n AdminInvite: '/institutes/:id/admin/invite',\n Course: '/courses/:id',\n Courses: '/courses',\n EmailValidation: '/email/validate/:id',\n Export: '/export',\n GlobalSettings: '/global-settings',\n Home: '/',\n Imprint: '/imprint',\n Institute: '/institutes/:id',\n InstituteAdminShares: '/institute-admin-shares',\n InstituteAdminSharingObject: '/institute-admin-shares/:id',\n Institutes: '/institutes',\n InternalServerError: '/error/500',\n Login: '/login',\n LoginPasswordForgot: '/login/password',\n LoginPasswordForgotSetPassword: '/login/reset/:code',\n LoginTermsOfUse: '/login/termsofuse',\n Logout: '/logout',\n MeAccount: '/me/account',\n MeEMail: '/me/email',\n MePassword: '/me/password',\n NetworkError: '/error/network',\n Register: '/register',\n Settings: '/settings',\n SharingObject: '/sharing/:id',\n Shop: '/shop',\n SingleTrainings: '/cps/trainings',\n Trainee: '/trainees/:id',\n Trainees: '/trainees',\n TraineeShares: '/trainee-shares',\n TraineeSharesInvite: '/trainee-shares/invite/:id',\n Trainer: '/trainers/:id',\n TrainerInvite: '/institutes/:id/trainer/invite',\n Trainers: '/trainers',\n Trainings: '/courses/:id/training/:idx',\n UserDetails: '/user/:id',\n ValidateLogin: '/login/validate/:token',\n ValidateLoginPublic: '/login/validate',\n}\n","/**\n * The role of the user\n */\nexport type UserRole =\n | 'CorPatchAdmin'\n | 'InstituteAdmin'\n | 'Trainer'\n | 'Trainee'\n | 'Researcher'\n | 'Unknown'\n\n/**\n * The UserRole type as an enum to avoid typos\n */\nexport const USERROLES: {\n CorPatchAdmin: UserRole\n InstituteAdmin: UserRole\n Trainer: UserRole\n Trainee: UserRole\n Researcher: UserRole\n Unknown: UserRole\n} = {\n CorPatchAdmin: 'CorPatchAdmin',\n InstituteAdmin: 'InstituteAdmin',\n Trainer: 'Trainer',\n Trainee: 'Trainee',\n Researcher: 'Researcher',\n Unknown: 'Unknown',\n}\n\n/**\n * All available roles with different permissions. These roles are ordered in descending order of their permission priviledges\n * It is important that if you add a new role you respect this order because it is implied in other functions e.g. getMostProviledgedRole()\n */\nexport const allRoles: UserRole[] = [\n USERROLES.CorPatchAdmin,\n USERROLES.InstituteAdmin,\n USERROLES.Trainer,\n USERROLES.Trainee,\n USERROLES.Researcher,\n USERROLES.Unknown,\n]\n\n/**\n *\n * @param roles a users roles\n * @returns the role with the highest permission priviledges\n */\nexport const getMostProviledgedRole = (roles: UserRole[]) => {\n for (const role of allRoles) {\n if (roles.includes(role)) return role\n }\n\n return USERROLES.Unknown\n}\n\n/**\n *\n * @param requiredRoles array of roles of which at least one must be matched by the user\n * @param userRoles all roles of the user\n * @returns boolean if the user fulfills at least one of the required roles\n */\nexport const hasAnyRolesOf = (\n requiredRoles: UserRole[],\n userRoles: UserRole[]\n) => {\n for (const role of userRoles) {\n if (requiredRoles.includes(role)) return true\n }\n\n return false\n}\n","import { UserRole, USERROLES } from 'model/UserRole'\n\nexport interface AppDrawerMessage {\n type: 'AppDrawer/Role'\n}\n\nexport interface AppDrawerState {\n open: boolean\n variant: UserRole\n}\n\nexport const defaultAppDrawerState: AppDrawerState = {\n open: false,\n variant: USERROLES.Trainee,\n}\n","const ALL_FRONTEND_LOCALES = [\n 'ar-SA', // Assuming Saudi Arabia\n 'da-DA',\n 'de-DE',\n 'en-US',\n 'es-ES',\n 'fi-FI',\n 'fr-FR',\n 'it-IT',\n]\n\nexport type FrontendLocale =\n | 'ar-SA'\n | 'da-DA'\n | 'de-DE'\n | 'en-US'\n | 'es-ES'\n | 'fi-FI'\n | 'fr-FR'\n | 'it-IT'\n\nexport interface I18NState {\n locale: FrontendLocale\n}\n\nfunction isFrontendLocale(value: string): boolean {\n return ALL_FRONTEND_LOCALES.includes(value)\n}\n\nconst DEFAULT_FALLBACK_LANGUAGE = 'en-US'\n\nexport const LOCAL_STORAGE_LANGUAGE = 'CP-language'\n\n/**\n * Converts a short locale code (like 'de') into a fully qualified\n * language code (like 'de-DE')\n *\n * @param code\n * @returns\n */\nexport const toFrontendLocale = function (code: string): FrontendLocale {\n if (isFrontendLocale(code)) return code as FrontendLocale\n\n if (code.startsWith('de')) return 'de-DE'\n if (code.startsWith('en')) return 'en-US'\n if (code.startsWith('da')) return 'da-DA'\n if (code.startsWith('fi')) return 'fi-FI'\n if (code.startsWith('it')) return 'it-IT'\n if (code.startsWith('fr')) return 'fr-FR'\n if (code.startsWith('da')) return 'da-DA'\n if (code.startsWith('es')) return 'es-ES'\n if (code.startsWith('ar')) return 'ar-SA'\n\n console.warn(`Could not find FrontendLocale for code \"${code}\"`)\n return DEFAULT_FALLBACK_LANGUAGE\n}\n\nexport const defaultI18NState: I18NState = {\n locale:\n (localStorage.getItem(LOCAL_STORAGE_LANGUAGE) as FrontendLocale) ||\n toFrontendLocale(getNavigatorLanguage()),\n}\n\n//\n// See also index.html: getNavigatorLanguage for Ecwid\n//\nfunction getNavigatorLanguage(): string {\n if (!navigator) {\n return DEFAULT_FALLBACK_LANGUAGE\n }\n\n if (Array.isArray(navigator.languages)) {\n return navigator.languages[0]\n }\n\n return (\n (navigator as any).userLanguage ||\n navigator.language ||\n (navigator as any).browserLanguage ||\n DEFAULT_FALLBACK_LANGUAGE\n )\n}\n","import { UserInfo } from 'model/ctrl/signup/ValidateRes.schema'\n\nexport interface AcceptInvitationPageState {\n meta: {\n loading: boolean\n notFound: boolean\n success: boolean\n }\n userInfo: UserInfo | null\n}\n\nexport const defaultAcceptInvitationPageState: AcceptInvitationPageState = {\n meta: {\n loading: true,\n notFound: false,\n success: false,\n },\n userInfo: null,\n}\n","export enum Locale {\n ar = 'ar',\n de = 'de',\n en = 'en',\n da = 'da',\n it = 'it',\n fi = 'fi',\n fr = 'fr',\n es = 'es',\n}\n\nexport const getLocaleByCode = (code: string): Locale => {\n switch (code) {\n case 'ar':\n return Locale.ar\n case 'de':\n return Locale.de\n case 'en':\n return Locale.en\n case 'da':\n return Locale.da\n case 'it':\n return Locale.it\n case 'fi':\n return Locale.fi\n case 'fr':\n return Locale.fr\n case 'es':\n return Locale.es\n default:\n return Locale.en\n }\n}\n","import { FeedbackConfig } from 'model/FeedbackConfig'\nimport { ResultConfig } from '../../model/CptConfig'\n\nexport interface GlobalSettingsState {\n meta: {\n loading: boolean\n }\n feedbackConfig: FeedbackConfig\n resultConfig: ResultConfig\n sessionConfig: {\n audioFeedbackDebounceTime: number\n }\n}\n\nexport const defaultGlobalSettingsState: GlobalSettingsState = {\n meta: {\n loading: true,\n },\n feedbackConfig: {\n averageCountDepth: -1,\n averageCountFreq: -1,\n averageCountRecoil: -1,\n maxDepth: -1,\n maxDepthLimit: -1,\n maxFreq: -1,\n maxFreqLimit: -1,\n maxRecoil: -1,\n minDepth: -1,\n minDepthLimit: -1,\n minFreq: -1,\n minFreqLimit: -1,\n minRecoil: -1,\n minRecoilLimit: -1,\n noFlow: -1,\n ventilationTime: -1,\n },\n resultConfig: {\n simple: {\n thresholdGood: 50,\n thresholdGreat: 70,\n },\n },\n sessionConfig: {\n audioFeedbackDebounceTime: 1000,\n },\n}\n","import { UserRole } from './UserRole'\nimport { UUID } from './UUID'\nimport { EMail } from './Email'\nimport { UserSettings } from './UserSettings'\n\nexport enum SignUpStatus {\n pending = 'pending',\n valid = 'valid',\n}\n\nexport interface UserBase {\n firstName: string\n familyName: string\n gender: 'female' | 'male' | 'other'\n roles: UserRole[]\n email: EMail\n signUpStatus: SignUpStatus\n settings: UserSettings\n instituteId?: UUID\n}\n","import { Address } from 'model/Address'\nimport { InstituteUserDto } from 'model/ctrl/institute/GetInstituteRes.schema'\nimport { UUID } from 'model/UUID'\nimport { Locale } from '../../model/Locale'\nimport { ResultConfig } from 'model/CptConfig'\nimport { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\n\nexport interface InstituteState {\n id: UUID\n meta: {\n loading: boolean\n notFound: boolean\n error: string | null\n }\n name: string\n address: Address\n settings: {\n locale: Locale\n }\n admins: InstituteUserDto[]\n trainers: InstituteUserDto[]\n sharingObjects: SharingObjectDocument[]\n}\n\nexport const defaultInstituteState: InstituteState = {\n id: '',\n meta: {\n loading: true,\n notFound: false,\n error: null,\n },\n name: '',\n address: {\n street: '',\n nr: '',\n co1: '',\n co2: '',\n city: '',\n state: '',\n zip: '',\n country: '',\n },\n settings: {\n locale: Locale.en,\n },\n admins: [],\n trainers: [],\n sharingObjects: [],\n}\n\nexport const defaultInstituteResultConfigState: ResultConfig = {\n simple: {\n thresholdGood: 50,\n thresholdGreat: 70,\n },\n}\n","import { Gender } from 'model/Gender'\n\nexport interface MeState {\n firstName: string\n familyName: string\n gender: Gender\n meta: {\n ready: boolean\n loading: boolean\n }\n}\n\nexport const defaultMeState: MeState = {\n firstName: '',\n familyName: '',\n gender: 'other',\n meta: {\n ready: false,\n loading: false,\n },\n}\n","import { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\n\nexport interface SharingObjectsState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n data: SharingObjectDocument\n}\n\nexport const defaultSharingObjectsState: SharingObjectsState = {\n meta: {\n loading: false,\n notFound: false,\n },\n data: {\n _id: '',\n name: '',\n type: 'training',\n version: '?',\n instituteId: '?',\n invitationCode: '?',\n pullApiSecret: '?',\n webHook: '?',\n active: false,\n meta: {\n createdAt: new Date(),\n deletedAt: null,\n updatedAt: new Date(),\n },\n },\n}\n","import { Locale } from 'model/Locale'\nimport { SignUpStatus } from 'model/User.base'\nimport { BaseUserDTO } from 'model/User.dto'\nimport { USERROLES } from '../../model/UserRole'\n\nexport const defaultUserState: BaseUserDTO = {\n _id: 'no-such-id',\n email: '',\n familyName: '',\n firstName: '',\n role: USERROLES.Unknown,\n availableRoles: [],\n gender: 'other',\n signUpStatus: SignUpStatus.pending,\n token: 'no-such-token',\n settings: { locale: Locale.en },\n}\n\nexport interface SessionState {\n user: BaseUserDTO\n token: string | null\n}\n\nexport const defaultSessionState: SessionState = {\n user: defaultUserState,\n token: null,\n}\n","export interface OnboardingProgress {\n cpsConnected: boolean\n emailAddressVerified: boolean\n legalConditionsAccepted: boolean\n selfAssessmentCompleted: boolean\n testTrainingCompleted: boolean\n tutorialCompleted: boolean\n userLoggedIn: boolean\n}\n\nexport interface OnboardingState {\n onboarding: OnboardingProgress\n meta: {\n loading: boolean\n notFound: boolean\n }\n}\n\nexport const defaultOnboardingState = {\n onboarding: {\n userLoggedIn: false,\n tutorialCompleted: false,\n testTrainingCompleted: false,\n selfAssessmentCompleted: false,\n legalConditionsAccepted: false,\n cpsConnected: false,\n emailAddressVerified: false,\n },\n meta: {\n loading: true,\n notFound: false,\n },\n}\n","export interface DashboardState {\n data: {\n usersCount: number\n mobilesCount: number\n cpsCount: number\n trainingsCount: number\n usersCountRecently: number\n mobilesCountRecently: number\n cpsCountRecently: number\n }\n meta: {\n loading: boolean\n notFound: boolean\n error: string | null\n }\n}\n\nexport const defaultDashboardState = {\n data: {\n usersCount: 0,\n mobilesCount: 0,\n cpsCount: 0,\n trainingsCount: 0,\n usersCountRecently: 0,\n mobilesCountRecently: 0,\n cpsCountRecently: 0,\n },\n meta: {\n loading: false,\n notFound: false,\n error: null,\n },\n}\n","import { GenericTableData } from 'components/GenericTable/GenericTable'\nimport { TraineeDTO } from 'model/ctrl/trainees/GetTraineesRes.schema'\n\nexport type TraineeData = TraineeDTO & \n GenericTableData & { displayName?: string }\n\n\nexport interface TraineesState {\n data: TraineeData[]\n meta: {\n loading: boolean\n notFound: boolean\n error: string | null\n }\n}\n\nexport const defaultTraineesState = {\n data: [],\n meta: {\n loading: false,\n notFound: false,\n error: null,\n },\n}\n","import { SharingTraineeAggregate } from 'model/SharingTraineeAggregate'\n\nexport interface TraineeSharesState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n sharingTrainee: SharingTraineeAggregate[]\n addDialogOpen: boolean\n addDialogCode: string\n value: number\n}\n\nexport const defaultTraineeSharesState: TraineeSharesState = {\n meta: {\n loading: false,\n notFound: false,\n },\n sharingTrainee: [],\n addDialogOpen: false,\n addDialogCode: '',\n value: 0,\n}\n","import { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { defaultState } from 'state/state'\nimport { clearStorage } from 'services/utils/clearStorage'\n\nexport enum LogoutService {\n Logout = 'Service/Logout/Logout',\n Done = 'Service/Logout/Done',\n}\n\nexport type LogoutServiceMessages = { type: LogoutService }\n\nexport const connectLogout = (store: AppStore) => {\n const { onAction, goTo } = tools(store)\n\n onAction({ type: LogoutService.Logout }).subscribe(() => {\n const location = store.state.location\n store.next(() => ({ ...defaultState, location }), {\n type: LogoutService.Done,\n })\n clearStorage()\n goTo(AppRoutes.Logout)\n })\n}\n","import {\n defaultRouterState,\n WithConnectReactRouterState,\n} from '@restate/router'\nimport {\n AppDrawerState,\n defaultAppDrawerState,\n} from 'components/AppDrawer/AppDrawer.state'\nimport {\n defaultUserMenuState,\n UserMenuState,\n} from 'components/UserMenu/UserMenu.state'\nimport { defaultI18NState, I18NState } from 'I18N/I18N.state'\nimport { ResultConfig } from 'model/CptConfig'\nimport { Institute } from 'model/Institute'\nimport {\n AcceptInvitationPageState,\n defaultAcceptInvitationPageState,\n} from 'pages/AcceptInvitation.tsx/AcceptInvitation.state'\nimport {\n AdminInviteState,\n defaultAdminInviteState,\n} from 'pages/AdminInvite/AdminInvite.state'\nimport { AdminsState, defaultAdminsState } from 'pages/Admins/Admins.state'\nimport { CourseState, defaultCourseState } from 'pages/Course/Course.state'\nimport { CoursesState, defaultCoursesState } from 'pages/Courses/Courses.state'\nimport {\n defaultExportPageState,\n ExportPageState,\n} from 'pages/Export/Export.state'\nimport {\n defaultGlobalSettingsState,\n GlobalSettingsState,\n} from 'pages/GlobalSettings/GlobalSettings.state'\nimport {\n defaultInstituteResultConfigState,\n defaultInstituteState,\n InstituteState,\n} from 'pages/Institute/Institute.state'\nimport {\n defaultInstitutesState,\n InstitutesState,\n} from 'pages/Institutes/Institutes.state'\nimport { defaultLoginState, LoginState } from 'pages/Login/Login.state'\nimport {\n defaultLoginPasswordForgotState,\n LoginPasswordForgotState,\n} from 'pages/LoginPasswordForgot/LoginPasswordForgot.state'\nimport {\n defaultLoginPasswordForgotSetPasswordState,\n LoginPasswordForgotSetPasswordState,\n} from 'pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.state'\nimport { defaultMeState, MeState } from 'pages/Me/Me.state'\nimport {\n defaultRegisterState,\n RegisterState,\n} from 'pages/Register/Register.state'\nimport {\n defaultSettingsState,\n SettingsState,\n} from 'pages/Settings/Settings.state'\nimport {\n defaultSharingObjectsState,\n SharingObjectsState,\n} from 'pages/SharingObject/SharingObject.state'\nimport {\n defaultSingleTrainingsState,\n SingleTrainingsState,\n} from 'pages/SingleTrainings/SingleTrainings.state'\nimport {\n defaultTrainerInviteState,\n TrainerInviteState,\n} from 'pages/TrainerInvite/TrainerInvite.state'\nimport {\n defaultTrainersState,\n TrainersState,\n} from 'pages/Trainers/Trainers.state'\nimport {\n defaultTrainingsPageState,\n TrainingsPageState,\n} from 'pages/Trainings/Trainings.state.'\nimport {\n defaultTrainingsTableState,\n TrainingsTablePageState,\n} from 'pages/TrainingsTablePage/TrainingsTablePage.state'\nimport {\n defaultUserChangeEmailState,\n UserChangeEmailState,\n} from 'pages/UserChangeEmail/UserChangeEmail.state'\nimport {\n defaultUserChangePasswordState,\n UserChangePasswordState,\n} from 'pages/UserChangePassword/UserChangePassword.state'\nimport {\n defaultUserDetailsState,\n UserDetailsState,\n} from 'pages/UserDetails/UserDetails.state'\nimport {\n defaultNetworkState,\n NetworkState,\n} from 'services/network/network.state'\nimport {\n defaultSessionState,\n SessionState,\n} from 'services/session/session.state'\nimport {\n defaultOnboardingState,\n OnboardingState,\n} from '../components/Reminder/Reminder.state'\nimport {\n DashboardState,\n defaultDashboardState,\n} from '../pages/Dashboard/Dashboard.state'\nimport {\n defaultTraineesState,\n TraineesState,\n} from '../pages/Trainees/Trainees.state'\nimport {\n defaultRouterExtensionState,\n RouterExtensionState,\n} from '../services/router/router.service'\nimport {\n defaultTraineeSharesState,\n TraineeSharesState,\n} from 'pages/TraineeShares/TraineeShares.state'\nimport {\n defaultInstituteAdminSharesState,\n InstituteAdminSharesState,\n} from 'pages/InstituteAdminShares/InstituteAdminShares.state'\n\nexport interface State extends WithConnectReactRouterState {\n services: {\n institutes: Institute[]\n }\n pages: {\n acceptInvitation: AcceptInvitationPageState\n adminInvite: AdminInviteState\n admins: AdminsState\n course: CourseState\n courses: CoursesState\n dashboard: DashboardState\n export: ExportPageState\n globalSettings: GlobalSettingsState\n institute: InstituteState\n instituteAdminShares: InstituteAdminSharesState\n instituteResultConfig: ResultConfig\n institutes: InstitutesState\n login: LoginState\n loginPasswordForgot: LoginPasswordForgotState\n loginPasswordForgotSetPassword: LoginPasswordForgotSetPasswordState\n me: MeState\n onboarding: OnboardingState\n register: RegisterState\n settings: SettingsState\n sharingObjects: SharingObjectsState\n singleTrainings: SingleTrainingsState\n trainees: TraineesState\n traineeShares: TraineeSharesState\n trainerInvite: TrainerInviteState\n trainers: TrainersState\n trainings: TrainingsPageState\n trainingsTable: TrainingsTablePageState\n userChangeEmail: UserChangeEmailState\n userChangePassword: UserChangePasswordState\n userDetails: UserDetailsState\n }\n components: {\n appDrawer: AppDrawerState\n userMenu: UserMenuState\n }\n document: {\n title: string\n }\n network: NetworkState\n i18n: I18NState\n session: SessionState\n routerExtension: RouterExtensionState\n}\n\nexport const defaultState: State = {\n services: {\n institutes: [],\n },\n pages: {\n acceptInvitation: defaultAcceptInvitationPageState,\n adminInvite: defaultAdminInviteState,\n admins: defaultAdminsState,\n course: defaultCourseState,\n courses: defaultCoursesState,\n dashboard: defaultDashboardState,\n export: defaultExportPageState,\n globalSettings: defaultGlobalSettingsState,\n institute: defaultInstituteState,\n instituteAdminShares: defaultInstituteAdminSharesState,\n instituteResultConfig: defaultInstituteResultConfigState,\n institutes: defaultInstitutesState,\n login: defaultLoginState,\n loginPasswordForgot: defaultLoginPasswordForgotState,\n loginPasswordForgotSetPassword: defaultLoginPasswordForgotSetPasswordState,\n me: defaultMeState,\n onboarding: defaultOnboardingState,\n register: defaultRegisterState,\n settings: defaultSettingsState,\n sharingObjects: defaultSharingObjectsState,\n singleTrainings: defaultSingleTrainingsState,\n trainees: defaultTraineesState,\n traineeShares: defaultTraineeSharesState,\n trainerInvite: defaultTrainerInviteState,\n trainers: defaultTrainersState,\n trainings: defaultTrainingsPageState,\n trainingsTable: defaultTrainingsTableState,\n userChangeEmail: defaultUserChangeEmailState,\n userChangePassword: defaultUserChangePasswordState,\n userDetails: defaultUserDetailsState,\n },\n network: defaultNetworkState,\n session: defaultSessionState,\n components: {\n appDrawer: defaultAppDrawerState,\n userMenu: defaultUserMenuState,\n },\n document: {\n title: '',\n },\n location: { ...defaultRouterState },\n i18n: defaultI18NState,\n routerExtension: defaultRouterExtensionState,\n}\n","export interface AdminInviteState {\n email: string\n send: boolean\n error: string | null\n meta: {\n loading: boolean\n notFound: boolean\n }\n}\n\nexport const defaultAdminInviteState: AdminInviteState = {\n email: '',\n send: false,\n error: null,\n meta: {\n loading: false,\n notFound: false,\n },\n}\n","import { InstituteAdminUserDTO } from 'model/User.dto'\n\nexport interface AdminsState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n admins: InstituteAdminUserDTO[]\n}\n\nexport const defaultAdminsState: AdminsState = {\n meta: {\n loading: false,\n notFound: false,\n },\n admins: [],\n}\n","import { Course } from 'model/Course'\nimport { Institute } from 'model/Institute'\nimport { TrainerDTO } from 'model/ctrl/trainers/GetTrainersRes.schema'\n\nexport interface CourseAggregate extends Course {\n institute: Institute\n trainer: TrainerDTO\n}\n\nexport interface CourseState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n course: CourseAggregate | null\n}\n\nexport const defaultCourseState: CourseState = {\n meta: {\n loading: false,\n notFound: false,\n },\n course: null,\n}\n","import { CourseTableData } from 'components/CourseTable/CourseTable'\nimport { Message } from '@restate/core'\n\nexport interface CoursesPageMessage extends Message {\n type:\n | 'Page/Courses/Service/Update'\n | 'Page/Courses/Service/Error'\n | 'Page/Courses/Delete'\n payload?: string\n}\n\nexport interface CoursesState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n data: CourseTableData[]\n}\n\nexport const defaultCoursesState: CoursesState = {\n meta: {\n loading: true,\n notFound: false,\n },\n data: [],\n}\n","import { GenericTableData } from 'components/GenericTable/GenericTable'\n\nexport interface ExportTableData extends GenericTableData {\n date: Date\n institute: string\n identifier: string\n location: string\n traineeCount: number\n}\n\nexport interface ExportPageState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n courses: ExportTableData[]\n}\n\nexport const defaultExportPageState: ExportPageState = {\n meta: {\n loading: false,\n notFound: false,\n },\n courses: [],\n}\n","import { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\n\nexport interface InstituteAdminSharesState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n sharingObjects: SharingObjectDocument[]\n}\n\nexport const defaultInstituteAdminSharesState: InstituteAdminSharesState = {\n meta: {\n loading: false,\n notFound: false,\n },\n sharingObjects: [],\n}\n","export interface InstituteEntry {\n _id: string\n name: string\n street: string\n zip: string\n city: string\n country: string\n}\n\nexport interface InstitutesState {\n meta: {\n loading: boolean\n }\n entries: InstituteEntry[]\n}\n\nexport const defaultInstitutesState: InstitutesState = {\n meta: {\n loading: true,\n },\n entries: [],\n}\n","export interface LoginState {\n email: string\n password: string\n showProgress: boolean\n error: string | null\n}\n\nexport const defaultLoginState: LoginState = {\n email: '',\n password: '',\n showProgress: false,\n error: null,\n}\n","type SEND = 'input' | 'sending' | 'send' | 'error'\n\nexport interface LoginPasswordForgotState {\n send: SEND\n}\n\nexport const defaultLoginPasswordForgotState: LoginPasswordForgotState = {\n send: 'input',\n}\n","export interface LoginPasswordForgotSetPasswordState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n success: boolean\n}\n\nexport const defaultLoginPasswordForgotSetPasswordState: LoginPasswordForgotSetPasswordState = {\n meta: {\n loading: true,\n notFound: false,\n },\n success: false,\n}\n","export interface RegisterState {\n firstName: string\n lastName: string\n email: string\n password: string\n termsOfUseAccepted: boolean\n showProgress: boolean\n error: string | null\n success: boolean\n}\n\nexport const defaultRegisterState: RegisterState = {\n firstName: '',\n lastName: '',\n email: '',\n password: '',\n termsOfUseAccepted: false,\n showProgress: false,\n error: null,\n success: false,\n}\n","import { CptConfig } from 'model/CptConfig'\n\nexport interface SettingsState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n appConfig: CptConfig | null\n}\n\nexport const defaultSettingsState: SettingsState = {\n meta: {\n loading: false,\n notFound: false,\n },\n appConfig: null,\n}\n","import { UUID } from 'model/UUID'\nimport { SingleTrainingView } from './SingleTrainings.page-service'\nimport { SharingTraineeAggregate } from 'model/SharingTraineeAggregate'\n\nexport type SingleTrainingsState = {\n singleTrainings: SingleTrainingView[]\n traineeSharingObjects: SharingTraineeAggregate[]\n share: {\n selectedTrainingId: UUID\n selectedTraineeSharingObject: UUID[]\n }\n}\n\nexport const defaultSingleTrainingsState: SingleTrainingsState = {\n singleTrainings: [],\n traineeSharingObjects: [],\n share: {\n selectedTrainingId: '',\n selectedTraineeSharingObject: [],\n },\n}\n","export interface TrainerInviteState {\n email: string\n send: boolean\n meta: {\n loading: boolean\n notFound: boolean\n }\n}\n\nexport const defaultTrainerInviteState: TrainerInviteState = {\n email: '',\n send: false,\n meta: {\n loading: false,\n notFound: false,\n },\n}\n","import { GenericTableData } from 'components/GenericTable/GenericTable'\nimport { TrainerDTO } from 'model/ctrl/trainers/GetTrainersRes.schema'\n\nexport type TrainersTableData = TrainerDTO &\n GenericTableData & { displayName: string }\n\nexport interface TrainersState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n data: TrainersTableData[]\n}\n\nexport const defaultTrainersState: TrainersState = {\n meta: {\n loading: true,\n notFound: false,\n },\n data: [],\n}\n","export interface TrainingsPageState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n idx: number\n}\n\nexport const defaultTrainingsPageState: TrainingsPageState = {\n meta: {\n loading: false,\n notFound: false,\n },\n idx: 0,\n}\n","import { TrainingsTableData } from '../../components/TrainingsTable/TrainingsTable'\n\nexport interface TrainingsTablePageState {\n meta: {\n loading: false\n }\n data: TrainingsTableData[]\n}\n\nexport const defaultTrainingsTableState: TrainingsTablePageState = {\n meta: {\n loading: false,\n },\n data: [],\n}\n","import { Message } from '@restate/core'\n\nexport interface PagesUserChangeEmailMessages extends Message {\n type: 'USER/CHANGE_EMAIL/SEND'\n}\n\nexport interface UserChangeEmailState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n nextEmail: string\n send: boolean\n errorNextEmail: boolean\n errorNextEmailMessage: string\n}\n\nexport const defaultUserChangeEmailState: UserChangeEmailState = {\n meta: {\n loading: false,\n notFound: false,\n },\n nextEmail: '',\n send: false,\n errorNextEmail: false,\n errorNextEmailMessage: '',\n}\n","export interface UserChangePasswordState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n}\n\nexport const defaultUserChangePasswordState: UserChangePasswordState = {\n meta: {\n loading: false,\n notFound: false,\n },\n}\n","import { UserDetailsDTO } from 'model/ctrl/user/GetUserRes.schema'\n\nexport interface UserDetailsState {\n meta: {\n loading: boolean\n notFound: boolean\n }\n userDetails: UserDetailsDTO | null\n}\n\nexport const defaultUserDetailsState: UserDetailsState = {\n meta: {\n loading: true,\n notFound: false,\n },\n userDetails: null,\n}\n","export interface NetworkState {\n online: boolean\n}\n\nexport const defaultNetworkState: NetworkState = {\n online: true,\n}\n","export interface UserMenuState {\n avatarUrl: string\n userName: string\n eMail: string\n}\n\nexport const defaultUserMenuState: UserMenuState = {\n avatarUrl: '',\n userName: '',\n eMail: '',\n}\n","import { RxStore } from '@restate/core'\nimport { History } from 'history'\nimport { map } from 'rxjs/operators'\nimport { tools } from 'services/utils/tools'\nimport { AppMessages } from 'state/appMessages'\nimport { State } from 'state/state'\nimport { GoMessage, RouterMessageType } from './router.restate'\n\nexport const defaultRouterExtensionState = {\n embeddedMode: false,\n}\n\nexport interface RouterExtensionState {\n embeddedMode: boolean\n}\n\ninterface ConnectRouterProps {\n store: RxStore\n history: History\n}\n\nexport function connectRouter({ store, history }: ConnectRouterProps) {\n const { onAction } = tools(store)\n\n const subs = [\n onAction({ type: RouterMessageType.GO })\n .pipe(\n map(pack => pack.message as GoMessage),\n map(message => message.payload.path)\n )\n .subscribe(path => {\n history.push(path)\n }),\n onAction({ type: RouterMessageType.BACK }).subscribe(() => {\n history.goBack()\n }),\n ]\n\n return function cleanUp() {\n subs.forEach(sub => sub.unsubscribe())\n }\n}\n","function deleteAllCookies() {\n const cookies = document.cookie.split(';')\n\n for (let i = 0; i < cookies.length; i++) {\n var cookie = cookies[i]\n var eqPos = cookie.indexOf('=')\n var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie\n document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT'\n }\n}\n\nexport function clearStorage() {\n localStorage.clear()\n sessionStorage.clear()\n deleteAllCookies()\n}\n","import { animationFrameScheduler } from 'rxjs'\nimport { filter, observeOn } from 'rxjs/operators'\nimport { AppMessages } from 'state/appMessages'\nimport { AppStore } from 'state/store'\n\nexport type ActionType = Pick\n\nexport const onAction = (store: AppStore) => (actionType: ActionType) =>\n store.state$.pipe(\n observeOn(animationFrameScheduler),\n filter(update => update.message.type === actionType.type)\n )\n","import { animationFrameScheduler } from 'rxjs'\nimport { distinctUntilChanged } from 'rxjs/internal/operators/distinctUntilChanged'\nimport { map, observeOn } from 'rxjs/operators'\nimport { State } from 'state/state'\nimport { AppStore } from 'state/store'\n\nexport const onChange = (store: AppStore) => (\n selector: (state: State) => T\n) =>\n store.state$.pipe(\n observeOn(animationFrameScheduler),\n map(update => selector(update.state)),\n distinctUntilChanged()\n )\n","import { filter } from 'rxjs/internal/operators/filter'\nimport { AppStore } from 'state/store'\nimport { onChange } from './onChange'\nimport { map } from 'rxjs/operators'\n\nexport const onLogin = (store: AppStore) => () =>\n onChange(store)(state => state.session.token).pipe(\n map(token => token !== null),\n filter(hasToken => hasToken === true)\n )\n","import { LogoutService } from 'services/logout/logout.service'\nimport { AppStore } from 'state/store'\nimport { onAction } from './onAction'\n\nexport const onLogout = (store: AppStore) => () =>\n onAction(store)({ type: LogoutService.Logout })\n","import RouteParser from 'route-parser'\nimport { Observable, animationFrameScheduler } from 'rxjs'\nimport { map } from 'rxjs/internal/operators/map'\nimport { distinctUntilChanged, filter, observeOn } from 'rxjs/operators'\nimport { AppStore } from 'state/store'\n\nexport const onPageEnter = (store: AppStore) => (route: string) => {\n const parser = new RouteParser(route)\n\n const ret = store.state$.pipe(\n observeOn(animationFrameScheduler),\n map(update => update.state.location.pathname),\n distinctUntilChanged(),\n map(pathname => parser.match(pathname)),\n filter(params => params !== false)\n )\n\n return (ret as unknown) as Observable<{ [x: string]: any }>\n}\n","import RouteParser from 'route-parser'\nimport { animationFrameScheduler } from 'rxjs'\nimport { map } from 'rxjs/internal/operators/map'\nimport {\n distinctUntilChanged,\n filter,\n observeOn,\n pairwise,\n} from 'rxjs/operators'\nimport { AppStore } from 'state/store'\n\nexport const onPageLeave = (store: AppStore) => (route: string) => {\n const parser = new RouteParser(route)\n\n const ret = store.state$.pipe(\n observeOn(animationFrameScheduler),\n map(update => update.state.location.pathname),\n distinctUntilChanged(),\n pairwise(),\n map(([oldPage, currPage]) => ({\n oldPageIsPage: parser.match(oldPage) !== false,\n currPageIsPage: parser.match(currPage) !== false,\n })),\n filter(\n ({ oldPageIsPage, currPageIsPage }) =>\n oldPageIsPage === true && currPageIsPage === false\n )\n )\n\n return ret\n}\n","import { UserRole } from 'model/UserRole'\nimport { animationFrameScheduler } from 'rxjs'\nimport { filter, map, observeOn, distinctUntilChanged } from 'rxjs/operators'\nimport { AppStore } from 'state/store'\n\nexport const hasUserRole = (store: AppStore) => (...roles: UserRole[]) =>\n store.state$.pipe(\n observeOn(animationFrameScheduler),\n map(update => update.state.session.user.role as UserRole),\n distinctUntilChanged(),\n filter((currentUserRole: UserRole) => roles.indexOf(currentUserRole) > -1)\n )\n","import { AppStore } from 'state/store'\n\nexport const snackBar = (store: AppStore) => ({\n success(msg: string) {\n store.dispatch({ type: 'AppSnackBar/Success', message: msg })\n },\n error(msg: string) {\n store.dispatch({ type: 'AppSnackBar/Error', message: msg })\n },\n})\n","import { AppStore } from 'state/store'\nimport RouteParser from 'route-parser'\n\nexport const pageParams = (store: AppStore) => (route: string) => {\n const routeParser = new RouteParser(route)\n return () => {\n const pathname = store.state.location.pathname\n const match = routeParser.match(pathname)\n return match !== false ? match : {}\n }\n}\n","import { AppStore } from 'state/store'\nimport { onPageEnter } from './onPageEnter'\nimport { onLogin } from './onLogin'\nimport { combineLatest, animationFrameScheduler } from 'rxjs'\nimport { map, observeOn, filter } from 'rxjs/operators'\nimport { UserRole, USERROLES } from 'model/UserRole'\n\ninterface OnLoginPageEnterProps {\n roles: UserRole[]\n}\n\nconst defaultOnLoginPageEnterProps = {\n roles: [\n USERROLES.CorPatchAdmin,\n USERROLES.InstituteAdmin,\n USERROLES.Trainer,\n USERROLES.Trainee,\n USERROLES.Unknown,\n ] as UserRole[],\n}\n\n/**\n * If the user opens a page and is logged in\n */\nexport const onLoginPageEnter = (store: AppStore) => (\n route: string,\n props: OnLoginPageEnterProps = defaultOnLoginPageEnterProps\n) => {\n const enterEvent = onPageEnter(store)(route)\n const loginEvent = onLogin(store)()\n\n function hasRole() {\n return props.roles.indexOf(store.state.session.user.role) !== -1\n }\n\n return combineLatest(enterEvent, loginEvent).pipe(\n observeOn(animationFrameScheduler),\n filter(hasRole),\n map(arr => ({\n pageEnter: arr[0],\n loginEvent: arr[1],\n }))\n )\n}\n","import { createIntl, createIntlCache } from 'react-intl'\nimport { AppStore } from 'state/store'\n\nconst translations: any = {\n de: require(`../../I18N/translations/de`),\n en: require(`../../I18N/translations/en`),\n da: require(`../../I18N/translations/da`),\n fi: require(`../../I18N/translations/fi`),\n it: require(`../../I18N/translations/it`),\n es: require(`../../I18N/translations/es`),\n}\n\nconst cache = createIntlCache()\n\n//\n// see https://github.com/formatjs/react-intl/blob/master/docs/API.md#createintl\n//\nexport const intl = (store: AppStore) => () => {\n const locale = store.state.i18n.locale\n const language = locale.split(/[-_]/)[0] // language without region code\n const messages: any = translations[language] || translations['de']\n const intl = createIntl({ locale, messages }, cache)\n return intl\n}\n","import { AppStore } from 'state/store'\nimport { goTo } from './goTo'\nimport { http } from './http'\nimport { onAction } from './onAction'\nimport { onChange } from './onChange'\nimport { onLogin } from './onLogin'\nimport { onLogout } from './onLogout'\nimport { onPageEnter } from './onPageEnter'\nimport { onPageLeave } from './onPageLeave'\nimport { hasUserRole } from './hasUserRole'\nimport { snackBar } from './snackBar'\nimport { pageParams } from './pageParams'\nimport { onLoginPageEnter } from './onLoginPageEnter'\nimport { intl } from './intl'\n\nexport const tools = (store: AppStore) => ({\n goTo: goTo(store),\n hasUserRole: hasUserRole(store),\n http: http(store),\n intl: intl(store),\n onAction: onAction(store),\n onChange: onChange(store),\n onLogin: onLogin(store),\n onLoginPageEnter: onLoginPageEnter(store),\n onLogout: onLogout(store),\n onPageEnter: onPageEnter(store),\n onPageLeave: onPageLeave(store),\n pageParams: pageParams(store),\n snackBar: snackBar(store),\n})\n","import axios, { AxiosRequestConfig } from 'axios'\nimport { config } from 'config/config'\nimport RouteParser from 'route-parser'\nimport { AppRoutes } from 'routes'\nimport { Observable } from 'rxjs'\nimport { LogoutService } from 'services/logout/logout.service'\nimport { AppStore } from 'state/store'\nimport { goTo } from './goTo'\n\ninterface HttpProps extends AxiosRequestConfig {\n route?: {\n path: string\n id?: string\n token?: string\n }\n}\n\nexport interface HttpError {\n errorMessage: T\n status: number\n}\n\nexport const http = (_store: AppStore) => (conf: HttpProps) => {\n const { route } = conf\n\n if (route) {\n const { api } = config()\n const routeParser = new RouteParser(route.path)\n const params = route.id\n ? { id: route.id }\n : route.token\n ? { token: route.token }\n : {}\n const fqRoute = routeParser.reverse(params)\n conf.url = api + fqRoute\n }\n\n const request$ = new Observable(observable => {\n console.log('HTTP [REQ]: ' + conf.url, conf)\n axios(conf)\n .then(response => {\n console.log('HTTP [RES]', response)\n observable.next(response.data.data)\n observable.complete()\n })\n .catch(err => {\n const redirect = goTo(_store)\n\n if (!err.response || !err.response.status) {\n // TODO: handle Network error (server is not responding)\n return redirect(AppRoutes.NetworkError)\n }\n\n const status = err.response.status\n\n if (status === 400 || status === 500) {\n return redirect(AppRoutes.InternalServerError)\n }\n\n if (status === 401) {\n _store.dispatch({ type: LogoutService.Logout })\n }\n\n const errMsg: HttpError = {\n errorMessage:\n err.response.data?.errorMessage ||\n 'No error message provided by server.',\n status,\n }\n observable.error(errMsg)\n })\n })\n\n return request$\n}\n","import { distinctUntilChanged, map } from 'rxjs/operators'\nimport { AppStore } from 'state/store'\nimport { FrontendLocale } from './I18N.state'\n\nconst LangReg = /lang=(\\w*)/\n\nfunction setLocale(search: string, store: AppStore) {\n const matches = LangReg.exec(search)\n if (matches) {\n const language = matches[1]\n\n const lang: FrontendLocale =\n ({\n de: 'de-DE',\n en: 'en-US',\n da: 'da-DA',\n fi: 'fi-FI',\n it: 'it-IT',\n es: 'es-ES',\n ar: 'ar-SA',\n } as any)[language] || 'en-US'\n\n if (language) {\n store.next(s => {\n s.i18n.locale = lang\n })\n }\n }\n}\n\n// Enables the user to change the language to another local using ?lang=de for example\nexport function connectLanguageQueryParam(store: AppStore) {\n store.state$\n .pipe(\n map(update => update.state.location.search),\n distinctUntilChanged()\n )\n .subscribe(search => setLocale(search, store))\n}\n","export const routes = {\n auth: {\n login: '/api/auth/login',\n validateLogin: '/api/auth/authenticate/email',\n changeRole: '/api/auth/changeRole',\n me: '/api/auth/me', // TODO: move to `me`\n signup: '/api/auth/signup',\n delete: '/api/auth/delete',\n traineeSignUp: '/api/auth/traineeSignUp',\n validate: '/api/auth/validate/:id',\n validateEmail: '/api/auth/email/validate/:id',\n initialPassword: '/api/auth/initialPassword',\n },\n forgotPassword: {\n sendEmail: '/api/auth/forgotPassword/sendEmail',\n resetPassword: '/api/auth/forgotPassword/resetPassword',\n checkCode: '/api/auth/forgotPassword/checkCode/:id',\n },\n corPatchAdmin: {\n institute: '/api/corpatch-admin/institutes/:id',\n institutes: '/api/corpatch-admin/institutes/',\n globalConfig: '/api/corpatch-admin/global-config',\n resultConfig: '/api/corpatch-admin/resultConfig/institute/:id',\n resultConfigInstituteAdmin: '/api/institute-admin/resultConfig/institute',\n deletedData: '/api/deletion',\n notifyUser: '/api/notification/user',\n testNotifications: '/api/notification/test/:id',\n },\n cron: {\n notifications: '/api/cron/notifications',\n purgeData: '/api/cron/purge',\n },\n export: {\n csv: '/api/export/csv/:id',\n json: '/api/export/json/:id',\n allCPS: '/api/export/cpx',\n allMobiles: '/api/export/mobiles',\n },\n me: {\n changeEmail: '/api/me/email',\n changePassword: '/api/me/password',\n changeMe: '/api/me/update',\n settings: '/api/me/settings',\n },\n research: {\n courses: '/api/research/courses',\n rawData: '/api/research/rawData',\n },\n mobile: {\n count: '/api/mobile/count',\n device: '/api/mobile/devices/:id',\n devices: '/api/mobile/devices',\n status: '/api/mobile/status',\n },\n cpx: {\n user: '/api/cpx/user/device',\n count: '/api/cpx/count',\n connect: '/api/cpx/connect',\n device: '/api/cpx/devices/:id',\n devices: '/api/cpx/devices',\n },\n cpt: {\n config: '/api/config',\n },\n cps: {\n config: '/api/cps/config',\n pushToken: '/api/cps/push',\n singleTrainings: '/api/cps/single-training',\n userSingleTrainings: '/api/cps/single-training/:id',\n },\n onboarding: {\n onboarding: '/api/onboarding',\n resendVerificationEmail: '/api/onboarding/email/validate',\n },\n course: '/api/courses/:id',\n courses: '/api/courses',\n dashboard: '/api/dashboard',\n hooks: {\n ecwid: '/api/hooks/ecwid',\n },\n sharing: {\n trainee: {\n acceptInvitation: '/api/sharing/trainee/accept-invitation',\n deactivateInvitation: '/api/sharing/trainee/deactivate-invitation',\n sharingObjects: '/api/sharing/trainee/sharing-objects',\n postSingleTraining: '/api/sharing/trainee/post-single-training',\n },\n admin: {\n deleteSharingObject: '/api/sharing/admin/delete-sharing-object/:id',\n },\n instituteAdmin: {},\n pullRequest: '/api/sharing/pull/:sharingObjectId',\n sharingObject: '/api/sharing/sharingObjects/:id',\n sharingObjects: '/api/sharing/sharingObjects',\n dummy: '/api/sharing/dummy',\n },\n rawData: '/api/rawData',\n shopSso: '/api/shop',\n trainees: '/api/trainees',\n trainer: '/api/trainers/:id',\n trainers: '/api/trainers',\n user: '/api/user/:id',\n userInviteAgain: '/api/user/:id/invite',\n userDelete: '/api/user/:id/delete',\n debug: '/api/debug',\n debugEntry: '/api/debug/:sessionId',\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n inviteCardTitle: {\n id: 'cp.pages.adminInvite.inviteCardTitle',\n defaultMessage: 'Invite Admin',\n },\n successSnackbar: {\n id: 'cp.pages.adminInvite.successSnackbar',\n defaultMessage: 'Email send to {email}',\n },\n errorSnackbar: {\n id: 'cp.pages.adminInvite.errorSnackbar',\n defaultMessage: 'E-Mail {email} is in use',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n roleInstituteAdmin: {\n id: 'cp.pages.courses.roleInstituteAdmin',\n defaultMessage: 'Institute Admin',\n },\n roleTrainee: {\n id: 'cp.pages.courses.roleTrainee',\n defaultMessage: 'Trainee',\n },\n pageTitle: {\n id: 'cp.pages.courses.pageTitle',\n defaultMessage: 'Courses',\n },\n pageNotFoundTitle: {\n id: 'cp.pages.courses.pageNotFoundTitle',\n defaultMessage: 'Nicht gefunden.',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.courses.pageNotFoundMessage',\n defaultMessage: 'Wurde gelöscht. Sorry :(',\n },\n successSnackbar: {\n id: 'cp.pages.courses.successSnackbar',\n defaultMessage: 'Course has been deleted successfully',\n },\n errorSnackbar: {\n id: 'cp.pages.courses.errorSnackbar',\n defaultMessage: 'Sorry, course could not be deleted',\n },\n})\n","import { Course } from 'model/Course'\nimport { routes } from 'model/ctrl/routes'\nimport { TrainerDTO } from 'model/ctrl/trainers/GetTrainersRes.schema'\nimport { Institute } from 'model/Institute'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { USERROLES } from '../../model/UserRole'\nimport { AppRoutes } from '../../routes'\nimport { ExportTableData } from './Export.state'\n\nexport interface CourseAggregate extends Course {\n institute: Institute\n trainer: TrainerDTO\n}\n\nfunction model2ViewModel(model: CourseAggregate[]): ExportTableData[] {\n return model.map(course => ({\n id: (course as any)._id as string,\n selected: false,\n isSelectionEnabled: true,\n date: new Date(course.date),\n institute: course.institute.name,\n identifier: course.identifier || '',\n location: course.location,\n traineeCount: course.trainees.length,\n }))\n}\n\nexport const connectExportPageService = (store: AppStore) => {\n const { onLoginPageEnter, http } = tools(store)\n\n onLoginPageEnter(AppRoutes.Export, {\n roles: [\n USERROLES.CorPatchAdmin,\n USERROLES.InstituteAdmin,\n USERROLES.Trainer,\n ],\n }).subscribe(() => {\n http({ route: { path: routes.courses } }).subscribe(\n courses => {\n store.next(\n state => {\n state.pages.export.courses = model2ViewModel(courses)\n },\n { type: 'Page/Courses/Service/Update' }\n )\n },\n\n _error => {\n console.error(_error)\n store.next(\n state => {\n state.pages.courses.data = []\n state.pages.courses.meta.notFound = true\n state.pages.courses.meta.loading = false\n },\n { type: 'Page/Courses/Service/Error' }\n )\n }\n )\n })\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n tabsBase: {\n id: 'cp.pages.institute.tabsBaseData',\n defaultMessage: 'BASE DATA',\n },\n tabsAdmins: {\n id: 'cp.pages.institute.tabsAdmins',\n defaultMessage: 'ADMINS',\n },\n tabsTrainers: {\n id: 'cp.pages.institute.tabsTrainers',\n defaultMessage: 'TRAINERS',\n },\n institutePageNotFoundTitle: {\n id: 'cp.pages.institute.PageNotFound.title',\n defaultMessage: 'Institute not found.',\n },\n institutePageNotFoundMessage: {\n id: 'cp.pages.institute.PageNotFound.message',\n defaultMessage:\n 'This institute has been deleted and cannot be edited anymore.',\n },\n institute: {\n id: 'cp.pages.institute.institute',\n defaultMessage: 'Institute',\n },\n instituteSuccessSnackbar: {\n id: 'cp.pages.institute.snackbarSuccess',\n defaultMessage: 'Saved',\n },\n instituteErrorSnackbar: {\n id: 'cp.pages.institute.snackbarError',\n defaultMessage: 'Error saving institute',\n },\n})\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { InstituteDocumentWithUsers } from 'model/ctrl/institute/GetInstituteRes.schema'\nimport { routes } from 'model/ctrl/routes'\nimport { GlobalConfig } from 'model/GlobalConfig'\nimport { Institute } from 'model/Institute'\nimport RouteParser from 'route-parser'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { ResultConfig } from '../../model/CptConfig'\nimport { Locale } from '../../model/Locale'\nimport { USERROLES } from '../../model/UserRole'\nimport messages from './Institute.messages'\nimport {\n defaultInstituteResultConfigState,\n defaultInstituteState,\n InstituteState,\n} from './Institute.state'\nimport { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\n\nexport let institutePageTabIndex = 0\nexport const setInstitutePageTabIndex = (newPageIndex: number) => {\n institutePageTabIndex = newPageIndex\n}\n\nfunction model2ViewModel(model: InstituteDocumentWithUsers): InstituteState {\n return {\n id: model._id,\n meta: {\n loading: false,\n notFound: false,\n error: null,\n },\n name: model.name,\n address: model.address,\n settings: model.settings ? model.settings : { locale: Locale.en },\n admins: model.admins,\n trainers: model.trainers,\n sharingObjects: model.sharingObjects,\n }\n}\n\nfunction viewModel2Model(viewModel: InstituteState): Institute {\n return {\n name: viewModel.name,\n address: viewModel.address,\n settings: viewModel.settings,\n }\n}\n\nexport interface PagesInstituteServiceMessages extends Message {\n type:\n | 'Pages/Institute/CorPatchAdmin/Sharing/Create'\n | 'Pages/Institute/CorPatchAdmin/ResultConfig/Save'\n | 'Pages/Institute/Service/Error'\n | 'Pages/Institute/Service/Loading'\n | 'Pages/Institute/Service/Save'\n | 'Pages/Institute/Service/Update'\n}\n\nexport const connectInstitutePage = (store: AppStore) => {\n const {\n onLoginPageEnter,\n http,\n snackBar,\n onAction,\n onPageLeave,\n goTo,\n } = tools(store)\n\n const { api } = config()\n\n function setLoading() {\n store.next(\n state => {\n state.pages.institute = defaultInstituteState\n },\n { type: 'Pages/Institute/Service/Loading' }\n )\n }\n\n //\n // entering page and user is a corpatch admin\n //\n onLoginPageEnter(AppRoutes.Institute, {\n roles: [USERROLES.CorPatchAdmin],\n }).subscribe(params => {\n const { id } = params.pageEnter\n\n //\n // Fetch\n //\n function fetchData(id: string) {\n const onSuccess = (institute: InstituteDocumentWithUsers) => {\n store.next(\n state => {\n state.pages.institute.id = id\n state.pages.institute = model2ViewModel(institute)\n },\n { type: 'Pages/Institute/Service/Update' }\n )\n }\n\n const onError = () =>\n store.next(\n state => {\n state.pages.institute = defaultInstituteState\n state.pages.institute.meta.notFound = true\n state.pages.institute.meta.loading = false\n },\n { type: 'Pages/Institute/Service/Error' }\n )\n\n http({\n route: { path: routes.corPatchAdmin.institute, id },\n }).subscribe(onSuccess, onError)\n }\n\n function fetchResultConfig(id: string) {\n const onSuccess = (instituteResultConfig: ResultConfig) => {\n store.next(state => {\n state.pages.instituteResultConfig.simple =\n instituteResultConfig.simple\n })\n }\n\n const onError = () =>\n http({\n route: { path: routes.corPatchAdmin.globalConfig },\n }).subscribe(\n (config: GlobalConfig) => {\n console.log('CONFIG: ', config)\n store.next(state => {\n state.pages.instituteResultConfig.simple =\n config.resultConfig.simple\n })\n },\n () => {\n store.next(\n state => {\n state.pages.instituteResultConfig = defaultInstituteResultConfigState\n state.pages.institute.meta.notFound = true\n state.pages.institute.meta.loading = false\n },\n { type: 'Pages/Institute/Service/Error' }\n )\n }\n )\n\n http({\n route: { path: routes.corPatchAdmin.resultConfig, id },\n }).subscribe(onSuccess, onError)\n }\n\n fetchResultConfig(id)\n fetchData(id)\n })\n\n //\n // on page leave\n //\n onPageLeave(AppRoutes.Institute).subscribe(setLoading)\n\n //\n // Save\n //\n onAction({ type: 'Pages/Institute/Service/Save' }).subscribe(() => {\n const { intl } = tools(store)\n\n const successSnackbar = intl().formatMessage(\n messages.instituteSuccessSnackbar\n )\n\n const errorSnackbar = intl().formatMessage(messages.instituteErrorSnackbar)\n\n const institute = viewModel2Model(store.state.pages.institute)\n const id = store.state.pages.institute.id\n const path = new RouteParser(routes.corPatchAdmin.institute).reverse({ id })\n http({\n url: api + path,\n method: 'PUT',\n data: institute,\n }).subscribe(\n _success => snackBar.success(successSnackbar),\n _error => snackBar.error(errorSnackbar)\n )\n })\n\n onAction({\n type: 'Pages/Institute/CorPatchAdmin/ResultConfig/Save',\n }).subscribe(() => {\n const { intl } = tools(store)\n\n const successSnackbar = intl().formatMessage(\n messages.instituteSuccessSnackbar\n )\n\n const errorSnackbar = intl().formatMessage(messages.instituteErrorSnackbar)\n\n const id = store.state.pages.institute.id\n const instituteResultConfig = store.state.pages.instituteResultConfig\n const path = new RouteParser(routes.corPatchAdmin.resultConfig).reverse({\n id,\n })\n http({\n url: api + path,\n method: 'POST',\n data: instituteResultConfig,\n }).subscribe(\n _success => snackBar.success(successSnackbar),\n _error => snackBar.error(errorSnackbar)\n )\n })\n\n //\n // Create a sharing config\n //\n onAction({ type: 'Pages/Institute/CorPatchAdmin/Sharing/Create' }).subscribe(\n () => {\n http({\n url: api + routes.sharing.sharingObjects,\n method: 'PUT',\n data: {\n instituteId: store.state.pages.institute.id,\n },\n }).subscribe(\n (sharingObject: SharingObjectDocument) => {\n store.next(state => {\n state.pages.institute.sharingObjects.push(sharingObject)\n })\n goTo(AppRoutes.SharingObject, { id: sharingObject._id })\n snackBar.success('Sharing object created')\n },\n _error => snackBar.error('Error creating sharing object')\n )\n }\n )\n}\n","import { Message, RxStore } from '@restate/core'\nimport { Institute } from 'model/Institute'\nimport { skip } from 'rxjs/operators'\nimport { tools } from 'services/utils/tools'\nimport { AppMessages } from 'state/appMessages'\nimport { State } from 'state/state'\nimport { InstituteEntry } from './Institutes.state'\n\nexport interface PagesInstitutesServiceMessages extends Message {\n type: 'Pages/Institutes/Update'\n}\n\nfunction model2ViewModel(model: Institute[]): InstituteEntry[] {\n const entries: InstituteEntry[] = model.map(institute => ({\n _id: '' + (institute as any)._id,\n name: institute.name,\n street: institute.address.street,\n zip: institute.address.zip,\n city: institute.address.city,\n country: institute.address.country,\n }))\n\n return entries\n}\n\nexport const connectInstitutesPage = (store: RxStore) => {\n const { onChange } = tools(store)\n\n onChange(state => state.services.institutes)\n .pipe(skip(1))\n .subscribe(institutes => {\n const entries = model2ViewModel(institutes)\n setTimeout(\n () =>\n store.next(\n state => {\n state.pages.institutes.entries = entries\n state.pages.institutes.meta.loading = false\n },\n {\n type: 'Pages/Institutes/Update',\n }\n ),\n 0\n )\n })\n}\n","import { Message } from '@restate/core'\nimport axios from 'axios'\nimport { config } from 'config/config'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { routes } from 'model/ctrl/routes'\nimport { Locale } from 'model/Locale'\nimport { AppRoutes } from 'routes'\n\nimport messages from './Register.messages'\n\nexport enum RegisterService {\n Register = 'Service/Register/Request',\n RegisterSuccess = 'Service/Register/Success',\n}\n\nexport interface RegisterMessage extends Message {\n type: RegisterService.Register\n payload: {\n email: string\n password: string\n firstName: string\n lastName: string\n }\n}\n\nexport type RegisterServiceMessages =\n | RegisterMessage\n | { type: RegisterService.RegisterSuccess }\n\nexport const connectRegister = (store: AppStore) => {\n const { onAction, snackBar, goTo, intl } = tools(store)\n\n onAction({ type: RegisterService.Register }).subscribe(event => {\n const { api } = config()\n const {\n email,\n password,\n firstName,\n lastName,\n } = (event.message as RegisterMessage).payload\n const locale = store.state.pages.userDetails.userDetails?.settings.locale\n ? store.state.pages.userDetails.userDetails.settings.locale\n : Locale.en\n\n store.next(s => {\n s.pages.register.showProgress = true\n s.pages.register.error = ''\n })\n\n axios\n .post(api + routes.auth.traineeSignUp, {\n email,\n password,\n firstName,\n lastName,\n locale,\n })\n .then(function () {\n store.next(s => {\n s.pages.register.showProgress = false\n s.pages.register.success = true\n })\n goTo(AppRoutes.Login)\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n snackBar.success(successSnackbar)\n store.dispatch({ type: RegisterService.RegisterSuccess })\n })\n .catch(function (error) {\n store.next(s => {\n s.pages.register.showProgress = false\n s.pages.register.error = error.response.data.errorMessage\n s.pages.register.success = false\n })\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n snackBar.error(errorSnackbar)\n goTo(AppRoutes.Register)\n })\n })\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n institutePageSnackbarSuccess: {\n id: 'cp.components.general.institutePageSnackbarSuccess',\n defaultMessage: 'Saved',\n },\n institutePageSnackbarError: {\n id: 'cp.components.general.institutePageSnackbarError',\n defaultMessage: 'Error saving institute',\n },\n tableRowName: {\n id: 'cp.components.general.tableRowName',\n defaultMessage: 'Name',\n },\n\n // Util snackbars to use everywhere, default success and failure handlers\n emailAllreadySentSnackbar: {\n id: 'cp.components.general.snackbar.emailAllreadySentSnackbar',\n defaultMessage:\n 'The E-Mail has been sent within the last 10 minutes. Please wait before you can send another one.',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n title: {\n id: 'cp.pages.me.title',\n defaultMessage: 'Personal setting',\n },\n notFoundTitle: {\n id: 'cp.pages.me.notFoundTitle',\n defaultMessage: 'Personal setting',\n },\n firstName: {\n id: 'cp.pages.me.firstName',\n defaultMessage: 'First name',\n },\n familyName: {\n id: 'cp.pages.me.familyName',\n defaultMessage: 'Family name',\n },\n gender: {\n id: 'cp.pages.me.gender',\n defaultMessage: 'Gender',\n },\n genderMale: {\n id: 'cp.pages.me.genderMale',\n defaultMessage: 'Male',\n },\n genderFemale: {\n id: 'cp.pages.me.genderFemale',\n defaultMessage: 'Female',\n },\n genderOther: {\n id: 'cp.pages.me.genderOther',\n defaultMessage: 'Other',\n },\n save: {\n id: 'cp.pages.me.save',\n defaultMessage: 'Save',\n },\n snackBarSaved: {\n id: 'cp.pages.me.snackBarSaved.saved',\n defaultMessage: 'Saved',\n },\n snackBarError: {\n id: 'cp.pages.me.snackBarSaved.error',\n defaultMessage: 'Error saving personal setting',\n },\n deleteOwnButtonRequest: {\n id: 'cp.pages.me.deleteOwnButtonRequest',\n defaultMessage: 'Delete your account permenantly',\n },\n deleteOwnContent: {\n id: 'cp.pages.me.deleteOwnContent',\n defaultMessage:\n 'This action will delete your account permanently. Please be confident that you have saved any data that might get lost when deleting your account. Be advised that you can not reverse this action.',\n },\n deleteOwnButtonConfirm: {\n id: 'cp.pages.me.deleteOwnButtonConfirm',\n defaultMessage: 'Delete your account permanently',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n firstnameField: {\n id: 'cp.pages.register.firstnameField',\n defaultMessage: 'firstname',\n },\n lastnameField: {\n id: 'cp.pages.register.lastnameField',\n defaultMessage: 'lastname',\n },\n emailField: {\n id: 'cp.pages.register.emailField',\n defaultMessage: 'E-Mail',\n },\n passwordField: {\n id: 'cp.pages.register.passwordField',\n defaultMessage: 'password',\n },\n acceptTermsOfUse: {\n id: 'cp.pages.register.acceptTermsOfUse',\n defaultMessage: 'Do you accept the terms of use?',\n },\n create: {\n id: 'cp.pages.register.create',\n defaultMessage: 'Create Account',\n },\n successSnackbar: {\n id: 'cp.pages.register.successSnackbar',\n defaultMessage: 'You registration was successful.',\n },\n errorSnackbar: {\n id: 'cp.pages.register.errorSnackbar',\n defaultMessage: 'An unintended error occured. Please try again.',\n },\n newToShortError: {\n id: 'cp.pages.register.newToShortError',\n defaultMessage: 'The provided passwort is to short.',\n },\n})\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { pageStateMachine } from 'machines/pageState.machine'\nimport { Institute } from 'model/Institute'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { Locale } from '../../model/Locale'\nimport { InstituteDocument } from 'model/db/InstituteDocument.db-schema'\n\nimport messages from '../../pages/Institutes/Institutes.messages'\nimport { USERROLES } from '../../model/UserRole'\n\nexport enum InstituteServiceMessageType {\n Clear = 'Service/Institutes/Clear',\n Create = 'Service/Institutes/Create',\n Update = 'Service/Institutes/Update',\n Delete = 'Service/Institutes/Delete',\n Edit = 'Service/Institutes/Edit',\n}\n\ninterface InstituteServiceClearMessage extends Message {\n type: InstituteServiceMessageType.Clear\n}\n\ninterface InstituteServiceEditMessage extends Message {\n type: InstituteServiceMessageType.Edit\n payload: string\n}\n\ninterface InstituteServiceCreateMessage extends Message {\n type: InstituteServiceMessageType.Create\n}\ninterface InstituteServiceUpdateMessage extends Message {\n type: InstituteServiceMessageType.Update\n}\ninterface InstituteServiceDeleteMessage extends Message {\n type: InstituteServiceMessageType.Delete\n payload: string\n}\n\nexport type InstituteServiceMessages =\n | InstituteServiceEditMessage\n | InstituteServiceCreateMessage\n | InstituteServiceUpdateMessage\n | InstituteServiceDeleteMessage\n | InstituteServiceClearMessage\n\nexport const connectInstituteService = (store: AppStore) => {\n const {\n http,\n onAction,\n goTo,\n hasUserRole,\n onLogout,\n onPageEnter,\n onPageLeave,\n snackBar,\n intl,\n } = tools(store)\n const { api } = config()\n\n const machine = pageStateMachine({\n id: 'connectInstituteService',\n fetchData,\n setLoading,\n }).start()\n\n hasUserRole(USERROLES.CorPatchAdmin).subscribe(() => machine.send('LOGIN'))\n\n onLogout().subscribe(() => machine.send('LOGOUT'))\n\n onPageEnter(AppRoutes.Institutes).subscribe(() => machine.send('PAGE_ENTER'))\n\n onPageLeave(AppRoutes.Institutes).subscribe(() => machine.send('PAGE_LEAVE'))\n\n function fetchData() {\n http({\n url: api + routes.corPatchAdmin.institutes,\n }).subscribe(institutes => {\n machine.send('RESOLVE')\n store.next(\n state => {\n state.services.institutes = institutes\n },\n { type: InstituteServiceMessageType.Update }\n )\n })\n }\n\n function setLoading() {\n store.next(\n s => {\n // s.services.institutes = []\n s.pages.institutes.meta.loading = true\n },\n { type: InstituteServiceMessageType.Clear }\n )\n }\n\n //\n // Create new institute\n //\n onAction({ type: InstituteServiceMessageType.Create }).subscribe(() => {\n const data: Institute = {\n name: 'New institute',\n\n address: {\n street: '',\n nr: '',\n co1: '',\n co2: '',\n city: '',\n state: '',\n zip: '',\n country: '',\n },\n\n settings: {\n locale: Locale.en,\n },\n }\n\n http({\n url: api + routes.corPatchAdmin.institutes,\n method: 'POST',\n data,\n }).subscribe(institute => {\n store.next(state => {\n state.services.institutes.push(institute)\n })\n goTo(AppRoutes.Institute, { id: (institute as any)._id })\n })\n })\n\n //\n // Edit institute\n //\n onAction({ type: InstituteServiceMessageType.Edit }).subscribe(update => {\n const id = (update.message as InstituteServiceEditMessage).payload\n goTo(AppRoutes.Institute, { id })\n })\n\n //\n // Delete institute and associated trainers, admins and trainees\n //\n onAction({ type: InstituteServiceMessageType.Delete }).subscribe(update => {\n const id = (update.message as InstituteServiceEditMessage).payload\n\n http({\n route: { path: routes.corPatchAdmin.institute, id },\n method: 'DELETE',\n }).subscribe(\n () => {\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n snackBar.success(successSnackbar)\n },\n () => {\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n snackBar.error(errorSnackbar)\n }\n )\n })\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageTitle: {\n id: 'cp.pages.sharingObject.pageTitle',\n defaultMessage: 'Sharing Objects',\n },\n pageNotFoundTitle: {\n id: 'cp.pages.sharingObject.pageNotFoundTitle',\n defaultMessage: 'Not found',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.sharingObject.pageNotFoundDescription',\n defaultMessage: 'The sharing objects you are looking for do not exists.',\n },\n title: {\n id: 'cp.pages.sharingObject.form.title',\n defaultMessage: 'Sharing object',\n },\n name: {\n id: 'cp.pages.sharingObject.form.name',\n defaultMessage: 'Name',\n },\n invitationCode: {\n id: 'cp.pages.sharingObject.form.invitationCode',\n defaultMessage: 'Invitation Code',\n },\n invitationLink: {\n id: 'cp.pages.sharingObject.form.invitationLink',\n defaultMessage: 'Invitation Link',\n },\n webHook: {\n id: 'cp.pages.sharingObject.form.webHook',\n defaultMessage: 'WebHook',\n },\n pullUrl: {\n id: 'cp.pages.sharingObject.form.pullUrl',\n defaultMessage: 'Pull URL',\n },\n pullApiSecret: {\n id: 'cp.pages.sharingObject.form.pullApiSecret',\n defaultMessage: 'Secret',\n },\n apiAccess: {\n id: 'cp.pages.sharingObject.form.apiAccess',\n defaultMessage: 'API Access',\n },\n enabled: {\n id: 'cp.pages.sharingObject.form.enabled',\n defaultMessage: 'Enabled',\n },\n disabled: {\n id: 'cp.pages.sharingObject.form.disabled',\n defaultMessage: 'Disabled',\n },\n saveButton: {\n id: 'cp.pages.sharingObject.form.saveButton',\n defaultMessage: 'Save',\n },\n deleteButton: {\n id: 'cp.pages.sharingObject.form.deleteButton',\n defaultMessage: 'Delete',\n },\n confirmDeleteDialogTitle: {\n id: 'cp.pages.sharingObject.form.confirmDeleteDialogTitle',\n defaultMessage: 'Remove Sharing Object',\n },\n confirmDeleteDialogYes: {\n id: 'cp.pages.sharingObject.form.confirmDeleteDialogYes',\n defaultMessage: 'Delete',\n },\n confirmDeleteDialogNo: {\n id: 'cp.pages.sharingObject.form.confirmDeleteDialogNo',\n defaultMessage: 'Cancel',\n },\n confirmDeleteDialogMessage1: {\n id: 'cp.pages.sharingObject.form.confirmDeleteDialogMessage1',\n defaultMessage: 'Are you sure you want to delete the sharing object?',\n },\n confirmDeleteDialogMessage2: {\n id: 'cp.pages.sharingObject.form.confirmDeleteDialogMessage2',\n defaultMessage:\n 'This action cannot be undone, but no data will be lost. The §sharing object will be visible as deactivated.',\n },\n snackBarSaved: {\n id: 'cp.pages.sharingObject.snackBarSaved',\n defaultMessage: 'Saved',\n },\n snackBarSaveError: {\n id: 'cp.pages.sharingObject.snackBarSaveError',\n defaultMessage: 'Could not save',\n },\n snackBarDeleted: {\n id: 'cp.pages.sharingObject.snackBarDeleted',\n defaultMessage: 'Deleted',\n },\n snackBarDeleteError: {\n id: 'cp.pages.sharingObject.snackBarDeleteError',\n defaultMessage: 'Could not delete',\n },\n})\n","import { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { combineLatest, interval } from 'rxjs'\nimport { distinctUntilChanged, filter, map, startWith } from 'rxjs/operators'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nconst start = Date.now()\n\nconst log = (args: any) => {\n const delta = Date.now() - start\n console.log(\n '%c 🛒 [ ' + delta + 'ms ] ' + args,\n 'background: bisque; color: #333; padding:5px; font-weight:bold'\n )\n}\n\nexport const connectShopPage = (store: AppStore) => {\n const { http, onChange } = tools(store)\n const { api } = config()\n const url = api + routes.shopSso\n\n //\n // Login / Logout\n //\n\n // We watch the global variable `Ecwid` and `Ecwid.setSsoProfile`\n // and check if the they become available\n const ecwidAvailable$ = interval(200).pipe(\n map(\n () =>\n window.Ecwid != null &&\n window.Ecwid.setSsoProfile != null &&\n window.xProductBrowser !== null\n ),\n startWith(false),\n distinctUntilChanged()\n )\n ecwidAvailable$.subscribe(available => log('ECWID available: ' + available))\n\n // Watch token changes\n const token$ = onChange(state => state.session.token)\n\n const ctx$ = combineLatest(token$, ecwidAvailable$).pipe(\n map(([token, ecwidAvailable]) => ({ token, ecwidAvailable }))\n )\n\n // Login Event - we have a token and Ecwid is available\n const login$ = ctx$.pipe(\n filter(ctx => ctx.token !== null && ctx.ecwidAvailable)\n )\n\n // Logout Event - we don't have a token and Ecwid is available\n const logout$ = ctx$.pipe(\n filter(ctx => ctx.token === null && ctx.ecwidAvailable)\n )\n\n login$.subscribe(() => log('Login Event'))\n logout$.subscribe(() => log('Logout Event'))\n\n login$.subscribe(() => {\n http({ url }).subscribe(shopData => {\n const { ecwidSsoProfile } = shopData\n window.Ecwid.setSsoProfile(ecwidSsoProfile)\n log('Set SSO profile: \"' + ecwidSsoProfile + '\"')\n })\n })\n\n logout$.subscribe(() => {\n window.Ecwid.setSsoProfile('')\n })\n\n //\n // History\n //\n // TODO restore shop navigation\n // onChange(state => state.location).pipe(map(location => {\n // if (location.pathname === '/shop') {\n // return location.hash\n // }\n // })\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageTitle: {\n id: 'cp.pages.traineeShares.pageTitle',\n defaultMessage: 'Trainee Shares',\n },\n pageTitleNotFound: {\n id: 'cp.pages.traineeShares.pageTitleNotFound',\n defaultMessage: 'Not found',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.traineeShares.pageNotFoundMessage',\n defaultMessage: 'The trainee shares you are looking for do not exists.',\n },\n active: {\n id: 'cp.pages.traineeShares.active',\n defaultMessage: 'Active',\n },\n inactive: {\n id: 'cp.pages.traineeShares.inactive',\n defaultMessage: 'Inactive',\n },\n addShare: {\n id: 'cp.pages.traineeShares.addShare',\n defaultMessage: 'Add Share',\n },\n noActiveItemsMessage: {\n id: 'cp.pages.traineeShares.noActiveItemsMessage',\n defaultMessage:\n 'Currently, you have not agreed to any data sharing agreements. Press the plus button at the bottom right to enter a corresponding invitation code.',\n },\n noInactiveItemsMessage: {\n id: 'cp.pages.traineeShares.noInactiveItemsMessage',\n defaultMessage: 'No in-active sharing agreements.',\n },\n startDate: {\n id: 'cp.pages.traineeShares.startDate',\n defaultMessage: 'Start date: ',\n },\n endDate: {\n id: 'cp.pages.traineeShares.endDate',\n defaultMessage: 'End date: ',\n },\n deactivateTooltip: {\n id: 'cp.pages.traineeShares.deactivateTooltip',\n defaultMessage: 'Deactivate',\n },\n\n addDialogTitle: {\n id: 'cp.pages.traineeShares.addDialogTitle',\n defaultMessage: 'Invitation',\n },\n addDialogDescription: {\n id: 'cp.pages.traineeShares.addDialogDescription',\n defaultMessage:\n 'Enter the invitation code you got from your partner organization:',\n },\n addDialogDescription2: {\n id: 'cp.pages.traineeShares.addDialogDescription2',\n defaultMessage:\n 'If you choose to click \"Add,\" you are acknowledging that you agree to the terms and conditions provided to you by the partner organization along with this invitation link/code. It is essential to read and understand the terms and conditions before proceeding.',\n },\n addDialogCancel: {\n id: 'cp.pages.traineeShares.addDialogCancel',\n defaultMessage: 'Cancel',\n },\n addDialogAdd: {\n id: 'cp.pages.traineeShares.addDialogAdd',\n defaultMessage: 'Add',\n },\n deactivateDialogTitle: {\n id: 'cp.pages.traineeShares.deactivateDialogTitle',\n defaultMessage: 'Deactivate',\n },\n deactivateDialogDescription: {\n id: 'cp.pages.traineeShares.deactivateDialogDescription',\n defaultMessage:\n 'Are you sure you want to deactivate this sharing agreement with {instituteName}?',\n },\n deactivateDialogNo: {\n id: 'cp.pages.traineeShares.deactivateDialogNo',\n defaultMessage: 'Cancel',\n },\n deactivateDialogYes: {\n id: 'cp.pages.traineeShares.deactivateDialogYes',\n defaultMessage: 'Deactivate',\n },\n snackBarInvalidCode: {\n id: 'cp.pages.traineeShares.snackBarInvalidCode',\n defaultMessage: 'Please enter a valid invitation code.',\n },\n snackBarInvitationAdded: {\n id: 'cp.pages.traineeShares.snackBarInvitationAdded',\n defaultMessage: 'Invitation added',\n },\n snackBarErrorAddingInvitation: {\n id: 'cp.pages.traineeShares.snackBarErrorAddingInvitation',\n defaultMessage: 'Error adding invitation: {errorMessage}!',\n },\n snackBarSharingDeactivated: {\n id: 'cp.pages.traineeShares.snackBarSharingDeactivated',\n defaultMessage: 'Sharing deactivated',\n },\n snackBarErrorDeactivatingSharing: {\n id: 'cp.pages.traineeShares.snackBarErrorDeactivatingSharing',\n defaultMessage: 'Error deactivating sharing: {errorMessage}!',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n trainerInviteTitle: {\n id: 'cp.pages.trainerInvite.title',\n defaultMessage: 'Invite trainer',\n },\n trainerSuccessSnackbar: {\n id: 'cp.pages.trainerInvite.successSnackbar',\n defaultMessage: 'Email send to {email}',\n },\n trainerErrorSnackbar: {\n id: 'cp.pages.trainerInvite.errorSnackbar',\n defaultMessage: 'Email is in use',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n trainersNotFoundTitle: {\n id: 'cp.pages.trainersNotFound.title',\n defaultMessage: 'Trainer not found',\n },\n trainersNotFoundMessage: {\n id: 'cp.pages.trainersNotFound.message',\n defaultMessage: 'This trainer has been deleted. Sorry :(',\n },\n trainersNotAvailableTitle: {\n id: 'cp.pages.trainersNotAvailable.title',\n defaultMessage: 'No trainers yet!',\n },\n trainersNotAvailableMessage: {\n id: 'cp.pages.trainersNotAvailable.message',\n defaultMessage: 'Do you want to invite the first trainer?',\n },\n trainersNotAvailableButton: {\n id: 'cp.pages.trainersNotAvailable.button',\n defaultMessage: 'Invite Trainer',\n },\n trainersTitle: {\n id: 'cp.pages.trainersTable.trainers',\n defaultMessage: 'Trainers',\n },\n selected: {\n id: 'cp.pages.trainersTable.selected',\n defaultMessage: 'selected',\n },\n tableRowName: {\n id: 'cp.pages.trainersTable.tableRowName',\n defaultMessage: 'Name',\n },\n tableRowEmail: {\n id: 'cp.pages.trainersTable.tableRowEmail',\n defaultMessage: 'E-Mail',\n },\n inviteTrainer: {\n id: 'cp.pages.trainersTable.inviteTrainer',\n defaultMessage: 'Invite Trainer',\n },\n deleteLabel: {\n id: 'cp.pages.trainersTable.deleteLabel',\n defaultMessage: 'delete',\n },\n successSnackbar: {\n id: 'cp.pages.trainers.successSnackbar',\n defaultMessage: 'Deleted.',\n },\n errorSnackbar: {\n id: 'cp.pages.trainers.errorSnackbar',\n defaultMessage: 'Oh no. Could not delete user :/',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageNotFoundTitle: {\n id: 'cp.pages.userChangeEmail.notFound.title',\n defaultMessage: 'Not found.',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.userChangeEmail.notFound.message',\n defaultMessage: 'Sorry, this user does not exist anymore Sorry :(',\n },\n changeEmail: {\n id: 'cp.pages.userChangeEmail.changeEmail',\n defaultMessage: 'Change E-Mail',\n },\n newEmail: {\n id: 'cp.pages.userChangeEmail.newEmail',\n defaultMessage: 'New E-Mail',\n },\n cancelButton: {\n id: 'cp.pages.userChangeEmail.cancelButton',\n defaultMessage: 'Cancel',\n },\n sendEmail: {\n id: 'cp.pages.userChangeEmail.sendEmail',\n defaultMessage: 'E-Mail send',\n },\n emailChangedSnackbar: {\n id: 'cp.pages.userChangeEmail.emailChangedSnackbar',\n defaultMessage: 'E-Mail changed',\n },\n emailErrorSnackbar: {\n id: 'cp.pages.userChangeEmail.emailErrorSnackbar',\n defaultMessage: 'Could not change E-Mail',\n },\n verifyEmailTitle: {\n id: 'cp.pages.userChangeEmail.verifyEmail.title',\n defaultMessage: 'Please verify your E-Mail',\n },\n verifyEmailContent: {\n id: 'cp.pages.userChangeEmail.verifyEmail.content',\n defaultMessage:\n 'If you want we can keep you informed about the latest and greates changes to our app and products. This is an opt-in but still we would like to offer you the full capabilities of our app. Therefore we need to verify your E-Mail address.',\n },\n verifyEmailButton: {\n id: 'cp.pages.userChangeEmail.verifyEmail.button',\n defaultMessage: 'Send me a new verification E-Mail to my address',\n },\n ok: {\n id: 'cp.pages.userChangeEmail.ok',\n defaultMessage: 'OK',\n },\n email: {\n id: 'cp.pages.userChangeEmail.email',\n defaultMessage: 'E-Mail',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n loadingTitle: {\n id: 'cp.pages.userChangePassword.title',\n defaultMessage: 'Change password',\n },\n pageNotFoundTitle: {\n id: 'cp.pages.userChangePassword.notFound.title',\n defaultMessage: 'Nutzer nicht gefunden.',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.userChangePassword.notFound.message',\n defaultMessage: 'Dieser Nutzer wurde gelöscht. Sorry :(',\n },\n wrongPasswordSnackbar: {\n id: 'cp.pages.userChangePassword.wrongPasswordSnackbar',\n defaultMessage: 'Current password is wrong',\n },\n notChangedPasswordSnackbar: {\n id: 'cp.pages.userChangePassword.notChangedPasswordSnackbar',\n defaultMessage: 'Could not change password:',\n },\n successSnackbar: {\n id: 'cp.pages.userChangePassword.successSnackbar',\n defaultMessage: 'Password changed',\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageNotFoundTitle: {\n id: 'cp.pages.userDetails.notFound.title',\n defaultMessage: 'Nicht gefunden.',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.userDetails.notFound.message',\n defaultMessage: 'Wurde gelöscht. Sorry :(',\n },\n invitation: {\n id: 'cp.pages.userDetails.invitation',\n defaultMessage: 'Invitation',\n },\n sendInvitation: {\n id: 'cp.pages.userDetails.sendInvitation',\n defaultMessage: 'Send Invitation',\n },\n signUpAccepted: {\n id: 'cp.pages.userDetails.signUpAccepted',\n defaultMessage: 'Accepted',\n },\n signUpPending: {\n id: 'cp.pages.userDetails.signUpPending',\n defaultMessage: 'Pending',\n },\n userDetailsEmail: {\n id: 'cp.pages.userDetails.userDetailsEmail',\n defaultMessage: 'E-Mail',\n },\n successSnackbar: {\n id: 'cp.pages.userDetails.successSnackbar',\n defaultMessage: 'Invitation send',\n },\n errorSnackbar: {\n id: 'cp.pages.userDetails.errorSnackbar',\n defaultMessage: 'Oh no. Could not send invite',\n },\n})\n","import { Machine, assign, interpret } from 'xstate'\n\ninterface PageStateMachineProps {\n id: string\n fetchData: () => any\n setLoading: () => any\n}\n\nexport type PageStateMachineEvents =\n | { type: 'LOGIN' }\n | { type: 'PAGE_ENTER' }\n | { type: 'LOGOUT' }\n | { type: 'PAGE_LEAVE' }\n | { type: 'RESOLVE' }\n | { type: 'REJECT' }\n\ninterface Context {\n id: string\n}\n\ninterface Schema {\n states: {\n init: {}\n waitingForPageEnter: {}\n waitingForLogin: {}\n fetching: {}\n success: {}\n error: {}\n }\n}\n\n/**\n *\n * Do not use anymore. This approach is outdated. Use the `onLoginPageEnter` tool instead\n * @deprecated\n */\nexport const pageStateMachine = ({\n id,\n fetchData,\n setLoading,\n}: PageStateMachineProps) => {\n const m = Machine(\n {\n id,\n initial: 'init',\n context: {\n id: '',\n },\n states: {\n init: {\n entry: ['setLoading'],\n on: {\n LOGIN: 'waitingForPageEnter',\n PAGE_ENTER: 'waitingForLogin',\n },\n },\n waitingForPageEnter: {\n entry: ['setLoading'],\n on: {\n LOGOUT: 'init',\n PAGE_ENTER: {\n target: 'fetching',\n actions: assign({ id: (ctx: any) => ctx.id }),\n },\n },\n },\n waitingForLogin: {\n entry: ['setLoading'],\n on: {\n PAGE_LEAVE: 'init',\n LOGIN: {\n target: 'fetching',\n actions: assign({ id: (ctx: any) => ctx.id }),\n },\n },\n },\n fetching: {\n entry: ['fetchData'],\n on: {\n LOGOUT: 'waitingForLogin',\n PAGE_LEAVE: 'waitingForPageEnter',\n PAGE_ENTER: 'fetching',\n RESOLVE: 'success',\n REJECT: 'error',\n },\n },\n success: {\n on: {\n PAGE_ENTER: 'fetching',\n PAGE_LEAVE: 'waitingForPageEnter',\n LOGOUT: 'waitingForLogin',\n },\n },\n error: {\n on: {\n PAGE_ENTER: 'fetching',\n PAGE_LEAVE: 'waitingForPageEnter',\n LOGOUT: 'waitingForLogin',\n },\n },\n },\n },\n {\n actions: {\n fetchData,\n setLoading,\n },\n }\n )\n return interpret(m).start()\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageNotFoundTitle: {\n id: 'cp.pages.institutes.pageNotFound.title',\n defaultMessage: 'No institute found',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.institutes.pageNotFound.message',\n defaultMessage: 'Do you want to add the first institute?',\n },\n addInstituteButton: {\n id: 'cp.pages.institutes.addInstituteButton',\n defaultMessage: 'Add Institute',\n },\n pageTitle: {\n id: 'cp.pages.institutes.pageTitle',\n defaultMessage: 'Institutes',\n },\n deleteLabel: {\n id: 'cp.pages.institutes.deleteLabel',\n defaultMessage: 'delete',\n },\n successSnackbar: {\n id: 'cp.pages.institutes.successSnackbar',\n defaultMessage: 'Institute was successfully deleted',\n },\n errorSnackbar: {\n id: 'cp.pages.institutes.errorSnackbar',\n defaultMessage: 'Institute could not be deleted',\n },\n})\n","import { Patch } from 'immer'\nimport { RxStore, StatePackage } from '@restate/core'\n// import sourceMapSupport from 'source-map-support'\n\ninterface LoggerProps {\n color?: string\n backgroundColor?: string\n}\n\nexport function connectLogger(\n appStore: RxStore,\n props: LoggerProps = { color: 'white', backgroundColor: 'DarkOrange' }\n) {\n const { color, backgroundColor } = props\n\n // sourceMapSupport.install()\n\n const name =\n appStore.options.storeName === '' ? 'RxState' : appStore.options.storeName\n\n appStore.state$.subscribe(update => {\n console.groupCollapsed(\n formatGroupName(name, update),\n `color: ${color}; background:${backgroundColor};`\n )\n formatPatches(update.patches || [])\n console.log('ID', (update as any).id)\n console.log('State: ', update.state)\n if (!/password/.test(JSON.stringify(update.message))) {\n console.log('Message: ', update.message)\n }\n formatStack(update)\n console.groupEnd()\n })\n}\n\nfunction formatStack(update: StatePackage) {\n const stack: string | undefined = (update as any).stack\n if (!stack) return\n\n const URL_REG = /http:.*:\\d/\n\n const lines = stack\n .split('\\n')\n .map(line => line.trim())\n .filter(line => !/^Error/.test(line))\n .filter(line => !/internal\\/operators/.test(line))\n .filter(line => !/internal\\/Scheduler.ts/.test(line))\n .filter(line => !/internal\\/scheduler/.test(line))\n .filter(line => !/internal\\/Subject.ts/.test(line))\n .filter(line => !/internal\\/BehaviorSubject.ts/.test(line))\n .filter(line => !/internal\\/Observable.ts/.test(line))\n .filter(line => !/node_modules/.test(line))\n .filter(line => !/Notification.observe/.test(line))\n .filter(line => !/rx-store.ts/.test(line))\n .filter(line => !/RxStore/.test(line))\n .filter(line => !/Subscriber.ts/.test(line))\n .filter(line => !/webpack\\/bootstrap/.test(line))\n .filter(line => !/chunk.js/.test(line))\n .filter(line => URL_REG.test(line))\n .map(line => {\n const match = URL_REG.exec(line)\n return match ? match[0] : ''\n })\n\n console.log('Source :', lines)\n}\n\nfunction formatGroupName(name: string, update: StatePackage) {\n const MAX_LEN = 60\n\n let payload =\n update.message.payload != null ? JSON.stringify(update.message.payload) : ''\n\n if (/password/.test(payload)) {\n return `%c [${name}] : UNDEFINED`\n }\n\n if (payload.length > MAX_LEN) {\n payload = payload.substring(0, MAX_LEN - 3) + '...'\n }\n\n return `%c [${name}] : ${update.message.type} ${payload}`\n}\n\nfunction formatPatches(patches: Patch[]) {\n patches.forEach(patch => {\n const path = patch.path.join('.')\n switch (patch.op) {\n case 'add': {\n console.groupCollapsed(\n '%c Add \"' + path + '\":',\n 'color: green',\n patch.value\n )\n console.log(JSON.stringify(patch.value, null, 2))\n console.groupEnd()\n break\n }\n case 'remove': {\n console.groupCollapsed(\n '%c Remove \"' + path + '\":',\n 'color: red',\n patch.value\n )\n console.log(JSON.stringify(patch.value, null, 2))\n console.groupEnd()\n break\n }\n case 'replace': {\n console.groupCollapsed(\n '%c Replace \"' + path + '\":',\n 'color: #008800',\n patch.value\n )\n console.log(JSON.stringify(patch.value, null, 2))\n console.groupEnd()\n break\n }\n\n default: {\n console.groupCollapsed(\n '%c Default \"' + path + '\":',\n 'color: green',\n patch.value\n )\n console.log(JSON.stringify(patch.value, null, 2))\n console.groupEnd()\n }\n }\n })\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n validationTitle: {\n id: 'cp.pages.login.validate.validationTitle',\n defaultMessage: 'Please verify your login',\n },\n validationContent: {\n id: 'cp.pages.login.validate.validationContent',\n defaultMessage: 'We have sent you an E-Mail to verify your login.',\n },\n validationButton: {\n id: 'cp.pages.login.validate.validationButton',\n defaultMessage: 'Go back to login',\n },\n\n successTitle: {\n id: 'cp.pages.login.validate.successTitle',\n defaultMessage: 'We are logging you in.',\n },\n successContent: {\n id: 'cp.pages.login.validate.successContent',\n defaultMessage: 'Please wait a moment while we validate your login.',\n },\n\n errorTitle: {\n id: 'cp.pages.login.validate.errorTitle',\n defaultMessage: 'We could not recognize your browser session',\n },\n errorContent: {\n id: 'cp.pages.login.validate.errorContent',\n defaultMessage:\n 'Maybe you have tried to login from another browser or device or you have closed your browser in the meantime. Try to request another E-Mail to login.',\n },\n\n errorSnackbar: {\n id: 'cp.pages.login.validate.errorSnackbar',\n defaultMessage:\n 'There was an error with loging you in. Your link might be outdated.',\n },\n})\n","import { Message } from '@restate/core'\nimport axios from 'axios'\nimport { config } from 'config/config'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { routes } from 'model/ctrl/routes'\nimport { CorpatchAdminUserDTO, UserDTO } from '../../model/User.dto'\nimport { TwoFactorAuthenticationResponse } from '../../model/ctrl/login/LoginRes.schema'\nimport { AppRoutes } from '../../routes'\n\nimport validationMessages from '../../pages/ValidateLogin/ValidateLogin.messages'\n\nexport const LS_VERIFICATION_KEY = 'corpatch-email-verification'\n\nexport enum LoginService {\n Login = 'Service/Login/Request',\n LoginSuccess = 'Service/Login/Success',\n LoginValidate = 'Service/Login/Validate',\n}\n\nexport interface LoginMessage extends Message {\n type: LoginService.Login\n payload: {\n email: string\n password: string\n }\n}\n\nconst is2FAValidationReponse = (\n res: UserDTO | TwoFactorAuthenticationResponse\n): res is TwoFactorAuthenticationResponse =>\n Boolean((res as TwoFactorAuthenticationResponse).verificationToken)\n\nexport interface LoginValidateMessage extends Message {\n type: LoginService.LoginValidate\n payload: {\n validationToken: string\n verificationToken: string\n }\n}\n\nexport type LoginServiceMessages =\n | LoginMessage\n | { type: LoginService.LoginSuccess }\n | LoginValidateMessage\n\nexport const connectLogin = (store: AppStore) => {\n const { onAction, snackBar, http, goTo, intl } = tools(store)\n\n onAction({ type: LoginService.Login }).subscribe(event => {\n const { api } = config()\n const { email, password } = (event.message as LoginMessage).payload\n\n store.next(s => {\n s.pages.login.showProgress = true\n s.pages.login.error = ''\n })\n\n axios\n .post(api + routes.auth.login, {\n email,\n password,\n })\n .then(function (response) {\n const data: UserDTO | TwoFactorAuthenticationResponse =\n response.data.data\n\n if (is2FAValidationReponse(data)) {\n localStorage.setItem(LS_VERIFICATION_KEY, data.verificationToken)\n return goTo(AppRoutes.ValidateLoginPublic)\n }\n\n store.next(s => {\n s.session.user = data\n s.pages.login.showProgress = false\n s.session.token = data.token\n })\n store.dispatch({ type: LoginService.LoginSuccess })\n })\n .catch(function () {\n store.next(s => {\n s.pages.login.showProgress = false\n s.pages.login.error = 'Error'\n })\n })\n })\n\n onAction({ type: LoginService.LoginValidate }).subscribe(event => {\n const {\n validationToken,\n verificationToken,\n } = (event.message as LoginValidateMessage).payload\n\n http({\n route: {\n path: routes.auth.validateLogin,\n },\n method: 'POST',\n data: {\n validationToken,\n verificationToken,\n },\n }).subscribe(\n response => {\n store.next(s => {\n s.session.user = response\n s.session.token = response.token\n })\n\n localStorage.removeItem(LS_VERIFICATION_KEY)\n\n goTo(AppRoutes.Home)\n },\n () => {\n const errorSnackbar = intl().formatMessage(\n validationMessages.errorSnackbar\n )\n snackBar.error(errorSnackbar)\n }\n )\n })\n}\n","import { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nenum NetworkServiceMessageType {\n Offline = 'Service/Network/Offline',\n Online = 'Service/Network/Online',\n}\n\nexport interface NetworkServiceMessages {\n type: NetworkServiceMessageType\n}\n\nexport const connectNetwork = (store: AppStore) => {\n const { onAction } = tools(store)\n\n window.addEventListener('offline', () => {\n store.next(\n state => {\n state.network.online = false\n },\n { type: NetworkServiceMessageType.Offline }\n )\n })\n\n window.addEventListener('online', () => {\n store.next(\n state => {\n state.network.online = true\n },\n { type: NetworkServiceMessageType.Online }\n )\n })\n\n function init() {\n const online = navigator.onLine\n store.next(\n state => {\n state.network.online = online\n },\n {\n type: online\n ? NetworkServiceMessageType.Online\n : NetworkServiceMessageType.Offline,\n }\n )\n }\n\n onAction({ type: 'App/Init' }).subscribe(init)\n}\n","import { Message } from '@restate/core'\nimport { distinctUntilChanged, map, skip } from 'rxjs/operators'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nexport enum SessionServiceMessageType {\n Done = 'Service/Session/Done',\n Restored = 'Service/Session/Restored',\n}\n\nexport interface ServiceSessionMessages extends Message {\n type: SessionServiceMessageType\n}\n\nexport const connectSession = (store: AppStore) => {\n const { onAction } = tools(store)\n\n // Load session data\n onAction({ type: 'App/Init' }).subscribe(() => {\n try {\n const session = JSON.parse(localStorage.getItem('corpatch') || 'null')\n if (session) {\n store.next(\n s => {\n s.session = session\n },\n { type: SessionServiceMessageType.Restored }\n )\n }\n } catch (e) {\n console.error('Error parsing session infos')\n } finally {\n store.dispatch({ type: SessionServiceMessageType.Done })\n }\n })\n\n // Save session on changes in the state\n store.state$\n .pipe(\n map(update => update.state.session),\n distinctUntilChanged(),\n skip(1)\n )\n .subscribe(() => {\n const { session } = store.state\n localStorage.setItem('corpatch', JSON.stringify(session))\n })\n}\n","import { RxStore } from '@restate/core'\nimport { combineLatest, animationFrameScheduler } from 'rxjs'\nimport { tools } from 'services/utils/tools'\nimport { State } from 'state/state'\nimport { AppMessages } from 'state/appMessages'\nimport { SessionServiceMessageType } from 'services/session/session.service'\nimport RouteParser from 'route-parser'\nimport { AppRoutes } from 'routes'\nimport { observeOn } from 'rxjs/operators'\n\nconst PUBLIC_PAGES = [\n AppRoutes.AcceptInvitation,\n AppRoutes.InternalServerError,\n AppRoutes.Login,\n AppRoutes.LoginPasswordForgot,\n AppRoutes.LoginPasswordForgotSetPassword,\n AppRoutes.Logout,\n AppRoutes.LoginTermsOfUse,\n AppRoutes.Register,\n AppRoutes.EmailValidation,\n AppRoutes.ValidateLogin,\n AppRoutes.ValidateLoginPublic,\n]\n\nfunction isPublicPage(location: string) {\n return PUBLIC_PAGES.some(page => {\n const match = new RouteParser(page).match(location)\n return match !== false\n })\n}\n\nexport const connectRouteGuard = (store: RxStore) => {\n const { goTo, onChange, onAction } = tools(store)\n\n // Token changes\n const token$ = onChange(s => s.session.token)\n\n // Location changes\n const location$ = onChange(s => s.location.pathname)\n\n // Session restored\n const session$ = onAction({ type: SessionServiceMessageType.Done })\n\n // We watch for token changes\n combineLatest(token$, location$, session$)\n .pipe(observeOn(animationFrameScheduler))\n .subscribe(props => {\n const [token, location] = props\n\n if (token !== null && location === '/login') {\n goTo('/')\n }\n\n // Do nothing on public pages\n if (isPublicPage(location)) {\n return\n }\n\n if (token === null) {\n goTo('/login?redirect=' + location)\n }\n })\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n successSnackbar: {\n id: 'cp.components.changeUserRole.successSnackbar',\n defaultMessage: 'Changed role to {role}',\n },\n errorSnackbar: {\n id: 'cp.components.changeUserRole.errorSnackbar',\n defaultMessage:\n 'An unknown error occured. Please try again or contact the support if the error persists.',\n },\n selectLabel: {\n id: 'cp.components.changeUserRole.selectLabel',\n defaultMessage: 'choose role',\n },\n})\n","import React from 'react'\nimport { IntlProvider } from 'react-intl'\nimport { distinctUntilChanged, map } from 'rxjs/operators'\nimport { AppStore, useAppState } from 'state/store'\nimport { FrontendLocale } from './I18N.state'\n\nconst translations: any = {\n de: require(`./translations/de`),\n en: require(`./translations/en`),\n da: require(`./translations/da`),\n fi: require(`./translations/fi`),\n it: require(`./translations/it`),\n fr: require(`./translations/fr`),\n es: require(`./translations/es`),\n ar: require(`./translations/ar`),\n}\n\nexport const AppIntlProvider: React.FC<{}> = props => {\n const locale = useAppState(state => state.i18n.locale)\n const language = locale.split(/[-_]/)[0] // language without region code\n const messages: any = translations[language] || translations['de']\n return (\n \n {props.children}\n \n )\n}\n\nconst LangReg = /lang=(\\w*)&?/\n\nexport function connectTranslationSwitch(store: AppStore) {\n store.state$\n .pipe(\n map(update => update.state.location.search),\n distinctUntilChanged()\n )\n .subscribe(search => {\n const matches = LangReg.exec(search)\n if (matches) {\n const language = matches[1] as FrontendLocale\n if (language) {\n store.next(s => {\n s.i18n.locale = language\n })\n }\n }\n })\n}\n","import { AppStore } from '../../state/store'\nimport { tools } from '../../services/utils/tools'\nimport { config } from '../../config/config'\nimport RouteParser from 'route-parser'\nimport { routes } from '../../model/ctrl/routes'\nimport { AppRoutes } from '../../routes'\nimport { defaultDashboardState } from './Dashboard.state'\nimport { Message } from '@restate/core'\nimport { USERROLES } from '../../model/UserRole'\n\nexport interface PagesDashboardServiceMessages extends Message {\n type:\n | 'Pages/Dashboard/Service/Loading'\n | 'Pages/Dashboard/Service/Update'\n | 'Pages/Dashboard/Service/Error'\n | 'Pages/Dashboard/Service/Save'\n}\n\nexport const connectDashboardPage = (store: AppStore) => {\n const { onLoginPageEnter, http } = tools(store)\n const { api } = config()\n\n onLoginPageEnter(AppRoutes.Home, {\n roles: [USERROLES.CorPatchAdmin],\n }).subscribe(() => {\n fetchData()\n })\n\n function setLoading() {\n store.next(state => {\n state.pages.dashboard = defaultDashboardState\n state.pages.dashboard.meta.notFound = false\n state.pages.dashboard.meta.loading = true\n })\n }\n\n function fetchData() {\n setLoading()\n const path = new RouteParser(routes.dashboard).reverse({})\n\n http({ url: api + path }).subscribe(\n dashboard => {\n store.next(\n state => {\n state.pages.dashboard.data = dashboard\n state.pages.dashboard.meta.loading = false\n },\n { type: 'Pages/Dashboard/Service/Update' }\n )\n },\n\n _error => {\n console.error(_error)\n store.next(\n state => {\n state.pages.dashboard = defaultDashboardState\n state.pages.dashboard.meta.notFound = true\n state.pages.dashboard.meta.loading = false\n },\n { type: 'Pages/Dashboard/Service/Error' }\n )\n }\n )\n }\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n title: {\n id: 'cp.pages.trainee.title',\n defaultMessage: 'Trainees',\n },\n tableName: {\n id: 'cp.pages.trainee.table.name',\n defaultMessage: 'Full Name',\n },\n tableEmail: {\n id: 'cp.pages.trainee.table.email',\n defaultMessage: 'E-Mail',\n },\n tableCreated: {\n id: 'cp.pages.trainee.table.created',\n defaultMessage: 'Created',\n },\n tableSelected: {\n id: 'cp.pages.trainee.table.selected',\n defaultMessage: 'selected',\n },\n mobileButton: {\n id: 'cp.pages.trainee.mobileButton',\n defaultMessage: 'Download Mobile Data',\n },\n cpsButton: {\n id: 'cp.pages.trainee.cpsButton',\n defaultMessage: 'Download CPS Data',\n },\n singleTrainee: {\n id: 'cp.pages.trainee.singleTrainee',\n defaultMessage: 'trainee',\n },\n multipleTrainees: {\n id: 'cp.pages.trainee.multipleTrainees',\n defaultMessage: 'trainees',\n },\n deleteLabel: {\n id: 'cp.pages.trainee.deleteLabel',\n defaultMessage: 'delete',\n },\n\n successSnackbar: {\n id: 'cp.pages.trainee.delete.successSnackbar',\n defaultMessage: 'Trainees deleted successfully',\n },\n errorSnackbar: {\n id: 'cp.pages.trainee.delete.errorSnackbar',\n defaultMessage: 'An unknown error occured',\n },\n warningSnackbar: {\n id: 'cp.pages.trainee.delete.warningSnackbar',\n defaultMessage: 'One or more users were not deleted',\n },\n})\n","import {\n createDispatchHook,\n createNextHook,\n createProvider,\n createStateHook,\n createStore,\n createStoreHook,\n RxStore,\n} from '@restate/core'\nimport { connectDevTools } from '@restate/dev-tools'\nimport { connectReactRouter } from '@restate/router'\nimport { connectAppDrawer } from 'components/AppDrawer/AppDrawer.service'\nimport { createBrowserHistory } from 'history'\nimport { connectLanguageQueryParam } from 'I18N/connectLanguageQueryParam'\nimport { connectAcceptInvitationPageService } from 'pages/AcceptInvitation.tsx/AcceptInvitation.page-service'\nimport { connectAdminInvitePageService } from 'pages/AdminInvite/AdminInvite.page-service'\nimport { connectCoursePageService } from 'pages/Course/Course.page-service'\nimport { connectCoursesPageService } from 'pages/Courses/Courses.page-service'\nimport { connectExportPageService } from 'pages/Export/Export.page-service'\nimport { connectGlobalSettingsPage } from 'pages/GlobalSettings/GlobalSettings.page-service'\nimport { connectInstitutePage } from 'pages/Institute/Institute.page-service'\nimport { connectInstituteAdminSharesPage } from 'pages/InstituteAdminShares/InstituteAdminShares.page-service'\nimport { connectInstitutesPage } from 'pages/Institutes/Institutes.page-service'\nimport { connectLoginPasswordForgot } from 'pages/LoginPasswordForgot/LoginPasswordForgot.service'\nimport { connectLoginPasswordForgotSetPasswordService } from 'pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword.service'\nimport { connectMePage } from 'pages/Me/Me.service'\nimport { connectRegister } from 'pages/Register/Register.page-service'\nimport { connectSettingsPage } from 'pages/Settings/Settings.page-service'\nimport { connectSharingObjectPage } from 'pages/SharingObject/SharingObject.page-service'\nimport { connectShopPage } from 'pages/Shop/Shop.page-service'\nimport { connectSingleTrainingsPage } from 'pages/SingleTrainings/SingleTrainings.page-service'\nimport { connectTraineesSharePage } from 'pages/TraineeShares/TraineesShares.page-service'\nimport { connectTrainerInvitePageService } from 'pages/TrainerInvite/TrainerInvite.page-service'\nimport { connectTrainersPage } from 'pages/Trainers/Trainers.page-service'\nimport { connectTrainingsPageService } from 'pages/Trainings/Trainings.page-service'\nimport { connectUserChangeEmailPageService } from 'pages/UserChangeEmail/UserChangeEmail.service'\nimport { connectChangePasswordPageService } from 'pages/UserChangePassword/UserChagnePassword.service'\nimport { connectUserPageService } from 'pages/UserDetails/UserDetails.page-service'\nimport { connectAxios } from 'services/axios/axios.service'\nimport { connectEcwidLocaleService } from 'services/ecwidLocale/ecwidLocale.service'\nimport { connectInstituteService } from 'services/institutes/institutes.service'\nimport { connectLogger } from 'services/logger/logger.service'\nimport { connectLogin } from 'services/login/login.service'\nimport { connectLogout } from 'services/logout/logout.service'\nimport { connectNetwork } from 'services/network/network.service'\nimport { connectRouteGuard } from 'services/routeGuard/routeGuard.service'\nimport { connectRouter } from 'services/router/router.service'\nimport { connectSession } from 'services/session/session.service'\nimport { connectChangeUserRoleComponentService } from '../components/ChangeUserRole/ChangeUserRole.component-service'\nimport { connectReminderPageService } from '../components/Reminder/Reminder.page-service'\nimport { connectTranslationMenuPage } from '../components/TranslationMenu/TranslationMenu.page-service'\nimport { connectTranslationSwitch } from '../I18N/AppIntlProvider'\nimport { connectDashboardPage } from '../pages/Dashboard/Dashboard.page-service'\nimport { connectTraineesPage } from '../pages/Trainees/Trainees.page-service'\nimport { AppMessages } from './appMessages'\nimport { connectUserChangePassword } from './connector/userChangeEmail.connector'\nimport { connectUserMenu } from './connector/userMenu.connector'\nimport { defaultState, State } from './state'\n\nexport type AppStore = RxStore\n\nexport const store = createStore({\n state: defaultState,\n options: {\n storeName: 'CP',\n },\n})\n\nexport const history = createBrowserHistory()\n\nconnectLogger(store, { color: '#333', backgroundColor: '#bbfdc8' })\nconnectAxios(store)\nconnectNetwork(store)\nconnectSession(store)\nconnectDevTools(store)\nconnectReactRouter({ appStore: store, history })\nconnectRouter({ store, history })\nconnectLanguageQueryParam(store)\nconnectLogin(store)\nconnectLogout(store)\nconnectRegister(store)\nconnectInstituteService(store)\nconnectAppDrawer(store)\nconnectRouteGuard(store)\nconnectTranslationSwitch(store)\nconnectEcwidLocaleService(store)\n\n// Pages\nconnectAcceptInvitationPageService(store)\nconnectAdminInvitePageService(store)\nconnectChangePasswordPageService(store)\nconnectCoursePageService(store)\nconnectCoursesPageService(store)\nconnectDashboardPage(store)\nconnectExportPageService(store)\nconnectGlobalSettingsPage(store)\nconnectInstituteAdminSharesPage(store)\nconnectInstitutePage(store)\nconnectInstitutesPage(store)\nconnectLoginPasswordForgot(store)\nconnectLoginPasswordForgotSetPasswordService(store)\nconnectMePage(store)\nconnectReminderPageService(store)\nconnectSettingsPage(store)\nconnectSharingObjectPage(store)\nconnectShopPage(store)\nconnectSingleTrainingsPage(store)\nconnectTraineesPage(store)\nconnectTraineesSharePage(store)\nconnectTrainerInvitePageService(store)\nconnectTrainersPage(store)\nconnectTrainingsPageService(store)\nconnectTranslationMenuPage(store)\nconnectUserChangeEmailPageService(store)\nconnectUserPageService(store)\n\n// Widgets\nconnectUserMenu(store)\nconnectUserChangePassword(store)\nconnectChangeUserRoleComponentService(store)\n\nstore.dispatch({ type: 'App/Init' })\n\nexport const AppStoreProvider = createProvider(store)\nexport const useAppState = createStateHook(AppStoreProvider)\nexport const useNextAppState = createNextHook(AppStoreProvider)\nexport const useStoreHook = createStoreHook(AppStoreProvider)\nexport const useDispatchHook = createDispatchHook(AppStoreProvider)\n","import axios from 'axios'\nimport { AppStore } from 'state/store'\nimport { tools } from 'services/utils/tools'\n\nexport interface AxiosServiceMessages {\n type: 'Axios/Config/Set'\n payload: { token: boolean }\n}\n\nexport const connectAxios = (store: AppStore) => {\n const { onChange } = tools(store)\n\n axios.defaults.responseType = 'json'\n\n onChange(state => state.session.token).subscribe(token => {\n if (token) {\n axios.defaults.headers['authorization'] = 'Bearer ' + token\n } else {\n axios.defaults.headers['authorization'] = undefined\n }\n store.dispatch({\n type: 'Axios/Config/Set',\n payload: { token: token !== null },\n })\n })\n\n // If loged in the request permission header is set to the current users active role\n onChange(state => state.session.user).subscribe(user => {\n console.log('user.role: ', user.role)\n if (user) {\n axios.defaults.headers['request-with-role'] = user.role\n } else {\n axios.defaults.headers['request-with-role'] = undefined\n }\n })\n}\n","import { debounceTime } from 'rxjs/operators'\nimport { RouterMessageType } from 'services/router/router.restate'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nexport const connectAppDrawer = (store: AppStore) => {\n const { onAction, onChange } = tools(store)\n\n onAction({ type: RouterMessageType.GO }).subscribe(() =>\n store.next(s => {\n s.components.appDrawer.open = false\n })\n )\n\n onChange(s => s.session.user.role)\n .pipe(debounceTime(10))\n .subscribe(role => {\n store.next(s => {\n s.components.appDrawer.variant = role\n })\n })\n}\n","import { AppStore } from 'state/store'\nimport { tools } from 'services/utils/tools'\nimport { distinctUntilChanged, delay, skip } from 'rxjs/operators'\n\n//\n// In order to change the language of the store we have to reload the page.\n//\n// The other part - loading the ECWID store - is in the `index.html`\n// See https://github.com/kodira/corpatch/issues/247\n//\nexport const connectEcwidLocaleService = (store: AppStore) => {\n const { onChange } = tools(store)\n\n onChange(state => state.i18n.locale)\n .pipe(\n skip(1), // ignore the first initial loading\n distinctUntilChanged(), // if changed\n delay(200) //\n )\n .subscribe(() => {\n window.location.reload()\n })\n}\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { InitialPasswordReq } from 'model/ctrl/signup/InitialPasswordReq.schema'\nimport { UserInfo } from 'model/ctrl/signup/ValidateRes.schema'\nimport { UserDTO } from 'model/User.dto'\nimport RouteParser from 'route-parser'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { defaultAcceptInvitationPageState } from './AcceptInvitation.state'\n\nexport interface AcceptInvitationMessage extends Message {\n type: 'Page/AcceptInvitation/Send'\n payload: string\n}\n\nexport const connectAcceptInvitationPageService = (store: AppStore) => {\n const { onPageEnter, onPageLeave, http, onAction, pageParams } = tools(store)\n const { api } = config()\n const params = pageParams(AppRoutes.AcceptInvitation)\n\n onPageEnter(AppRoutes.AcceptInvitation).subscribe(props => {\n const { id } = props\n\n const route = new RouteParser(routes.auth.validate)\n const fullRoute = route.reverse({ id })\n\n if (id) {\n http({\n url: api + fullRoute,\n method: 'GET',\n }).subscribe(\n // success\n userInfo =>\n store.next(s => {\n s.pages.acceptInvitation.meta = {\n loading: false,\n notFound: false,\n success: false,\n }\n s.pages.acceptInvitation.userInfo = userInfo\n }),\n\n // error\n () =>\n store.next(s => {\n s.pages.acceptInvitation.meta = {\n loading: false,\n notFound: true,\n success: false,\n }\n })\n )\n }\n })\n\n onPageLeave(AppRoutes.AcceptInvitation).subscribe(() => {\n store.next(s => {\n s.pages.acceptInvitation = defaultAcceptInvitationPageState\n })\n })\n\n onAction({ type: 'Page/AcceptInvitation/Send' }).subscribe(pack => {\n const newPassword = (pack.message as AcceptInvitationMessage).payload\n const { id } = params()\n\n store.next(s => {\n s.pages.acceptInvitation.meta.loading = true\n })\n const data: InitialPasswordReq = {\n key: id,\n newPassword,\n }\n\n http({\n method: 'POST',\n url: api + routes.auth.initialPassword,\n data,\n }).subscribe(\n // Success\n data => {\n store.next(s => {\n s.pages.acceptInvitation.meta.success = true\n s.pages.acceptInvitation.meta.loading = false\n s.session.user = {\n ...data,\n }\n s.session.token = data.token\n })\n },\n // Error\n () => {\n store.next(s => {\n s.pages.acceptInvitation.meta = {\n loading: false,\n notFound: true,\n success: false,\n }\n })\n }\n )\n })\n}\n","import { AppStore } from 'state/store'\nimport { tools } from 'services/utils/tools'\nimport { Message } from '@restate/core'\nimport { routes } from 'model/ctrl/routes'\nimport { config } from 'config/config'\nimport { SignUpReq } from 'model/ctrl/signup/SignUpReq.schema'\nimport { AppRoutes } from 'routes'\nimport { Locale } from 'model/Locale'\nimport { EMail } from 'model/Email'\nimport messages from './AdminInvite.messages'\nimport { USERROLES } from '../../model/UserRole'\n\nexport interface AdminInviteMessage extends Message {\n type: 'Page/Service/AdminInvite/Invite'\n payload: {\n email: EMail\n firstName: string\n lastName: string\n }\n}\n\nexport const connectAdminInvitePageService = (store: AppStore) => {\n const { onAction, http, pageParams, snackBar, intl } = tools(store)\n const { api } = config()\n const getInstituteId = pageParams(AppRoutes.AdminInvite)\n\n onAction({ type: 'Page/Service/AdminInvite/Invite' }).subscribe(pack => {\n const payload = (pack.message as AdminInviteMessage).payload\n\n const { id } = getInstituteId()\n\n if (!id) return\n\n const setSend = (send: boolean) =>\n store.next(s => {\n s.pages.adminInvite.send = send\n })\n\n store.next(s => {\n s.pages.adminInvite.meta.loading = true\n })\n const data: SignUpReq = {\n email: payload.email,\n firstName: payload.firstName,\n lastName: payload.lastName,\n instituteId: id,\n locale: Locale.de,\n roles: [USERROLES.InstituteAdmin, USERROLES.Trainer, USERROLES.Trainee],\n }\n\n http({\n url: api + routes.auth.signup,\n method: 'POST',\n data,\n }).subscribe(\n // Success\n () => {\n store.next(s => {\n s.pages.adminInvite.meta.loading = false\n })\n setSend(true)\n const successSnackbar = intl().formatMessage(messages.successSnackbar, {\n email: payload.email,\n })\n snackBar.success(successSnackbar)\n },\n // Error\n _err => {\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar, {\n email: payload.email,\n })\n // const status = err.response.status\n snackBar.error(errorSnackbar)\n store.next(s => {\n s.pages.adminInvite.error = ''\n s.pages.adminInvite.meta.loading = false\n })\n }\n )\n })\n}\n","import { Message } from '@restate/core'\nimport { PostMeChangePasswordReq } from 'model/ctrl/me/PostMeChangePasswordReq.schema'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { HttpError } from 'services/utils/http'\nimport { ChangePasswordErrorMessage } from 'model/ctrl/me/PostMeChangePasswordRes.schema'\n\nimport messages from './UserChangePassword.messages'\nimport { AppRoutes } from '../../routes'\n\nexport interface ChangePasswordMessage extends Message {\n type: 'Page/ChangePassword/Send'\n payload: { oldPassword: string; newPassword: string }\n}\n\nexport const connectChangePasswordPageService = (store: AppStore) => {\n const { onAction, http, snackBar, intl, goTo } = tools(store)\n const wrongPasswordSnackbar = intl().formatMessage(\n messages.wrongPasswordSnackbar\n )\n const notChangedPasswordSnackbar = intl().formatMessage(\n messages.notChangedPasswordSnackbar\n )\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n\n const { api } = config()\n\n onAction({ type: 'Page/ChangePassword/Send' }).subscribe(pack => {\n const {\n oldPassword,\n newPassword,\n } = (pack.message as ChangePasswordMessage).payload\n\n const data: PostMeChangePasswordReq = { oldPassword, newPassword }\n\n const onError = (err: HttpError) => {\n if (err.errorMessage === 'Wrong password') {\n snackBar.error(wrongPasswordSnackbar)\n } else {\n snackBar.error(notChangedPasswordSnackbar + err.errorMessage)\n }\n }\n\n const onSuccess = () => {\n snackBar.success(successSnackbar)\n goTo(AppRoutes.Home)\n }\n\n http({\n method: 'POST',\n url: api + routes.me.changePassword,\n data,\n }).subscribe(onSuccess, onError)\n })\n}\n","import { Message } from '@restate/core'\nimport { routes } from 'model/ctrl/routes'\nimport { AppRoutes } from 'routes'\nimport { combineLatest } from 'rxjs'\nimport { map } from 'rxjs/operators'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { CourseAggregate } from './Course.state'\n\nexport interface PagesServiceCourseUpdateMessage extends Message {\n type: 'Pages/Service/Course/Update' | 'Pages/Service/Course/Error'\n}\n\nexport const connectCoursePageService = (store: AppStore) => {\n const { http, onPageEnter, onLogin } = tools(store)\n\n combineLatest(onLogin(), onPageEnter(AppRoutes.Course))\n .pipe(map(([_login, pageEnter]) => pageEnter))\n .subscribe(params => {\n const { id } = params\n\n http({\n route: {\n path: routes.course,\n id,\n },\n }).subscribe(\n course =>\n store.next(\n state => {\n state.pages.course.course = course\n state.pages.course.meta.loading = false\n state.pages.course.meta.notFound = false\n },\n { type: 'Pages/Service/Course/Update' }\n ),\n _error => {\n console.error('COURSES:', _error)\n store.next(\n state => {\n state.pages.course.course = null\n state.pages.course.meta.notFound = true\n state.pages.course.meta.loading = false\n },\n { type: 'Pages/Service/Course/Error' }\n )\n }\n )\n })\n}\n","import { CourseTableData } from 'components/CourseTable/CourseTable'\nimport { Course } from 'model/Course'\nimport { routes } from 'model/ctrl/routes'\nimport { TrainerDTO } from 'model/ctrl/trainers/GetTrainersRes.schema'\nimport { Institute } from 'model/Institute'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { CoursesPageMessage } from './Courses.state'\nimport { CourseDocument } from 'model/db/CourseDocument.db-schema'\n\nimport messages from './Courses.messages'\nimport { USERROLES } from '../../model/UserRole'\n\nexport interface CourseAggregate extends Course {\n institute: Institute\n trainer: TrainerDTO\n}\n\nfunction model2ViewModel(model: CourseAggregate[]): CourseTableData[] {\n return model.map(course => {\n return {\n id: course._id,\n selected: false,\n isSelectionEnabled: true,\n date: new Date(course.date),\n institute: course.institute.name,\n trainer: course.trainer\n ? course.trainer.firstName + ' ' + course.trainer.familyName\n : '-',\n trainerEmail: course.trainer ? course.trainer.email : '-',\n identifier: course.identifier || '',\n location: course.location,\n traineeCount: course.trainees.length,\n }\n })\n}\n\nexport const connectCoursesPageService = (store: AppStore) => {\n const { onLoginPageEnter, http, onPageLeave, onAction, snackBar, intl } =\n tools(store)\n\n onPageLeave(AppRoutes.Courses).subscribe(() => {\n store.next(state => {\n state.pages.courses.meta.loading = true\n state.pages.courses.meta.notFound = false\n })\n })\n\n function fetchCourses() {\n http({ route: { path: routes.courses } }).subscribe(\n courses => {\n store.next(\n state => {\n state.pages.courses.data = model2ViewModel(courses)\n state.pages.courses.meta.loading = false\n state.pages.courses.meta.notFound = false\n },\n { type: 'Page/Courses/Service/Update' }\n )\n },\n\n _error => {\n console.error(_error)\n store.next(\n state => {\n debugger\n state.pages.courses.data = []\n state.pages.courses.meta.notFound = true\n state.pages.courses.meta.loading = false\n },\n { type: 'Page/Courses/Service/Error' }\n )\n }\n )\n }\n\n onLoginPageEnter(AppRoutes.Courses, {\n roles: [\n USERROLES.CorPatchAdmin,\n USERROLES.InstituteAdmin,\n USERROLES.Trainer,\n ],\n }).subscribe(() => {\n fetchCourses()\n })\n\n //\n // Delete institute and associated trainers, admins and trainees\n //\n onAction({ type: 'Page/Courses/Delete' }).subscribe(deleteReq => {\n const id = (deleteReq.message as CoursesPageMessage).payload\n const isAdmin = store.state.session.user.role === USERROLES.CorPatchAdmin\n\n if (isAdmin) {\n http({\n route: { path: routes.course, id },\n method: 'DELETE',\n }).subscribe(\n () => {\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n snackBar.success(successSnackbar)\n fetchCourses()\n },\n () => {\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n snackBar.error(errorSnackbar)\n }\n )\n }\n })\n}\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { GlobalConfig } from 'model/GlobalConfig'\nimport { NotificationType } from 'model/Notification'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { PostGlobalConfigReq } from '../../model/ctrl/cpxCorpatchAdminConfig/PostGlobalConfigReq.schema'\nimport { defaultGlobalSettingsState } from './GlobalSettings.state'\n\nexport interface GlobalSettingsPageNotificationMessages extends Message {\n type: 'Page/GlobalSettings/Notifications/Test'\n payload?: { notificationType: NotificationType }\n}\n\nexport interface GlobalSettingsPageCptConfigMessages extends Message {\n type: 'Page/GlobalSettings/Config/Save' | 'Page/GlobalSettings/Config/Load'\n}\n\nexport const connectGlobalSettingsPage = (store: AppStore) => {\n const { http, onAction, snackBar, onPageLeave } = tools(store)\n const { api } = config()\n\n //\n // onPageEnter\n //\n function setLoading() {\n store.next(state => {\n state.pages.globalSettings = defaultGlobalSettingsState\n })\n }\n\n onPageLeave(AppRoutes.GlobalSettings).subscribe(setLoading)\n\n onAction({ type: 'Page/GlobalSettings/Config/Load' }).subscribe(() => {\n setLoading()\n\n http({\n url: api + routes.corPatchAdmin.globalConfig,\n }).subscribe(\n res => {\n store.next(state => {\n state.pages.globalSettings.feedbackConfig = res.feedbackConfig\n state.pages.globalSettings.resultConfig.simple =\n res.resultConfig.simple\n state.pages.globalSettings.sessionConfig.audioFeedbackDebounceTime =\n res.sessionConfig.audioFeedbackDebounceTime.value\n state.pages.globalSettings.meta.loading = false\n })\n },\n\n _error => {\n console.error(_error)\n store.next(state => {\n state.pages.globalSettings = defaultGlobalSettingsState\n })\n }\n )\n })\n\n onAction({ type: 'Page/GlobalSettings/Config/Save' }).subscribe(() => {\n const globalSettings = store.state.pages.globalSettings\n\n const data: PostGlobalConfigReq = {\n feedbackConfig: globalSettings.feedbackConfig,\n resultConfig: globalSettings.resultConfig,\n sessionConfig: {\n audioFeedbackDebounceTime: {\n locked: true,\n value: globalSettings.sessionConfig.audioFeedbackDebounceTime,\n },\n },\n }\n\n http({\n url: api + routes.corPatchAdmin.globalConfig,\n method: 'POST',\n data: data,\n }).subscribe(\n () => snackBar.success('Your updated configuration was saved'),\n () => snackBar.error('Your configuration could not be saved')\n )\n })\n\n onAction({ type: 'Page/GlobalSettings/Notifications/Test' }).subscribe(\n pack => {\n const notificationType = (\n pack.message as GlobalSettingsPageNotificationMessages\n ).payload?.notificationType\n\n http({\n method: 'GET',\n route: {\n path: routes.corPatchAdmin.testNotifications,\n id: notificationType,\n },\n }).subscribe(\n () => {\n snackBar.success('The test notification has been sent successfully')\n },\n () => {\n snackBar.error('The test notification could not be sent')\n }\n )\n }\n )\n}\n","import { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { USERROLES } from '../../model/UserRole'\n\nexport const connectInstituteAdminSharesPage = (store: AppStore) => {\n const { onLoginPageEnter, http } = tools(store)\n const { api } = config()\n\n // //\n // // entering page and user is a corpatch admin\n // //\n onLoginPageEnter(AppRoutes.InstituteAdminShares, {\n roles: [USERROLES.InstituteAdmin],\n }).subscribe(() => {\n http({\n url: api + routes.sharing.sharingObjects,\n method: 'GET',\n }).subscribe(sharingObjects => {\n store.next(state => {\n state.pages.instituteAdminShares.sharingObjects = sharingObjects\n })\n })\n })\n}\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { ForgotPasswordSendEmailReq } from 'model/ctrl/forgotPassword/ForgotPasswordSendEmailReq.schema'\nimport { routes } from 'model/ctrl/routes'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nimport messages from '../../I18N/general.messages'\n\nexport interface PagesLoginPasswordForgotMessage extends Message {\n type: 'Pages/Login/PasswordForgot/SendEmail'\n}\n\nexport const connectLoginPasswordForgot = (store: AppStore) => {\n const { onAction, http, onPageLeave, snackBar, intl } = tools(store)\n\n onPageLeave(AppRoutes.LoginPasswordForgot).subscribe(() => {\n store.next(s => {\n s.pages.loginPasswordForgot.send = 'input'\n })\n })\n\n onAction({ type: 'Pages/Login/PasswordForgot/SendEmail' }).subscribe(() => {\n const email = store.state.pages.login.email\n\n const request: ForgotPasswordSendEmailReq = {\n email,\n }\n\n const { api } = config()\n\n store.next(s => {\n s.pages.loginPasswordForgot.send = 'sending'\n })\n\n const onError = () => {\n store.next(s => {\n s.pages.loginPasswordForgot.send = 'error'\n\n const errorSnackbar = intl().formatMessage(\n messages.emailAllreadySentSnackbar\n )\n snackBar.error(errorSnackbar)\n })\n }\n\n const onSuccess = () => {\n store.next(s => {\n s.pages.loginPasswordForgot.send = 'send'\n })\n }\n\n http({\n url: api + routes.forgotPassword.sendEmail,\n method: 'POST',\n data: request,\n }).subscribe(onSuccess, onError)\n })\n}\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { ForgotPasswordSetPasswordReq } from 'model/ctrl/forgotPassword/ForgotPasswordSetPasswordReq.schema'\nimport { routes } from 'model/ctrl/routes'\nimport { AppRoutes } from 'routes'\nimport { delay } from 'rxjs/operators'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nexport interface PagesPasswordForgotSetPasswordMessage extends Message {\n type: 'Pages/LoginPasswordForgotSetPassword/Set'\n payload: string\n}\n\nexport const connectLoginPasswordForgotSetPasswordService = (\n store: AppStore\n) => {\n const { onPageLeave, onPageEnter, pageParams, http, onAction } = tools(store)\n const params = pageParams(AppRoutes.LoginPasswordForgotSetPassword)\n\n onPageLeave(AppRoutes.LoginPasswordForgotSetPassword).subscribe(() => {\n store.next(s => {\n s.pages.loginPasswordForgotSetPassword.meta = {\n loading: true,\n notFound: false,\n }\n s.pages.loginPasswordForgotSetPassword.success = false\n })\n })\n\n onPageEnter(AppRoutes.LoginPasswordForgotSetPassword).subscribe(() => {\n const { code } = params()\n\n const success = () => {\n store.next(s => {\n s.pages.loginPasswordForgotSetPassword.meta = {\n loading: false,\n notFound: false,\n }\n })\n }\n\n const error = () => {\n store.next(s => {\n s.pages.loginPasswordForgotSetPassword.meta = {\n loading: false,\n notFound: true,\n }\n })\n }\n\n http({\n route: {\n path: routes.forgotPassword.checkCode,\n id: code,\n },\n })\n .pipe(delay(500))\n .subscribe(success, error)\n })\n\n onAction({ type: 'Pages/LoginPasswordForgotSetPassword/Set' }).subscribe(\n pck => {\n const { api } = config()\n const { code } = params()\n\n const password = (pck.message as PagesPasswordForgotSetPasswordMessage)\n .payload\n\n const data: ForgotPasswordSetPasswordReq = {\n code,\n password,\n }\n\n store.next(s => {\n s.pages.loginPasswordForgotSetPassword.meta.loading = true\n })\n\n const success = () => {\n store.next(s => {\n s.pages.loginPasswordForgotSetPassword = {\n meta: {\n loading: false,\n notFound: false,\n },\n success: true,\n }\n })\n }\n\n const error = () => {\n store.next(s => {\n s.pages.loginPasswordForgotSetPassword = {\n meta: {\n loading: false,\n notFound: true,\n },\n success: false,\n }\n })\n }\n\n http({\n method: 'POST',\n url: api + routes.forgotPassword.resetPassword,\n data,\n })\n .pipe(delay(1000))\n .subscribe(success, error)\n }\n )\n}\n","import { Message } from '@restate/core'\nimport { PostMeChangeUserReq } from 'model/ctrl/me/PostMeChangeUserReq.schema'\nimport { routes } from 'model/ctrl/routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { defaultMeState } from './Me.state'\nimport messages from './Me.messages'\nimport { AppRoutes } from 'routes'\nimport { defaultState } from 'state/state'\nimport { LogoutService } from 'services/logout/logout.service'\n\nexport interface PagesMeServiceMessages extends Message {\n type: 'Page/Me/Save' | 'Page/Me/Delete'\n}\n\nexport const connectMePage = (store: AppStore) => {\n const { http, onAction, snackBar, onLogout, onChange, intl, goTo } = tools(\n store\n )\n\n const setLoading = (loading: boolean) =>\n store.next(s => {\n s.pages.me.meta.loading = loading\n })\n\n onChange(s => s.session.user).subscribe(() => {\n store.next(s => {\n s.pages.me = {\n firstName: s.session.user.firstName,\n familyName: s.session.user.familyName,\n gender: s.session.user.gender,\n meta: {\n loading: false,\n ready: true,\n },\n }\n })\n })\n\n onLogout().subscribe(() => {\n store.next(s => {\n s.pages.me = defaultMeState\n })\n })\n\n onAction({ type: 'Page/Me/Save' }).subscribe(() => {\n const me = store.state.pages.me\n\n const data: PostMeChangeUserReq = {\n firstName: me.firstName,\n familyName: me.familyName,\n gender: me.gender,\n }\n\n const onSuccess = () => {\n setLoading(false)\n store.next(s => {\n s.session.user.firstName = me.firstName\n s.session.user.familyName = me.familyName\n s.session.user.gender = me.gender\n })\n snackBar.success(intl().formatMessage(messages.snackBarSaved))\n }\n\n const onError = () => {\n setLoading(false)\n snackBar.error(intl().formatMessage(messages.snackBarError))\n }\n\n setLoading(true)\n\n http({\n route: { path: routes.me.changeMe },\n method: 'POST',\n data,\n }).subscribe(onSuccess, onError)\n })\n\n onAction({ type: 'Page/Me/Delete' }).subscribe(() => {\n http({\n route: { path: routes.auth.delete },\n method: 'DELETE',\n }).subscribe(\n () => {\n snackBar.success('The deletion of your account was successfull')\n const location = store.state.location\n store.next(() => ({ ...defaultState, location }), {\n type: LogoutService.Done,\n })\n goTo(AppRoutes.Logout)\n localStorage.removeItem('corpatch')\n },\n () => snackBar.error('There was an error while deleting your account.')\n )\n })\n}\n","import { Message } from '@restate/core'\nimport { routes } from '../../model/ctrl/routes'\nimport { USERROLES } from '../../model/UserRole'\nimport { tools } from '../../services/utils/tools'\nimport { AppStore } from '../../state/store'\nimport { defaultOnboardingState, OnboardingProgress } from './Reminder.state'\n\nexport interface ReminderPageServiceMessages extends Message {\n type:\n | 'Pages/Service/Reminder/Update'\n | 'Pages/Service/Reminder/Error'\n | 'Pages/Service/Reminder/Email/Verify'\n}\n\nexport const connectReminderPageService = (store: AppStore) => {\n const { http, hasUserRole, onLogout, onAction, snackBar } = tools(store)\n\n hasUserRole(USERROLES.Trainee).subscribe(() => {\n http({\n route: { path: routes.onboarding.onboarding },\n }).subscribe(\n onboarding => {\n store.next(\n state => {\n state.pages.onboarding.onboarding = onboarding\n state.pages.onboarding.meta.loading = false\n state.pages.onboarding.meta.notFound = false\n },\n { type: 'Pages/Service/Reminder/Update' }\n )\n },\n\n _error => {\n console.error(_error)\n store.next(\n state => {\n state.pages.onboarding.onboarding =\n defaultOnboardingState.onboarding\n state.pages.onboarding.meta.loading = false\n state.pages.onboarding.meta.notFound = true\n },\n { type: 'Pages/Service/Reminder/Error' }\n )\n }\n )\n })\n\n onAction({ type: 'Pages/Service/Reminder/Email/Verify' }).subscribe(() => {\n http({\n route: { path: routes.onboarding.resendVerificationEmail },\n }).subscribe(\n () => {\n snackBar.success('The verification E-Mail has been sent')\n },\n () => {\n console.error('Error sending verification E-Mail: ')\n snackBar.error('Sorry, verification E-Mail could not be sent')\n }\n )\n })\n\n onLogout().subscribe(() => {\n store.next(state => {\n state.pages.onboarding.onboarding = defaultOnboardingState.onboarding\n state.pages.onboarding.meta.loading = true\n state.pages.onboarding.meta.notFound = false\n })\n })\n}\n","import { Message } from '@restate/core'\nimport { routes } from 'model/ctrl/routes'\nimport { AppRoutes } from 'routes'\nimport { combineLatest } from 'rxjs'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { CptConfig } from 'model/CptConfig'\n\nexport interface PagesSettingsServiceMessages extends Message {\n type:\n | 'Page/Settings/Save'\n | 'Pages/Institute/InstituteAdmin/ResultConfig/Save'\n}\n\nexport const connectSettingsPage = (store: AppStore) => {\n const { onPageEnter, onLogin, http, onAction, snackBar } = tools(store)\n\n combineLatest(onLogin(), onPageEnter(AppRoutes.Settings)).subscribe(() => {\n http({ route: { path: routes.cpt.config } }).subscribe(\n appConfig => {\n store.next(s => {\n s.pages.settings.appConfig = appConfig\n s.pages.instituteResultConfig = appConfig.resultConfig\n })\n }\n )\n })\n\n onAction({ type: 'Page/Settings/Save' }).subscribe(() => {\n const data = store.state.pages.settings.appConfig\n http({\n route: { path: routes.cpt.config },\n method: 'PUT',\n data,\n }).subscribe(() => {\n snackBar.success('Configuration saved')\n })\n })\n\n onAction({\n type: 'Pages/Institute/InstituteAdmin/ResultConfig/Save',\n }).subscribe(() => {\n const data = store.state.pages.instituteResultConfig\n http({\n route: { path: routes.corPatchAdmin.resultConfigInstituteAdmin },\n method: 'POST',\n data,\n }).subscribe(() => {\n snackBar.success('Configuration saved')\n })\n })\n}\n","import { routes } from 'model/ctrl/routes'\nimport { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { USERROLES } from '../../model/UserRole'\nimport { defaultSharingObjectsState } from './SharingObject.state'\nimport { Message } from '@restate/core'\nimport messages from './SharingObject.messages'\n\nexport interface PageSharingObjectSaveMessage extends Message {\n type: 'Page/SharingObject/Save'\n}\n\nexport interface PageSharingObjectDeleteMessage extends Message {\n type: 'Page/SharingObject/Delete'\n}\n\nexport type PageSharingObjectMessages =\n | PageSharingObjectSaveMessage\n | PageSharingObjectDeleteMessage\n\nexport const connectSharingObjectPage = (store: AppStore) => {\n const {\n onLoginPageEnter,\n http,\n snackBar,\n pageParams,\n onAction,\n goTo,\n intl,\n } = tools(store)\n\n const { CorPatchAdmin, InstituteAdmin } = USERROLES\n\n function fetchData(url: string) {\n const params = pageParams(url)\n const { id } = params()\n\n http({\n route: { path: routes.sharing.sharingObject, id },\n }).subscribe(\n sharingObjects =>\n store.next(state => {\n state.pages.sharingObjects.data = sharingObjects\n }),\n error => {\n console.log(error)\n store.next(state => {\n state.pages.sharingObjects = defaultSharingObjectsState\n state.pages.sharingObjects.meta.notFound = true\n state.pages.sharingObjects.meta.loading = false\n })\n }\n )\n }\n\n onLoginPageEnter(AppRoutes.SharingObject, {\n roles: [CorPatchAdmin],\n }).subscribe(_params => {\n fetchData(AppRoutes.SharingObject)\n })\n\n onLoginPageEnter(AppRoutes.InstituteAdminSharingObject, {\n roles: [InstituteAdmin],\n }).subscribe(_params => {\n fetchData(AppRoutes.InstituteAdminSharingObject)\n })\n\n onAction({ type: 'Page/SharingObject/Save' }).subscribe(_ => {\n const sharingObject = store.state.pages.sharingObjects.data\n const id = sharingObject._id\n\n function onSuccess() {\n snackBar.success(intl().formatMessage(messages.snackBarSaved))\n }\n\n function onError() {\n snackBar.error(intl().formatMessage(messages.snackBarSaveError))\n }\n\n http({\n method: 'POST',\n route: { path: routes.sharing.sharingObject, id },\n data: sharingObject,\n }).subscribe(onSuccess, onError)\n })\n\n onAction({ type: 'Page/SharingObject/Delete' }).subscribe(() => {\n const sharingObject = store.state.pages.sharingObjects.data\n const id = sharingObject._id\n\n function onSuccess() {\n snackBar.success(intl().formatMessage(messages.snackBarDeleted))\n goTo(AppRoutes.Institute, { id: sharingObject.instituteId })\n }\n\n function onError() {\n snackBar.error(intl().formatMessage(messages.snackBarDeleteError))\n }\n\n http({\n method: 'POST',\n route: { path: routes.sharing.admin.deleteSharingObject, id },\n }).subscribe(onSuccess, onError)\n })\n}\n","import { Message } from '@restate/core'\nimport { SharingTraining } from 'model/SharingTraining'\nimport { SharingTrainingDto } from 'model/SharingTraining.dto'\nimport { routes } from 'model/ctrl/routes'\nimport { SingleTrainingDocument } from 'model/db/SingleTrainingDocument.db-schema'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { USERROLES } from '../../model/UserRole'\n\nexport interface SingleTrainingView extends SingleTrainingDocument {\n origin: string\n}\n\nexport interface SingleTrainingShareMessage extends Message {\n type: 'Page/SingleTraining/Share'\n}\n\nexport const connectSingleTrainingsPage = (store: AppStore) => {\n const { onLoginPageEnter, http, snackBar, hasUserRole, onAction } = tools(\n store\n )\n\n onLoginPageEnter(AppRoutes.SingleTrainings).subscribe(() => {\n hasUserRole(USERROLES.Trainee).subscribe(() => {\n http({\n route: { path: routes.sharing.trainee.sharingObjects },\n }).subscribe(res => {\n store.next(state => {\n state.pages.singleTrainings.traineeSharingObjects = res as any // TODO: fix typing\n })\n })\n\n http({\n route: { path: routes.cps.singleTrainings },\n }).subscribe(\n res => {\n store.next(state => {\n state.pages.singleTrainings.singleTrainings = res\n })\n },\n () => {\n snackBar.error('Single Trainings could not be fetched')\n }\n )\n })\n })\n\n onAction({ type: 'Page/SingleTraining/Share' }).subscribe(() => {\n const { share } = store.state.pages.singleTrainings\n const sharingTrainingDto: SharingTrainingDto = {\n singleTrainingId: share.selectedTrainingId,\n sharingObjectIds: share.selectedTraineeSharingObject,\n }\n\n store.next(state => {\n state.pages.singleTrainings.share.selectedTrainingId = ''\n state.pages.singleTrainings.share.selectedTraineeSharingObject = []\n })\n\n http({\n method: 'POST',\n route: { path: routes.sharing.trainee.postSingleTraining },\n data: sharingTrainingDto,\n }).subscribe(\n _success => {\n snackBar.success('Single Training shared!')\n http({\n route: { path: routes.sharing.trainee.sharingObjects },\n }).subscribe(res => {\n store.next(state => {\n state.pages.singleTrainings.traineeSharingObjects = res as any // TODO: fix typing\n })\n })\n },\n _err => {\n snackBar.error('Single Training could not be shared')\n console.log(_err)\n }\n )\n })\n}\n","import { TraineeDTO } from './../../model/ctrl/trainees/GetTraineesRes.schema'\nimport { AppStore } from '../../state/store'\nimport { tools } from '../../services/utils/tools'\nimport { config } from '../../config/config'\nimport RouteParser from 'route-parser'\nimport { routes } from '../../model/ctrl/routes'\nimport { AppRoutes } from '../../routes'\nimport { Message } from '@restate/core'\nimport { pageStateMachine } from '../../machines/pageState.machine'\nimport { defaultTraineesState } from './Trainees.state'\nimport { UUID } from 'model/UUID'\nimport { NotificationType } from 'model/Notification'\nimport { USERROLES } from '../../model/UserRole'\n\nimport messages from './Trainees.messages'\n\nexport interface PagesTraineeServiceMessages extends Message {\n type:\n | 'Pages/Trainee/Service/Loading'\n | 'Pages/Trainee/Service/Update'\n | 'Pages/Trainee/Service/Error'\n | 'Pages/Trainee/Service/Save'\n | 'Pages/Trainees/Notify'\n | 'Pages/Trainees/Delete'\n payload?: { ids: UUID[]; notificationType?: NotificationType }\n}\n\nexport const connectTraineesPage = (store: AppStore) => {\n const { onLoginPageEnter, http, onPageLeave, onAction, snackBar, intl } =\n tools(store)\n const { api } = config()\n\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n const warningSnackbar = intl().formatMessage(messages.warningSnackbar)\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n\n const machine = pageStateMachine({\n id: 'connectTraineePage',\n fetchData,\n setLoading,\n })\n\n onLoginPageEnter(AppRoutes.Trainees, {\n roles: [USERROLES.CorPatchAdmin],\n }).subscribe(() => {\n setLoading()\n fetchData()\n })\n\n onPageLeave(AppRoutes.Institute).subscribe(() => machine.send('PAGE_LEAVE'))\n\n function setLoading() {\n store.next(state => {\n state.pages.trainees = defaultTraineesState\n state.pages.trainees.meta.loading = true\n })\n }\n\n function fetchData() {\n const path = new RouteParser(routes.trainees).reverse({})\n\n http({ url: api + path }).subscribe(\n trainees => {\n store.next(\n state => {\n state.pages.trainees.data = trainees.map(t => {\n const firstnameInvalid =\n t.firstName === '' || t.firstName === 'null'\n const familyNameInvalid =\n t.familyName === '' || t.familyName === 'null'\n\n return {\n id: t._id,\n selected: false,\n isSelectionEnabled: true,\n displayName:\n !familyNameInvalid && !firstnameInvalid\n ? `${t.familyName}, ${t.firstName}`\n : !familyNameInvalid\n ? `${t.familyName}`\n : !firstnameInvalid\n ? `${t.firstName}`\n : '---',\n ...t,\n }\n })\n state.pages.trainees.meta.loading = false\n },\n { type: 'Pages/Trainee/Service/Update' }\n )\n },\n\n _error => {\n console.error(_error)\n store.next(\n state => {\n state.pages.trainees = defaultTraineesState\n state.pages.trainees.meta.notFound = true\n state.pages.trainees.meta.loading = false\n },\n { type: 'Pages/Trainee/Service/Error' }\n )\n }\n )\n }\n\n onAction({ type: 'Pages/Trainees/Notify' }).subscribe(pck => {\n const { ids, notificationType } = (\n pck.message as PagesTraineeServiceMessages\n ).payload!\n\n let errorResponses = 0\n let successfulResponses = 0\n ids.forEach(id => {\n const data = { id, notificationType }\n\n http({\n url: api + routes.corPatchAdmin.notifyUser,\n method: 'POST',\n data,\n }).subscribe(\n // Snackbars do not translation because they are a dev-only feature\n () => {\n successfulResponses += 1\n if (successfulResponses === ids.length && errorResponses === 0) {\n snackBar.success('Users have been notified successfully')\n } else if (\n errorResponses > 0 &&\n successfulResponses + errorResponses === ids.length\n ) {\n snackBar.error('One or more users could not be notified')\n }\n },\n () => {\n errorResponses += 1\n if (errorResponses === ids.length) {\n snackBar.error(\n 'An unknown error occured. No users have been notified'\n )\n }\n }\n )\n })\n })\n\n let errorResponses = 0\n let successfulResponses = 0\n onAction({ type: 'Pages/Trainees/Delete' }).subscribe(pck => {\n let ids = (pck.message as PagesTraineeServiceMessages).payload?.ids ?? []\n\n ids.forEach(id => {\n http({\n method: 'DELETE',\n route: {\n path: routes.userDelete,\n id,\n },\n }).subscribe(\n () => {\n successfulResponses += 1\n if (successfulResponses === ids.length && errorResponses === 0) {\n snackBar.success(successSnackbar)\n } else if (\n errorResponses > 0 &&\n successfulResponses + errorResponses === ids.length\n ) {\n snackBar.error(warningSnackbar)\n }\n },\n () => {\n errorResponses += 1\n if (errorResponses === ids.length) {\n snackBar.error(errorSnackbar)\n }\n\n const index = ids.indexOf(id)\n if (index !== -1) {\n ids?.splice(index, 1)\n }\n }\n )\n })\n\n const nextTraineeData = store.state.pages.trainees.data.filter(\n trainee => !ids?.includes(trainee._id)\n )\n store.next(s => {\n s.pages.trainees.data = nextTraineeData\n })\n })\n}\n","import { Message } from '@restate/core'\nimport { USERROLES } from 'model/UserRole'\nimport { routes } from 'model/ctrl/routes'\nimport { AppRoutes } from 'routes'\nimport { config } from '../../config/config'\nimport { tools } from '../../services/utils/tools'\nimport { AppStore } from '../../state/store'\nimport { SharingTraineeAggregate } from 'model/SharingTraineeAggregate'\nimport messages from './TraineeShares.messages'\n\nexport interface PagesTraineeSharesAddMessages extends Message {\n type: 'Pages/TraineeShares/Shares/Add'\n}\n\nexport interface PagesTraineeSharesDeactivateMessages extends Message {\n type: 'Pages/TraineeShares/Shares/Deactivate'\n sharingTrainee: SharingTraineeAggregate\n}\n\nexport const connectTraineesSharePage = (store: AppStore) => {\n const {\n http,\n onAction,\n snackBar,\n onLoginPageEnter,\n goTo,\n intl,\n pageParams,\n } = tools(store)\n const { api } = config()\n\n function fetchSharingTrainees() {\n store.next(state => {\n state.pages.traineeShares.meta.loading = true\n })\n\n http({\n route: { path: routes.sharing.trainee.sharingObjects },\n }).subscribe(\n res => {\n store.next(state => {\n state.pages.traineeShares.sharingTrainee = res\n state.pages.traineeShares.meta.loading = false\n })\n },\n () => {\n store.next(state => {\n state.pages.traineeShares.meta.loading = false\n })\n }\n )\n }\n\n onLoginPageEnter(AppRoutes.TraineeShares, {\n roles: [USERROLES.Trainee],\n }).subscribe(() => {\n fetchSharingTrainees()\n })\n\n onLoginPageEnter(AppRoutes.TraineeSharesInvite, {\n roles: [USERROLES.Trainee],\n }).subscribe(() => {\n const params = pageParams(AppRoutes.TraineeSharesInvite)\n const { id } = params()\n\n store.next(s => {\n s.pages.traineeShares.addDialogOpen = true\n s.pages.traineeShares.addDialogCode = id\n })\n\n goTo(AppRoutes.TraineeShares)\n })\n\n onAction({ type: 'Pages/TraineeShares/Shares/Add' }).subscribe(pck => {\n store.next(s => {\n s.pages.traineeShares.addDialogOpen = false\n })\n\n const url = api + routes.sharing.trainee.acceptInvitation\n const invitationCode = pck.state.pages.traineeShares.addDialogCode\n\n if (!invitationCode || invitationCode.length === 0) {\n const msg = intl().formatMessage(messages.snackBarInvalidCode)\n return snackBar.error(msg)\n }\n\n http({\n url,\n method: 'POST',\n data: { invitationCode },\n }).subscribe(\n () => {\n fetchSharingTrainees()\n snackBar.success(intl().formatMessage(messages.snackBarInvitationAdded))\n },\n e => {\n snackBar.error(\n intl().formatMessage(messages.snackBarErrorAddingInvitation, {\n errorMessage: e.errorMessage,\n })\n )\n }\n )\n })\n\n onAction({ type: 'Pages/TraineeShares/Shares/Deactivate' }).subscribe(pck => {\n const sharingTrainee = (pck.message as PagesTraineeSharesDeactivateMessages)\n .sharingTrainee\n\n const url = api + routes.sharing.trainee.deactivateInvitation\n\n http({\n url,\n method: 'POST',\n data: { sharingTraineeId: sharingTrainee._id },\n }).subscribe(\n () => {\n fetchSharingTrainees()\n snackBar.success(\n intl().formatMessage(messages.snackBarSharingDeactivated)\n )\n },\n e => {\n snackBar.error(\n intl().formatMessage(messages.snackBarErrorDeactivatingSharing, {\n errorMessage: e.errorMessage,\n })\n )\n }\n )\n })\n}\n","import { AppStore } from 'state/store'\nimport { tools } from 'services/utils/tools'\nimport { Message } from '@restate/core'\nimport { routes } from 'model/ctrl/routes'\nimport { config } from 'config/config'\nimport { SignUpReq } from 'model/ctrl/signup/SignUpReq.schema'\nimport { AppRoutes } from 'routes'\nimport { Locale } from 'model/Locale'\nimport { EMail } from 'model/Email'\n\nimport messages from './TrainerInvite.messages'\nimport { USERROLES } from '../../model/UserRole'\n\nexport interface TrainerInviteMessage extends Message {\n type: 'Page/Service/TrainerInvite/Invite'\n payload: {\n email: EMail\n firstName: string\n lastName: string\n }\n}\n\nexport const connectTrainerInvitePageService = (store: AppStore) => {\n const { onAction, http, pageParams, snackBar, intl } = tools(store)\n const { api } = config()\n const getInstituteId = pageParams(AppRoutes.TrainerInvite)\n\n onAction({ type: 'Page/Service/TrainerInvite/Invite' }).subscribe(pack => {\n const payload = (pack.message as TrainerInviteMessage).payload\n\n const successSnackbar = intl().formatMessage(\n messages.trainerSuccessSnackbar,\n { email: payload.email }\n )\n const errorSnackbar = intl().formatMessage(messages.trainerErrorSnackbar)\n\n const { id } = getInstituteId()\n\n if (!id) return\n\n const setSend = (send: boolean) =>\n store.next(s => {\n s.pages.trainerInvite.send = send\n })\n\n store.next(s => {\n s.pages.trainerInvite.meta.loading = true\n })\n const data: SignUpReq = {\n email: payload.email,\n firstName: payload.firstName,\n lastName: payload.lastName,\n instituteId: id,\n locale: Locale.de,\n roles: [USERROLES.Trainer, USERROLES.Trainee],\n }\n\n http({\n url: api + routes.auth.signup,\n method: 'POST',\n data,\n }).subscribe(\n () => {\n store.next(s => {\n s.pages.trainerInvite.meta.loading = false\n })\n setSend(true)\n snackBar.success(successSnackbar)\n },\n () => {\n store.next(s => {\n s.pages.trainerInvite.meta.loading = false\n })\n snackBar.error(errorSnackbar)\n }\n )\n })\n}\n","import { Message } from '@restate/core'\nimport { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport { TrainerDTO } from 'model/ctrl/trainers/GetTrainersRes.schema'\nimport { UUID } from 'model/UUID'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { USERROLES } from '../../model/UserRole'\n\nimport messages from './Trainers.messages'\n// TODO: this action should be in an own service as it is used on different pages\nexport interface TrainersPageMessages extends Message {\n type: 'Pages/Trainers/Delete'\n payload: UUID[]\n}\n\nexport const connectTrainersPage = (store: AppStore) => {\n const { http, onAction, snackBar, onPageLeave, intl, onLoginPageEnter } =\n tools(store)\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n\n const { api } = config()\n\n onPageLeave(AppRoutes.Trainers).subscribe(() => {\n store.next(s => {\n s.pages.trainers.meta = { loading: true, notFound: false }\n })\n })\n\n onAction({ type: 'Pages/Trainers/Delete' }).subscribe(pck => {\n const ids = (pck.message as TrainersPageMessages).payload\n\n ids.forEach(id => {\n http({\n method: 'DELETE',\n route: {\n path: routes.userDelete,\n id,\n },\n }).subscribe(\n () => snackBar.success(successSnackbar),\n () => snackBar.success(errorSnackbar)\n )\n })\n\n // TODO: del multiple users\n const id = ids[0]\n const nextTrainersData = store.state.pages.trainers.data.filter(\n trainer => trainer._id !== id\n )\n store.next(s => {\n s.pages.trainers.data = nextTrainersData\n })\n })\n\n onLoginPageEnter(AppRoutes.Trainers, {\n roles: [USERROLES.CorPatchAdmin, USERROLES.InstituteAdmin],\n }).subscribe(() => {\n http({\n method: 'GET',\n url: api + routes.trainers,\n }).subscribe(trainers => {\n store.next(s => {\n s.pages.trainers.meta.loading = false\n s.pages.trainers.data = trainers.map(t => ({\n id: t._id,\n selected: false,\n isSelectionEnabled: true,\n displayName: t.firstName + ' ' + t.familyName,\n ...t,\n }))\n })\n })\n })\n}\n","import { Message } from '@restate/core'\nimport { routes } from 'model/ctrl/routes'\nimport { CourseAggregate } from 'pages/Course/Course.state'\nimport { AppRoutes } from 'routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nexport interface PagesServiceCourseUpdateMessage extends Message {\n type: 'Pages/Service/Course/Update' | 'Pages/Service/Course/Error'\n}\n\nexport const connectTrainingsPageService = (store: AppStore) => {\n const { http, onLoginPageEnter } = tools(store)\n\n onLoginPageEnter(AppRoutes.Trainings).subscribe(params => {\n const { id, idx } = params.pageEnter\n\n const onSuccess = (course: CourseAggregate) =>\n store.next(\n state => {\n state.pages.trainings.idx = idx\n state.pages.course.course = course\n state.pages.course.meta.notFound = false\n state.pages.course.meta.loading = false\n state.pages.trainings.meta.notFound = false\n state.pages.trainings.meta.loading = false\n },\n { type: 'Pages/Service/Course/Update' }\n )\n\n const onError = () =>\n store.next(\n state => {\n state.pages.course.course = null\n state.pages.course.meta.notFound = true\n state.pages.course.meta.loading = false\n state.pages.trainings.meta.notFound = true\n state.pages.trainings.meta.loading = false\n },\n { type: 'Pages/Service/Course/Error' }\n )\n\n http({\n route: {\n path: routes.course,\n id,\n },\n }).subscribe(onSuccess, onError)\n })\n}\n","import { AppStore } from '../../state/store'\nimport { tools } from '../../services/utils/tools'\nimport { routes } from '../../model/ctrl/routes'\nimport { UserSettings } from '../../model/UserSettings'\nimport { Message } from '@restate/core'\nimport { USERROLES } from '../../model/UserRole'\nimport { LOCAL_STORAGE_LANGUAGE } from 'I18N/I18N.state'\n\nexport interface PagesTranslationMenuServiceMessages extends Message {\n type: 'Page/Settings/Locale'\n}\n\nexport const connectTranslationMenuPage = (store: AppStore) => {\n const { http, snackBar, onAction, hasUserRole } = tools(store)\n\n onAction({ type: 'Page/Settings/Locale' }).subscribe(() => {\n const i18n = store.state.i18n.locale\n localStorage.setItem(LOCAL_STORAGE_LANGUAGE, i18n)\n\n hasUserRole(\n USERROLES.CorPatchAdmin,\n USERROLES.InstituteAdmin,\n USERROLES.Trainee,\n USERROLES.Trainer\n ).subscribe(() => {\n const data = { locale: i18n.split('-')[0] }\n\n http({\n route: { path: routes.me.settings },\n method: 'POST',\n data,\n }).subscribe(() => {\n snackBar.success('Language saved')\n })\n })\n })\n}\n","import { routes } from 'model/ctrl/routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { PostMeChangeEmailReq } from 'model/ctrl/me/PostMeChangeEmailReq.schema'\nimport { config } from 'config/config'\n\nimport messages from './UserChangeEmail.messages'\n\nexport const connectUserChangeEmailPageService = (store: AppStore) => {\n const { onAction, http, snackBar, intl } = tools(store)\n const msgEmailChanged = intl().formatMessage(messages.emailChangedSnackbar)\n const msgEmailError = intl().formatMessage(messages.emailErrorSnackbar)\n\n const { api } = config()\n\n onAction({ type: 'USER/CHANGE_EMAIL/SEND' }).subscribe(() => {\n const newEmail = store.state.pages.userChangeEmail.nextEmail\n const data: PostMeChangeEmailReq = { newEmail }\n\n store.next(s => {\n s.pages.userChangeEmail.meta.loading = true\n })\n\n const onSuccess = () => {\n snackBar.success(msgEmailChanged)\n store.next(s => {\n s.pages.userChangeEmail.meta.loading = false\n s.pages.userChangeEmail.send = true\n s.session.user.email = newEmail\n })\n }\n\n const onError = () => {\n snackBar.error(msgEmailError)\n store.next(s => {\n s.pages.userChangeEmail.meta.loading = false\n s.pages.userChangeEmail.nextEmail = s.session.user.email\n })\n }\n\n http({\n method: 'POST',\n url: api + routes.me.changeEmail,\n data,\n }).subscribe(onSuccess, onError)\n })\n}\n","import { routes } from 'model/ctrl/routes'\nimport { UserDetailsDTO } from 'model/ctrl/user/GetUserRes.schema'\nimport { AppRoutes } from 'routes'\nimport { combineLatest } from 'rxjs'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { Message } from '@restate/core'\n\nimport messages from './UserDetails.messages'\n\nexport interface UserDetailsSendInvite extends Message {\n type: 'Page/UserDetails/SendInvite'\n}\n\nexport const connectUserPageService = (store: AppStore) => {\n const {\n http,\n pageParams,\n onPageEnter,\n onLogin,\n onPageLeave,\n onAction,\n snackBar,\n intl,\n } = tools(store)\n const successSnackbar = intl().formatMessage(messages.successSnackbar)\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n\n const getUserId = pageParams(AppRoutes.UserDetails)\n\n onAction({ type: 'Page/UserDetails/SendInvite' }).subscribe(() => {\n const { id } = getUserId()\n\n http({\n route: {\n path: routes.userInviteAgain,\n id,\n },\n }).subscribe(\n () => snackBar.success(successSnackbar),\n () => snackBar.error(errorSnackbar)\n )\n })\n\n onPageLeave(AppRoutes.UserDetails).subscribe(() => {\n store.next(s => {\n s.pages.userDetails = {\n meta: {\n loading: true,\n notFound: false,\n },\n userDetails: null,\n }\n })\n })\n\n combineLatest(onPageEnter(AppRoutes.UserDetails), onLogin()).subscribe(() => {\n const { id } = getUserId()\n\n store.next(s => {\n s.pages.userDetails = {\n meta: {\n loading: true,\n notFound: false,\n },\n userDetails: null,\n }\n })\n\n http({\n route: {\n path: routes.user,\n id,\n },\n }).subscribe(\n // Success\n userDetails => {\n store.next(s => {\n s.pages.userDetails.meta = {\n notFound: false,\n loading: false,\n }\n s.pages.userDetails.userDetails = userDetails\n })\n },\n // Error\n () => {\n store.next(s => {\n s.pages.userDetails = {\n meta: {\n notFound: true,\n loading: false,\n },\n userDetails: null,\n }\n })\n }\n )\n })\n}\n","import { Message } from '@restate/core'\nimport md5 from 'md5'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\nexport interface UserMenuMessages extends Message {\n type: 'Component/UserMenu/Update'\n}\n\n//\n// Initializes the UseMenu in the NavBar with the current user data\n//\n\nexport const connectUserMenu = (store: AppStore) => {\n const { onChange } = tools(store)\n\n onChange(state => state.session.user).subscribe(user => {\n const emailHash = md5(user.email)\n const imgUrl = `https://www.gravatar.com/avatar/${emailHash}`\n\n store.next(\n state => {\n state.components.userMenu = {\n avatarUrl: imgUrl,\n userName: user.familyName,\n eMail: user.email,\n }\n },\n { type: 'Component/UserMenu/Update' }\n )\n })\n}\n","import { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\n\n//\n// Initializes the userChangeEmail page with the current user email\n//\nexport const connectUserChangePassword = (store: AppStore) => {\n const { onChange } = tools(store)\n\n onChange(state => state.session.user.email).subscribe(() => {\n store.next(state => {\n state.pages.userChangeEmail.nextEmail = state.session.user.email\n })\n })\n}\n","import { routes } from 'model/ctrl/routes'\nimport { tools } from 'services/utils/tools'\nimport { AppStore } from 'state/store'\nimport { Message } from '@restate/core'\nimport { UserDTO } from '../../model/User.dto'\nimport { LoginService } from '../../services/login/login.service'\nimport { defaultState } from '../../state/state'\n\nimport messages from './ChangeUserRole.messages'\n\nexport interface ChangeUserRoleMessage extends Message {\n type: 'Components/ChangeUserRole/Set'\n payload: {\n requestedRole: string\n }\n}\n\nexport const connectChangeUserRoleComponentService = (store: AppStore) => {\n const { http, onAction, snackBar, intl } = tools(store)\n\n /**\n * Subscription that is called if the user logs into another role. The request-with-role header is changed and a new user state is loaded.\n * Also the preserved state is reset to the default and a log in event is emitted.\n */\n onAction({ type: 'Components/ChangeUserRole/Set' }).subscribe(pck => {\n const requestedRole = (pck.message as ChangeUserRoleMessage).payload\n\n http({\n route: {\n path: routes.auth.changeRole,\n },\n method: 'POST',\n data: requestedRole,\n }).subscribe(\n response => {\n const { token, ...user } = response\n\n // Reducer doesnt accept the root state. Therefore we loop through each slice of the state and update it.\n // This also causes a short twitch in the UI but is essential to keep the state clean.\n store.next(rootState => {\n Object.keys(rootState).forEach(key => {\n //@ts-ignore\n rootState[key] = defaultState[key]\n })\n })\n\n store.next(s => {\n s.session.user = user as UserDTO\n s.session.token = token\n })\n\n const successSnackbar = intl().formatMessage(messages.successSnackbar, {\n role: requestedRole.requestedRole,\n })\n snackBar.success(successSnackbar)\n store.dispatch({ type: LoginService.LoginSuccess })\n },\n () => {\n const errorSnackbar = intl().formatMessage(messages.errorSnackbar)\n snackBar.error(errorSnackbar)\n }\n )\n })\n}\n","import React, { useEffect } from 'react'\nimport { Colors } from 'theme/colors'\nimport { styled } from '@material-ui/styles'\nimport { SnackbarProvider, useSnackbar, MaterialDesignContent } from 'notistack'\nimport { useStoreHook } from 'state/store'\nimport { tools } from 'services/utils/tools'\nimport { AppSnackBarSuccessMessage } from './AppSnacBar.service'\n\nconst StyledMaterialDesignContent = styled(MaterialDesignContent)(() => ({\n '&.notistack-MuiContent-success': {\n backgroundColor: Colors.supportingLime[3],\n },\n '&.notistack-MuiContent-error': {\n backgroundColor: Colors.primary[5],\n },\n '&.notistack-MuiContent-warning': {\n backgroundColor: Colors.supportingCyan[5],\n },\n '&.notistack-MuiContent-info': {\n backgroundColor: Colors.vivid[5],\n },\n}))\n\nconst SnackBarListener: React.FC = () => {\n const { enqueueSnackbar } = useSnackbar()\n const store = useStoreHook()\n\n useEffect(() => {\n const { onAction } = tools(store)\n\n const subSuccess = onAction({ type: 'AppSnackBar/Success' }).subscribe(\n msg => {\n enqueueSnackbar((msg.message as AppSnackBarSuccessMessage).message, {\n variant: 'success',\n })\n }\n )\n\n const subError = onAction({ type: 'AppSnackBar/Error' }).subscribe(msg => {\n enqueueSnackbar((msg.message as AppSnackBarSuccessMessage).message, {\n variant: 'error',\n })\n })\n\n const cleanup = () => {\n subSuccess.unsubscribe()\n subError.unsubscribe()\n }\n\n return cleanup\n })\n\n return <>\n}\n\nexport const AppSnackBar: React.FC<{}> = props => {\n // const defaultToast = () => enqueueSnackbar('Default', { variant: 'default' })\n // const errorToast = () => enqueueSnackbar('Error', { variant: 'error' })\n // const infoToast = () => enqueueSnackbar('Info', { variant: 'info' })\n // const successToast = () => enqueueSnackbar('Success', { variant: 'success' })\n\n return (\n \n \n {props.children}\n \n )\n}\n","import RouteParser from 'route-parser'\nimport { goMessage } from 'services/router/router.restate'\nimport { useDispatchHook } from 'state/store'\n\ninterface RouteParams {\n id?: string\n idx?: string\n}\n\nexport function useGoToHook() {\n const dispatch = useDispatchHook()\n return function (path: string, params: RouteParams = {}) {\n const routeParser = new RouteParser(path)\n const fqRoute = routeParser.reverse(params)\n\n if (fqRoute) {\n dispatch(goMessage(fqRoute))\n } else {\n console.error(\n `Cannot parse route ${path} with params ${JSON.stringify(params)}`\n )\n }\n }\n}\n","export const DRAWER_WIDTH = 100\nexport const LOGO_HEIGHT = 70\n","const IMG_DIR = process.env.PUBLIC_URL + '/imgs/'\n\n// Color for undraw: #d64343\n// or #65931a\n// vivid: #dd901d\n// cyan:#dd901d\nexport const Images = {\n // logoUrl: IMG_DIR + 'corpatch-logo-with-text.svg',\n bugFix: IMG_DIR + 'undraw_bug_fixing.svg',\n celebration: IMG_DIR + 'undraw_celebration.svg',\n confirmation: IMG_DIR + 'undraw_confirmation.svg',\n detailedExamination: IMG_DIR + 'undraw_detailed_examination_joef.svg',\n doctors: IMG_DIR + 'undraw_doctors_hwty.svg',\n emailValidation: IMG_DIR + 'undraw_mail_2_tqip.svg',\n empty: IMG_DIR + 'undraw_empty.svg',\n femaleAvatar: IMG_DIR + 'undraw_female_avatar.svg',\n otherAvatar: IMG_DIR + 'undraw_other_avatar.svg',\n forgotPassword: IMG_DIR + 'undraw_forgot_password.svg',\n logoSmallUrl: IMG_DIR + 'corpatch-logo-with-text-small.svg',\n logout: IMG_DIR + 'undraw_quitting_time_dm8t.svg',\n mail: IMG_DIR + 'undraw_mail_2.svg',\n maleAvatar: IMG_DIR + 'undraw_male_avatar.svg',\n medicine: IMG_DIR + 'undraw_medicine_b1ol.svg',\n missingUrl: IMG_DIR + 'undraw_blank_canvas_3rbb.svg',\n mobileApp: IMG_DIR + 'undraw_mobile_app.svg',\n productTearDown: IMG_DIR + 'undraw_product_teardown.svg',\n questions: IMG_DIR + 'undraw_questions.svg',\n securityOn: IMG_DIR + 'undraw_security_on.svg',\n teacher: IMG_DIR + 'undraw_teacher.svg',\n qrCodeAppStoreCPS: IMG_DIR + 'qr-code-appstore-cps.svg',\n qrCodePlayStoreCPS: IMG_DIR + 'qr-code-playstore-cps.svg',\n newsletter: IMG_DIR + 'undraw_newsletter_vovu.svg',\n}\n","import { createTheme } from '@material-ui/core/styles'\nimport { Colors } from './colors'\n\n// Material UI color tool:\n// https://material.io/resources/color/#!/?view.left=0&view.right=1&primary.color=a31c2f&secondary.color=232323\nexport const theme = createTheme({\n palette: {\n warning: {\n main: Colors.vivid[3],\n },\n error: {\n main: Colors.primary[0],\n },\n success: {\n main: Colors.supportingLime[3],\n },\n background: {\n paper: Colors.neutrals[9],\n default: Colors.background[0],\n },\n primary: {\n light: Colors.primary[7],\n main: Colors.primary[4],\n dark: Colors.primary[2],\n },\n secondary: {\n light: Colors.supportingCyan[4],\n main: Colors.supportingCyan[2],\n dark: Colors.supportingCyan[0],\n },\n text: {\n primary: Colors.neutrals[2],\n secondary: Colors.neutrals[3],\n disabled: Colors.neutrals[4],\n hint: Colors.neutrals[5],\n },\n },\n overrides: {\n MuiTable: {\n root: {\n backgroundColor: Colors.background[0],\n },\n },\n MuiToolbar: {\n root: {\n backgroundColor: Colors.background[0],\n },\n },\n MuiPaper: {\n root: {\n backgroundColor: Colors.background[0],\n },\n },\n },\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n drawerShop: {\n id: 'cp.components.appDrawer.drawerShop',\n defaultMessage: 'Shop',\n },\n drawerTrainers: {\n id: 'cp.components.appDrawer.drawerTrainers',\n defaultMessage: 'Trainers',\n },\n drawerCourses: {\n id: 'cp.components.appDrawer.drawerCourses',\n defaultMessage: 'Courses',\n },\n drawerSingleTrainings: {\n id: 'cp.components.appDrawer.drawerSingleTrainings',\n defaultMessage: 'Trainings',\n },\n drawerExport: {\n id: 'cp.components.appDrawer.drawerExport',\n defaultMessage: 'Export',\n },\n drawerSettings: {\n id: 'cp.components.appDrawer.drawerSettings',\n defaultMessage: 'Settings',\n },\n drawerInstitutes: {\n id: 'cp.components.appDrawer.drawerInstitutes',\n defaultMessage: 'Institutes',\n },\n drawerTrainees: {\n id: 'cp.components.appDrawer.drawerTrainees',\n defaultMessage: 'Trainees',\n },\n drawerImprint: {\n id: 'cp.components.appDrawer.drawerImprint',\n defaultMessage: 'Imprint',\n },\n drawerShares: {\n id: 'cp.components.appDrawer.drawerShares',\n defaultMessage: 'Shares',\n },\n})\n","import { useNextAppState, AppStoreProvider } from 'state/store'\n\nimport { createStateHook } from '@restate/core'\n\nexport const useNextAppDrawerState = () =>\n useNextAppState(state => state.components.appDrawer)\nexport const useAppDrawerState = createStateHook(\n AppStoreProvider,\n state => state.components.appDrawer\n)\n","import React from 'react'\nimport { makeStyles, ListItem } from '@material-ui/core'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState } from 'state/store'\n\nconst useClasses = makeStyles({\n listItem: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n color: Colors.neutrals[8],\n '& p': {\n fontSize: theme.typography.fontSize - 3,\n },\n '& svg': {\n height: 25,\n width: 25,\n color: Colors.neutrals[8],\n },\n },\n})\n\nexport const DrawerListItem: React.FC<{ route: string }> = props => {\n const classes = useClasses()\n const goTo = useGoToHook()\n const path = useAppState(s => s.location.pathname)\n\n return (\n goTo(props.route)}\n >\n
{props.children}
\n \n )\n}\n","import { Drawer, Hidden, Typography } from '@material-ui/core'\nimport List from '@material-ui/core/List'\nimport TrainingsIcon from '@material-ui/icons/Assessment'\nimport InstitutesIcon from '@material-ui/icons/Business'\nimport GetAppIcon from '@material-ui/icons/GetApp'\nimport TrainersIcon from '@material-ui/icons/Group'\nimport LibraryBooksIcon from '@material-ui/icons/LibraryBooks'\nimport SettingsIcon from '@material-ui/icons/Settings'\nimport ShareIcon from '@material-ui/icons/Share'\nimport ShopIcon from '@material-ui/icons/ShoppingCart'\nimport ViewListIcon from '@material-ui/icons/ViewList'\nimport { makeStyles, withStyles } from '@material-ui/styles'\nimport { UserRole } from 'model/UserRole'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState } from 'state/store'\nimport { Colors } from 'theme/colors'\nimport { DRAWER_WIDTH, LOGO_HEIGHT } from 'theme/constants'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport messages from './AppDrawer.messages'\nimport { useAppDrawerState, useNextAppDrawerState } from './AppDrawer.restate'\nimport { DrawerListItem } from './DrawerListItem'\n\nconst useStyles = makeStyles({\n drawer: {},\n drawerContent: {\n width: DRAWER_WIDTH,\n height: '100%',\n },\n logo: {\n backgroundColor: 'white',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n paddingTop: theme.spacing(3),\n marginTop: 3,\n paddingBottom: theme.spacing(3),\n '& img': {\n height: LOGO_HEIGHT,\n },\n },\n deco: {\n width: '100%',\n height: '3px',\n },\n})\n\nconst ShopItem = () => {\n const intl = useIntl()\n const drawerShop = intl.formatMessage(messages.drawerShop)\n\n return (\n \n \n {drawerShop}\n \n )\n}\n\nconst TrainersItem = () => {\n const intl = useIntl()\n const drawerTrainers = intl.formatMessage(messages.drawerTrainers)\n\n return (\n \n \n {drawerTrainers}\n \n )\n}\n\nconst CoursesItem = () => {\n const intl = useIntl()\n const drawerCourses = intl.formatMessage(messages.drawerCourses)\n\n return (\n \n \n {drawerCourses}\n \n )\n}\n\nconst SingleTrainingsItem = () => {\n const intl = useIntl()\n const drawerSingleTrainings = intl.formatMessage(\n messages.drawerSingleTrainings\n )\n\n return (\n \n \n {drawerSingleTrainings}\n \n )\n}\n\nconst ExportItem = () => {\n const intl = useIntl()\n const drawerExport = intl.formatMessage(messages.drawerExport)\n\n return (\n \n \n {drawerExport}\n \n )\n}\n\nconst SettingsItem = () => {\n const intl = useIntl()\n const drawerSettings = intl.formatMessage(messages.drawerSettings)\n\n return (\n \n \n {drawerSettings}\n \n )\n}\n\nconst GlobalSettingsItem = () => {\n const intl = useIntl()\n const drawerSettings = intl.formatMessage(messages.drawerSettings)\n\n return (\n \n \n {drawerSettings}\n \n )\n}\n\nconst InstitutesItem = () => {\n const intl = useIntl()\n const drawerInstitutes = intl.formatMessage(messages.drawerInstitutes)\n\n return (\n \n \n {drawerInstitutes}\n \n )\n}\n\nconst TraineesItem = () => {\n const intl = useIntl()\n const drawerTrainees = intl.formatMessage(messages.drawerTrainees)\n\n return (\n \n \n {drawerTrainees}\n \n )\n}\n\nconst ImprintItem = () => {\n const intl = useIntl()\n const drawerImprint = intl.formatMessage(messages.drawerImprint)\n\n return (\n \n \n {drawerImprint}\n \n )\n}\n\nconst SharesItem = (props: { route: string }) => {\n const intl = useIntl()\n const drawerShares = intl.formatMessage(messages.drawerShares)\n\n return (\n \n \n {drawerShares}\n \n )\n}\n\nconst InstituteAdminEntries = () => (\n \n \n \n \n \n \n \n \n)\n\nconst CorPatchAdminEntries = () => (\n \n \n \n \n \n \n \n \n \n)\n\nconst TrainerEntries = () => (\n \n \n \n \n \n)\n\nconst TraineeEntries = () => (\n \n \n \n \n \n \n)\n\nconst USER_ROLES_to_Entries: { [k in UserRole]: React.ComponentType } = {\n CorPatchAdmin: CorPatchAdminEntries,\n InstituteAdmin: InstituteAdminEntries,\n Trainer: TrainerEntries,\n Trainee: TraineeEntries,\n Researcher: () => null,\n Unknown: () => null,\n}\n\ninterface AppDrawerProps {\n open: boolean\n closeDrawer: () => void\n variant: UserRole\n}\n\nconst AppDrawerContent: React.FC<{ variant: UserRole }> = ({ variant }) => {\n const classes = useStyles()\n const Entries = USER_ROLES_to_Entries[variant]\n const goTo = useGoToHook()\n\n return (\n
\n
\n goTo(AppRoutes.Home)}\n />\n
\n \n
\n )\n}\n\nconst CustomDrawer = withStyles({\n paper: {\n border: 0,\n boxShadow: theme.shadows[5],\n backgroundColor: Colors.primary[3],\n },\n})(Drawer)\n\nconst MobileDrawer = withStyles({\n paper: {\n backgroundColor: Colors.primary[3],\n },\n})(Drawer)\n\nexport const AppDrawer: React.FunctionComponent = ({\n open,\n closeDrawer,\n variant,\n}) => {\n return (\n <>\n \n \n \n \n \n\n \n \n \n \n \n \n )\n}\n\nexport default function () {\n const open = useAppDrawerState(state => state.open)\n const variant = useAppState(state => state.session.user.role)\n const next = useNextAppDrawerState()\n\n const closeDrawer = () =>\n next(drawer => {\n drawer.open = false\n })\n\n return \n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n rightsReserved: {\n id: 'cp.components.footer.rightsReserved',\n defaultMessage: '. All rights reserved.',\n },\n})\n","import { makeStyles } from '@material-ui/styles'\nimport React from 'react'\nimport { Colors } from 'theme/colors'\nimport { Typography } from '@material-ui/core'\nimport { theme } from 'theme/theme'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Footer.messages'\nimport { useAppState } from '../../state/store'\n\nconst useClasses = makeStyles({\n footer: {\n // backgroundColor: lighten(Colors.neutrals[8], 0.5),\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: theme.spacing(12),\n color: Colors.neutrals[3],\n padding: theme.spacing(),\n\n [theme.breakpoints.down('xs')]: {\n height: theme.spacing(8),\n },\n // borderBottom: '3px solid ' + Colors.primary[5],\n },\n link: {\n textDecoration: 'none',\n color: Colors.primary[5],\n },\n})\n\ninterface FooterProps {}\n\nexport const Footer: React.FC = () => {\n const intl = useIntl()\n const rightsReserved = intl.formatMessage(messages.rightsReserved)\n\n const classes = useClasses()\n\n const embeddedMode = useAppState(state => state.routerExtension.embeddedMode)\n\n const currentYear = new Date().getFullYear()\n\n if (embeddedMode) return null\n\n return (\n
\n \n Copyright© {currentYear}{' '}\n \n SmartResQ Aps{' '}\n \n {rightsReserved}\n \n
\n )\n}\n\nexport default Footer\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\nimport { State } from 'state/state'\n\nconst stateSelector = (state: State) => state.components.userMenu\nexport const useUserMenuState = createStateHook(AppStoreProvider, stateSelector)\nexport const useNextUserMenuState = createNextHook(\n AppStoreProvider,\n stateSelector\n)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n Password: {\n id: 'cp.components.userMenu.password',\n defaultMessage: 'Password',\n },\n Logout: {\n id: 'cp.components.userMenu.logout',\n defaultMessage: 'Logout',\n },\n EMail: {\n id: 'cp.components.userMenu.email',\n defaultMessage: 'E-Mail',\n },\n})\n","import {\n Divider,\n ListItemIcon,\n ListItemText,\n makeStyles,\n Menu,\n MenuItem,\n} from '@material-ui/core'\nimport AccountCircleIcon from '@material-ui/icons/AccountCircle'\nimport ExitIcon from '@material-ui/icons/ExitToApp'\nimport PasswordIcon from '@material-ui/icons/LockOpen'\nimport EmailIcon from '@material-ui/icons/MailOutline'\nimport React from 'react'\nimport { useLogout } from 'services/utils/useLogout.hook'\nimport { useUserMenuState } from './UserMenu.restate'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useIntl } from 'react-intl'\n\nimport messages from './userMenu.messages'\nimport { AppRoutes } from 'routes'\n\nconst useClasses = makeStyles({\n avatarListItem: {\n minWidth: 250,\n },\n avatar: {\n width: 32,\n height: 32,\n },\n})\n\ninterface UserMenuProps {\n anchorEl: HTMLElement\n open: boolean\n avatarUrl: string\n userName: string\n eMail: string\n\n handleClose: () => void\n handleAccount: () => void\n handleEmail: () => void\n handlePassword: () => void\n handleLogout: () => void\n}\n\nexport const UserMenu: React.FC = props => {\n const intl = useIntl()\n const Password = intl.formatMessage(messages.Password)\n const Logout = intl.formatMessage(messages.Logout)\n const EMail = intl.formatMessage(messages.EMail)\n\n const {\n open,\n userName,\n eMail,\n handleClose,\n anchorEl,\n handleLogout,\n handleAccount,\n handleEmail,\n handlePassword,\n } = props\n const classes = useClasses()\n\n return (\n \n \n \n \n \n \n \n\n \n\n \n \n \n \n \n \n\n \n \n \n \n \n \n\n \n\n \n \n \n \n \n \n \n )\n}\n\nconst ConnectedUserMenu: React.FC<{\n open: boolean\n handleClose: () => void\n}> = ({ open, handleClose }) => {\n const { userName, eMail, avatarUrl } = useUserMenuState(s => s)\n const go = useGoToHook()\n const logout = useLogout()\n\n const handleMaker = (path: string) => () => {\n handleClose()\n go(path)\n }\n\n const handleLogout = () => {\n handleClose()\n logout()\n }\n\n const handleAccount = handleMaker(AppRoutes.MeAccount)\n const handleEmail = handleMaker(AppRoutes.MeEMail)\n const handlePassword = handleMaker(AppRoutes.MePassword)\n\n const anchorRef = React.useRef(null)\n\n return (\n <>\n
\n {anchorRef.current != null && (\n \n )}\n \n )\n}\n\nexport default ConnectedUserMenu\n","import { LogoutService } from 'services/logout/logout.service'\nimport { useDispatchHook } from 'state/store'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\n\nexport const useLogout = () => {\n const dispatch = useDispatchHook()\n const go = useGoToHook()\n return function logout() {\n go(AppRoutes.Logout)\n dispatch({ type: LogoutService.Logout })\n }\n}\n","import { FormControl, InputLabel, Select, MenuItem } from '@material-ui/core'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { useHistory } from 'react-router-dom'\nimport { UserRole } from '../../model/UserRole'\nimport { AppRoutes } from '../../routes'\nimport { useAppState, useDispatchHook } from '../../state/store'\n\nimport messages from './ChangeUserRole.messages'\n\nfunction ChangeUserRole() {\n const intl = useIntl()\n const SelectLabel = intl.formatMessage(messages.selectLabel)\n\n const dispatch = useDispatchHook()\n const { role, availableRoles } = useAppState(state => state.session.user)\n const history = useHistory()\n\n const handleRoleChange = async (requestedRole: UserRole) => {\n history.push(AppRoutes.Home)\n\n dispatch({\n type: 'Components/ChangeUserRole/Set',\n payload: { requestedRole },\n })\n }\n\n return (\n \n \n {SelectLabel}\n \n handleRoleChange(event.target.value as UserRole)}\n >\n {availableRoles?.map((role, index) => (\n {role}\n ))}\n \n \n )\n}\n\nexport default ChangeUserRole\n","import React from 'react'\nimport { Divider, ListItemText, Menu, MenuItem } from '@material-ui/core'\nimport { UserMenuButtonProps } from '../NavBar/NavBar'\nimport { useNextAppTranslationState } from './TranslationMenu.restate'\nimport { useDispatchHook } from 'state/store'\nimport { FrontendLocale } from 'I18N/I18N.state'\n\nconst TranslationMenu: React.FC = props => {\n const next = useNextAppTranslationState()\n const dispatch = useDispatchHook()\n\n const changeLanguage = (language: FrontendLocale) => {\n next(settings => {\n settings.locale = language\n })\n props.handleClose()\n dispatch({ type: 'Page/Settings/Locale' })\n }\n\n return (\n props.handleClose()}\n anchorEl={props.anchorEl}\n >\n changeLanguage('de-DE')}>\n \n \n\n \n\n changeLanguage('en-US')}>\n \n \n\n \n\n changeLanguage('da-DA')}>\n \n \n\n \n\n changeLanguage('fi-FI')}>\n \n \n\n \n\n changeLanguage('it-IT')}>\n \n \n\n \n\n changeLanguage('fr-FR')}>\n \n \n\n \n\n changeLanguage('es-ES')}>\n \n \n\n \n\n changeLanguage('ar-SA')}>\n \n \n \n )\n}\n\nexport default TranslationMenu\n","import { useNextAppState } from '../../state/store'\n\nexport const useNextAppTranslationState = () =>\n useNextAppState(state => state.i18n)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n menuLabel: {\n id: 'cp.components.navBar.menuLabel',\n defaultMessage: 'menu',\n },\n})\n","import { Hidden } from '@material-ui/core'\nimport AppBar from '@material-ui/core/AppBar'\nimport IconButton from '@material-ui/core/IconButton'\nimport { makeStyles } from '@material-ui/core/styles'\nimport Toolbar from '@material-ui/core/Toolbar'\nimport Typography from '@material-ui/core/Typography'\nimport AccountCircleIcon from '@material-ui/icons/AccountCircle'\nimport ArrowBackIcon from '@material-ui/icons/ArrowBack'\nimport MenuIcon from '@material-ui/icons/Menu'\nimport TranslateIcon from '@material-ui/icons/Translate'\nimport UserMenu from 'components/UserMenu/UserMenu'\nimport React, { useState } from 'react'\nimport { useIntl } from 'react-intl'\nimport { useHistory } from 'react-router-dom'\nimport { Colors } from 'theme/colors'\nimport { DRAWER_WIDTH } from 'theme/constants'\nimport { useAppState } from '../../state/store'\nimport { useNextAppDrawerState } from '../AppDrawer/AppDrawer.restate'\nimport ChangeUserRole from '../ChangeUserRole/ChangeUserRole'\nimport TranslationMenu from '../TranslationMenu/TranslationMenu'\nimport messages from './NavBar.messages'\n\nconst useClasses = makeStyles(theme => ({\n menuButton: {\n marginRight: theme.spacing(2),\n },\n title: {\n flexGrow: 1,\n fontSize: '150%',\n },\n appBar: {\n backgroundColor: Colors.neutrals[9],\n color: Colors.neutrals[2],\n },\n drawerSpacer: {\n [theme.breakpoints.up('md')]: {\n width: DRAWER_WIDTH,\n },\n },\n}))\n\nexport interface UserMenuButtonProps {\n open: boolean\n handleClose: () => void\n handleOpen: () => void\n anchorEl?: HTMLDivElement | null\n showTranslationSwitch?: boolean\n}\n\nexport const TranslationButton: React.FC = ({\n showTranslationSwitch = true,\n handleOpen,\n handleClose,\n open,\n}) => {\n const anchorRef = React.useRef(null)\n\n const embeddedMode = useAppState(state => state.routerExtension.embeddedMode)\n\n // Language will be set from the native frontend.\n if (embeddedMode) return null\n if (!showTranslationSwitch) return null\n\n return (\n
\n
\n \n handleOpen()}\n style={{\n color: Colors.neutrals[2],\n height: '1.5rem',\n width: '1.5rem',\n padding: '1.5rem',\n }}\n >\n \n \n
\n )\n}\n\nconst UserMenuButton: React.FC = ({\n open,\n handleClose,\n handleOpen,\n}) => (\n <>\n \n \n \n \n \n)\n\ninterface NavBarProps {\n title: string\n showBackButton: boolean\n}\nexport const NavBar: React.FC = ({ title, showBackButton }) => {\n const intl = useIntl()\n const menuLabel = intl.formatMessage(messages.menuLabel)\n\n const classes = useClasses()\n const [openUserMenu, setOpenUserMenu] = useState(false)\n const [openTranslationMenu, setOpenTranslationMenu] = useState(false)\n const nextAppDrawer = useNextAppDrawerState()\n const history = useHistory()\n\n const openDrawer = () =>\n nextAppDrawer(state => {\n state.open = true\n })\n\n const goBack = () => {\n history.goBack()\n }\n\n return (\n
\n \n \n
\n\n \n \n \n \n \n\n {showBackButton && (\n \n \n \n )}\n \n {title}\n \n\n \n\n setOpenTranslationMenu(false)}\n handleOpen={() => setOpenTranslationMenu(true)}\n />\n setOpenUserMenu(false)}\n handleOpen={() => setOpenUserMenu(true)}\n />\n \n \n
\n )\n}\n","import { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\n\nexport const background = {\n backgroundColor: Colors.neutrals[9],\n}\n\nexport const center: any = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n flexGrow: 1,\n}\n\nexport const CARD_DEFAULTS = {\n minWidth: 700,\n maxWidth: 700,\n minHeight: 350,\n width: 700,\n [theme.breakpoints.down('sm')]: {\n minWidth: 'auto',\n minHeight: 'auto',\n width: '100%',\n height: '100%',\n borderRadius: 0,\n },\n}\n","import React from 'react'\nimport { makeStyles, CircularProgress } from '@material-ui/core'\nimport { center } from 'styles/styles'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\n\ninterface SpinnerProps {\n visible: boolean\n}\n\nconst useClasses = makeStyles({\n spinnerBackdrop: {\n zIndex: 1000,\n position: 'fixed',\n top: 68,\n left: 0,\n [theme.breakpoints.down('sm')]: {\n top: 60,\n },\n overflow: 'hidden',\n height: '100vh',\n width: '100vw',\n\n backgroundColor: Colors.neutrals[3],\n opacity: 0.01,\n },\n spinnerContainer: {\n zIndex: 1000,\n position: 'fixed',\n top: 0,\n [theme.breakpoints.down('sm')]: {\n top: 0,\n },\n overflow: 'hidden',\n left: 0,\n height: 'calc(100vh - 50px)',\n width: '100vw',\n ...center,\n },\n})\n\nexport const Spinner: React.FC = ({ visible }) => {\n const classes = useClasses()\n return (\n <>\n {visible && (\n <>\n
\n
\n \n
\n \n )}\n \n )\n}\n","import { makeStyles } from '@material-ui/styles'\nimport { background } from 'styles/styles'\nimport { Colors } from 'theme/colors'\n\nexport const useLayoutStyles = makeStyles({\n root: {\n height: '100%',\n margin: 0,\n display: 'flex',\n flexDirection: 'column',\n flex: 1,\n ...background,\n },\n deco: {\n width: '100%',\n height: '3px',\n backgroundColor: Colors.primary[3],\n },\n})\n","import { useEffect } from 'react'\n\nexport function useTitle(title: string) {\n useEffect(() => {\n document.title = title\n }, [title])\n}\n","import React, { useState } from 'react'\nimport { useLayoutStyles } from './useLayoutStyles.hook'\nimport { useTitle } from './useTitle.hook'\nimport { TranslationButton } from '../NavBar/NavBar'\nimport { Colors } from '../../theme/colors'\n\ninterface MainPageLayoutProps {\n title: string\n showTranslationSwitch?: boolean\n}\n\nexport const MainPageLayout: React.FunctionComponent = props => {\n const { root, deco } = useLayoutStyles()\n const { title, showTranslationSwitch = false } = props\n\n const [isOpen, setIsOpen] = useState(false)\n\n useTitle(title)\n\n return (\n
\n <>\n
\n \n {\n setIsOpen(false)\n }}\n handleOpen={() => {\n setIsOpen(true)\n }}\n showTranslationSwitch={showTranslationSwitch}\n />\n
\n\n {props.children}\n \n
\n )\n}\n","import { Theme } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport AppDrawer from 'components/AppDrawer/AppDrawer'\nimport Footer from 'components/Footer/Footer'\nimport { NavBar } from 'components/NavBar/NavBar'\nimport { Spinner } from 'components/Spinner/Spinner'\nimport React from 'react'\nimport { MainPageLayout } from './MainPageLayout'\n\nconst useStyles = makeStyles((theme: Theme) => ({\n scroller: {\n height: '100%',\n width: '100%',\n overflow: 'auto',\n display: 'flex',\n flexDirection: 'column',\n },\n safariScroller: {\n height: '100%',\n width: '100%',\n overflow: 'auto',\n },\n\n container: {\n [theme.breakpoints.up('md')]: {\n // TODO: This should be done in a better CSS way such that the\n // drawer ist not overlaying the content\n marginLeft: theme.direction === 'ltr' ? theme.spacing(10) : 0,\n marginRight: theme.direction === 'rtl' ? theme.spacing(10) : 0,\n },\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n flexGrow: 1,\n },\n\n content: {\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(2),\n marginRight: theme.spacing(2),\n\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n [theme.breakpoints.up('md')]: {\n maxWidth: 900,\n },\n flexGrow: 1,\n\n [theme.breakpoints.down('xs')]: {\n marginTop: 0,\n marginLeft: 0,\n marginRight: 0,\n maxWidth: 'auto',\n width: '100%',\n },\n },\n}))\n\ninterface AppPageLayoutProps {\n title: string\n loading?: boolean\n showBackButton?: boolean\n}\n\nexport const AppPageLayout: React.FunctionComponent = props => {\n const classes = useStyles()\n const { loading = false, title, showBackButton = false } = props\n\n // @ts-ignore\n const isSafari = window.safari !== undefined\n\n return (\n \n \n \n
\n
\n
\n \n {props.children}\n
\n
\n
\n
\n
\n \n )\n}\n","import React from 'react'\nimport { useAppState } from 'state/store'\nimport { Typography, Card, CardContent } from '@material-ui/core'\nimport {\n termsOfUse_en_US,\n termsOfUse_de_DE,\n termsOfUse_da_DA,\n termsOfUse_fi_FI,\n termsOfUse_it_IT,\n termsOfUse_fr_FR,\n termsOfUse_es_ES,\n} from './terms_of_use'\n\ninterface TermsOfUseProps {\n cardStyle: object\n}\n\nexport const TermsOfUse = (props: TermsOfUseProps) => {\n return (\n \n \n \n \n \n )\n}\n\nexport const TermsOfUseText = () => {\n const locale = useAppState(state => state.i18n.locale)\n\n let __html: string = \"imprint\"\n\n switch (locale) {\n case 'en-US':\n __html = termsOfUse_en_US\n break\n case 'de-DE':\n __html = termsOfUse_de_DE\n break\n case 'da-DA':\n __html = termsOfUse_da_DA\n break\n case 'fi-FI':\n __html = termsOfUse_fi_FI\n break\n case 'it-IT':\n __html = termsOfUse_it_IT\n break\n case 'fr-FR':\n __html = termsOfUse_fr_FR\n break\n case 'es-ES':\n __html = termsOfUse_es_ES\n break\n }\n\n return (\n \n )\n}\n\nexport default TermsOfUse\n","export const termsOfUse_en_US: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n\n
\n\n \n\n \n
\n

Terms and Conditions & Privacy Policy

\n

SmartResQ ApS / CorPatch®

\n \n
\n \n \n\n
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n

Terms and Conditions – SmartResQ ApS / CorPatch®

\n\n

Purpose of this document

\n\n

Welcome to SmartResQ/CorPatch®!

\n\n \n\n

You are currently reading our Terms and Conditions; a document with information about your relationship with SmartResQ ApS, which started when you entered our website, downloaded our free app(s), bought one of our products or the like.

\n\n \n\n

SmartResQ/CorPatch® and our associates provide our products and services to you subject to the following conditions. If you visit or shop within our website(s) or app(s), you accept these conditions. We strongly advise you to read them carefully before you proceed any use of our products or services.

\n\n \n\n

This document covers:

\n
    \n
  • How to contact SmartResQ
  • \n\n
  • Products, properties, and proper use
  • \n\n
  • Disclaimers and warranties
  • \n\n
  • Ordering
  • \n\n
  • Payment
  • \n\n
  • Delivery
  • \n\n
  • Responsibilities and rights relating to the sale
  • \n\n
  • Returns
  • \n\n
  • Data processing of personal data
  • \n\n
  • Complaints
  • \n\n
  • Changes to this document
  • \n\n
  • Law and jurisdiction
  • \n\n
  • Contact information
  • \n
\n \n\n

If you have any questions in relation to SmartResQ Terms and Conditions, please contact us.

\n\n \n\n

How to contact SmartResQ

\n\n

At SmartResQ we aim to increase survival through quality CPR in case of cardiac arrest. We want to prepare and guide bystanders to take action from the first crucial minutes after they witness a cardiac arrest. Therefore, we have developed CorPatch® – We help you save a life.

\n\n \n\n

Our company is located at Lundevej 26, 5700 Svendborg, Denmark

\n\n \n\n

You can find us in the Central Business Register under VAT No. DK 38674102

\n\n \n\n

You can call us on telephone number +45 62 200 100

\n\n \n\n

or

\n\n \n\n

e-mail us at info@corpatch.com.

\n\n \n\n

Any questions, comments, or complaints?

\n\n

We appreciate your opinion so please contact us through the above-mentioned contact information or use the contact formular on our website(s) or app(s).

\n\n
\n\n\n
\n

Products, properties, and proper use

\n

Our website(s), apps, and products

\n\n

The following paragraphs describe essential properties, rights, and responsibilities relating to the use of SmartResQ/CorPatch® services, apps, and products. \n
\nWe use reasonable efforts to include accurate and up-to-date information on the website(s) and in apps. However, SmartResQ/CorPatch® makes no warranties or representation as to the accuracy of the information. We assume no liability or responsibility for any errors or omissions in the website content, products, and apps. The information provided on this website or in apps are not a substitute for medical care. We assume responsibility for our products and apps according to the Medical Device Directive EU 745/2017 (MDR).

\n\n \n\n

Copyright

\n\n

All content included on this site, such as text, graphics, logos, button icons, images, audio clips, digital downloads, data compilations, and software, is the property of SmartResQ/CorPatch® or its content suppliers and protected by international copyright laws. The compilation of all content on this site is the exclusive property of SmartResQ/CorPatch®, with copyright authorship for this collection by SmartResQ/CorPatch® and protected by international copyright laws.

\n\n \n\n

Registered trademarks and design

\n\n

SmartResQ/CorPatch® trademarks, trade dress and product design may not be used in connection with any product or service that is not SmartResQ/CorPatch®, in any manner that is likely to cause confusion among customers, or in any manner that disparages or discredits SmartResQ/CorPatch®. All other trademarks not owned by SmartResQ/CorPatch® or its subsidiaries that appear on this site are the property of their respective owners, who may or may not be affiliated with, connected to or sponsored by SmartResQ/CorPatch® or its subsidiaries.

\n\n \n\n

License and site access

\n\n

SmartResQ/CorPatch® grants you a limited license to access and make personal use of our site(s) and apps and not to download (other than page caching) or modify it or any portion of it, except with express written consent of SmartResQ/CorPatch®. This license does not include any resale or commercial use of these site(s) or apps or its contents: (a) any collection and use of any product listings, descriptions, or prices: (b) any derivative use of this site or its contents: (c) any downloading or copying of account information for the benefit of another merchant: or (d) any use of data mining, robots, or similar data gathering and extraction tools.

\n\n \n\n

This site or app or any portion of this site may not be reproduced, re-engineered, duplicated, copied, sold, resold, visited, or otherwise exploited for any commercial purpose without express written consent of SmartResQ/CorPatch®. You may not frame or utilise framing techniques to enclose any trademark, logo, or other proprietary information (including images, text, page layout, or form) of SmartResQ/CorPatch® and our associates without express written consent.

\n\n \n\n

You may not use any meta tags or any other ‘hidden text’ utilising SmartResQ/CorPatch® name or trademarks without the express written consent of SmartResQ/CorPatch®. Any unauthorised use terminates the permission or license granted by SmartResQ/CorPatch®.

\n\n \n\n

You are granted a limited, revocable, and non-exclusive right to create a hyperlink to the home page of SmartResQ/CorPatch® so long as the link does not portray SmartResQ/CorPatch®, its associates or their products or services in a false, misleading, derogatory, or otherwise offensive matter. You may not use any SmartResQ/CorPatch® logo or other proprietary graphic or trademark as part of the link without express written permission. \n
\nIf the agreement about license and site access is breached, legal action will be taken, and a lawsuit may be filed in court.

\n\n

Electronic communication

\n\n

When you visit the homepage and social media channels of SmartResQ/CorPatch® or send e-mails to us, you are communicating with us electronically. You consent to receive communications from us electronically. We will communicate with you by e-mail or by posting notices on our websites or in the apps in the form of pop-ups or notifications. You agree that all agreements, notices, disclosures, and other communications that we provide to you electronically satisfy any legal requirement that such communications be in writing. Please refer to our Privacy Policy in a separate document that can be found on our homepage.

\n\n \n\n

Visitors of our website and social media channels may be invited to post reviews, comments, and other content e.g. submit suggestions, ideas, comments, questions, or other information, as long as the content is not illegal, obscene, threatening, defamatory, invasive of privacy, infringing of intellectual property rights, or otherwise injurious to third parties or objectionable and does not consist of or contain software viruses, political campaigning, commercial solicitation, chain letters, mass mailings, or any form of ‘spam’.

\n\n \n\n

You may not use a false e-mail address, impersonate any person or entity, or otherwise mislead as to the origin of a card or other content. SmartResQ/CorPatch® reserves the right (but not the obligation) to remove or edit such content but does not regularly review posted content. If you do post content or submit material and unless we indicate otherwise, you grant SmartResQ/CorPatch® and its associates a non-exclusive, royalty-free, perpetual, irrevocable, and fully sub-licensable right to use, reproduce, modify, adapt, publish, translate, create derivative works from, distribute, and display such content throughout the world in any media. You grant SmartResQ/CorPatch® and its associates and sublicensees the right to use the name that you submit in connection with such content if they choose.

\n\n \n\n

You represent and warrant that you own or otherwise control all the rights to the content that you post; that the content is accurate; that use of the content you supply does not violate this policy and will not cause injury to any person or entity; and that you will indemnify SmartResQ/CorPatch® or its associates for all claims resulting from content you supply. SmartResQ/CorPatch® has the right but not the obligation to monitor and edit or remove any activity or content. SmartResQ/CorPatch® takes no responsibility and assumes no liability for any content posted by you or any third party.

\n\n
\n\n\n\n
\n

Disclaimers and warranties

\n\n

Product information – CorPatch® and CorPatch® Trainer

\n\n

For correct use of any SmartResQ/CorPatch® product or service you must always follow the latest user guides, instructions, and descriptions. These can be found on our website and under each product description.

\n\n \n\n

The product CorPatch® is certified as a medical device. In case of an emergency with an adult person suffering from cardiac arrest, the product must be taken out of its enclosure, placed, and attached correctly on the chest of the victim. The product can collect data on compression, depth, frequency, and recoil and might transmit this via Bluetooth® to potential devices. Free apps on devices may guide the bystander to exercise CPR and show flow fraction, depth, recoil, and frequency if activated and correctly installed i.e., Bluetooth®, smartphone, app, battery power, etc. SmartResQ/CorPatch® is not responsible for external factors, e.g., interfering communication signals, lack of data coverage, lack of battery, incorrect hardware, or software settings, that may affect the user experience or the like.

\n\n \n\n\t\t\t \n

Similarly, SmartResQ/CorPatch® is not responsible for any physical harm caused during the use of the product in case it is not applied or used according to the instructions, e.g., performing chest compressions in a non-ergonomic way or having an unsuitable hand position. SmartResQ/CorPatch® has assessed technical risks as part of the legally prescribed risk management for medical devices, but no guarantee is given for errors going beyond this. In the event of unexpected malfunctions or occurring of non-plausible behaviour of a SmartResQ/CorPatch® system, the user is required to perform CPR manually. In this case, SmartResQ/CorPatch® is not liable as it is out of the control of SmartResQ/CorPatch®. \n
\nSmartResQ/CorPatch® monitors battery levels and state-of-health, but if the battery runs out of power, the product will not work. It is solely the responsibility of the user to ensure that the device is up to date, not harmed and has battery enough to work correctly, which can be done easily by executing a training that validates correct functionality. We recommend training for 4 minutes every 3 months with your CorPatch®.

\n\n \n\n

Important! The product CorPatch® must exclusively be used on a person in a real-life situation and only if a person suffers from cardiac arrest. It is not intended to be used on persons suffering from e.g., stroke, heart attack, or other health-related illnesses that are not cardiac arrest. The CorPatch® is not intended for use if the person is lying on a soft surface e.g., a couch or bed, as the depth feedback during such conditions might be inaccurate. No SmartResQ/CorPatch® solutions are intended for use in a moving environment including but not limited to an air, sea, or road ambulance. If used during patient transport or lifted/removed from the body during CPR, the device may provide inaccurate feedback. The CorPatch® must be attached to the chest of the patient with the patch. Make sure that the patient is lying on a firm, plane and not moving surface and that the CorPatch® is attached to the chest with the patch.

\n\n \n\n \n

The product CorPatch® Trainer must exclusively be used on manikins or similar objects in training sessions and never in a real-life situation on a real person suffering from cardiac arrest or any other health-related illness.

\n\n \n\n

It is possible to train your CPR-performance in relation to chest compressions using CorPatch® or CorPatch® Trainer regularly. We recommend that you train on a manikin, but if you do not have access to a manikin, an office chair with sufficient recoil or a hard couch can be used as a replacement. Consider the elasticity and hardness of the object you train with. SmartResQ does not recommend using soft objects including but not limited to pillows or soft couches when training, as user experience will not be right.

\n\n\n\n

If you cannot locate a manikin or a replacement object for training, consider training the situation that happens before you start chest compressions. This could be following the information given by the free app on identification of a cardiac arrest and calling emergency services and unpacking the CorPatch® from the key hanger. In this case, you will be ready to apply the CorPatch® quickly in case you witness a cardiac arrest.

\n\n \n\n

Do not use any SmartResQ/CorPatch® system for training or ‘for fun’ on any persons (living or dead), pets or any other living human being or creature.

\n\n \n\n

Products, website(s), and apps disclaimer

\n\n

SmartResQ/CorPatch® makes no representations or warranties and shall not be responsible for the competency of any person who may receive educational information and/or medical training provided through or based on the system or for the exercise of his or her skills by such person after completion of any training, courses or curriculum using the system. SmartResQ/CorPatch® does not guarantee that any person receiving educational information and/or medical training from the system will achieve any particular skill level or the necessary proficiency to qualify for any license, certificates, or ratings issued by any regulatory agency or government authority.

\n\n \n\n

SmartResQ/CorPatch® and its associates attempt to be as accurate as possible. However, SmartResQ/CorPatch® makes no representation and gives no warranty that the system and the information, products, and training provided herein: (a) will be available always or available at all; or (b) is free of error, complete, accurate, true, up to date, and/or non-misleading. When you use the system, you know and are aware that you waive any claim you may have against SmartResQ/CorPatch® for reliance on any information or training presented through the system.

\n\n \n\n

Our products are not intended for use by children. The products are small and colourful and can be mistaken for toys, but SmartResQ/CorPatch® products are not toys! We recommend not to leave the products out in the open and accessible to children. SmartResQ/CorPatch® takes no responsibility in relation to children’s use of the products. Any use of CorPatch® by children or teenagers must be allowed and monitored by responsible adults, e.g., parents, family member, or teachers.

\n\n \n\n\n

Disclaimer of warranties and limitation of liability, this site is provided by SmartResQ/CorPatch® on an ‘as is’ and ‘as available’ basis. SmartResQ/CorPatch® makes no representations or warranties of any kind, express or implied, as to the operation of this site or the information, content, materials, or products included on this site. You expressly agree that your use of this site is at your sole risk. \n
\nTo the full extent permissible by applicable law, SmartResQ/CorPatch® disclaims all warranties, express or implied, including, but not limited to, implied warranties of merchantability and fitness for a particular purpose. SmartResQ/CorPatch® does not warrant that this site, its servers, or e-mail sent from SmartResQ/CorPatch® are free of viruses/spam or other harmful components.

\n\n \n\n

SmartResQ/CorPatch® will not be liable for any damages of any kind arising from the use of this site or its products, including, but not limited to direct, indirect, incidental, punitive, and consequential damages.\n
\nCertain state laws do not allow limitations on implied warranties or the exclusion or limitation of certain damages. If these laws apply to you, some or all of the above disclaimers, exclusions or limitations may not apply to you, and you might have additional rights.

\n\n \n\n

The information presented on this website should not be construed as professional advice. You should always consult with professional advisors familiar with your factual situation for advice concerning specific matters before making any decision.

\n\n \n\n

The website may contain links which lead to websites maintained by individuals or organisations over which SmartResQ/CorPatch® has no control. SmartResQ/CorPatch® makes no representations and provides no warranties regarding the accuracy or any other aspect of the information located on such websites.

\n\n \n\n

The responsibility for any opinions, advice, statements, or other information contained in any articles or texts on this website resides solely with the author and may not necessarily reflect opinions and policies of SmartResQ/CorPatch® itself.

\n\n\n\n

Legal disclaimer

\n\n

By purchasing, licensing, viewing, using, and/or accessing our website(s), products, and apps, you acknowledge and agree that:

\n
    \n
  1. The systems provided by SmartResQ/CorPatch® are specific products to be used solely for the intended use stated in the manual of the product. Please carefully read the user instructions and manuals, and make sure you are familiar with our medical products before taking into use.
  2. \n\n
  3. The systems provided by SmartResQ/CorPatch® are specific educational and medical training products and tools are not certified as a medical device unless explicitly stated, they are not intended for any clinical or diagnostic use and intended to be used solely for medical training and performance improvement purposes.
  4. \n\n
  5. At all times you will use and access the system solely in connection with such medical training and performance improvement purposes; in compliance with all applicable laws and regulations; and in accordance with any user documentation, instruction manuals, guides, and/or requirements we provide to you electronically or in person.
  6. \n\n
  7. At no time can any SmartResQ/CorPatch® system alone diagnose, treat, or cure a human being’s condition or in a life-saving situation; support professional medical decisions, diagnosis or treatments or replace any diagnosis, recommendation, advice, treatment, or decision by an appropriately trained and licensed physician.
  8. \n\n
  9. The association of a device with any patient harm or outcomes does not mean that the device caused the harm or outcome.
  10. \n\n
  11. SmartResQ/CorPatch® takes no responsibility for harm resulting from unreasonable use of our products or use beyond the intended use of the product.
  12. \n
\n \n\n

Performance information

\n\n

The information contained herein is presented only as a guide for application of SmartResQ/CorPatch® products. SmartResQ/CorPatch® is continually working to improve the quality and reliability of its products. Nevertheless, our devices can malfunction or fail due to their inherent electrical sensitivity and vulnerability to physical stress and adverse communication signals. It is the responsibility of the buyer, when utilising SmartResQ/CorPatch® products, to observe standards of safety and testing and to avoid situations in which a malfunction or failure could result in bodily injury or damage to property.

\n\n \n\n

Standard warranty

\n\n

SmartResQ/CorPatch® Standard Limited Warranty is conditioned upon proper use of the products, website(s), and apps. \n
\nThis Warranty is confined to the first purchaser of the product only and only if the product is purchased from an authorized SmartResQ/CorPatch® dealer. Manufacturers, suppliers, or publishers, other than SmartResQ/CorPatch®, may provide their own warranties to you – please contact them for further information.

\n\n \n\n

The warranty does not cover:

\n
    \n
  1. defects or damage resulting from accident, misuse, abnormal use, abnormal conditions, improper storage, exposure to liquid, moisture, dampness, sand or dirt, neglect or unusual physical, electrical, or electromechanical stress,
  2. \n\n
  3. defects or damage resulting from excessive force or use of a metallic objects,
  4. \n\n
  5. equipment that has the production number or the enhancement data code removed, defaced, damaged, altered, or made illegible,
  6. \n\n
  7. ordinary wear and tear or normal ageing of the product,
  8. \n\n
  9. scratches, dents, and cosmetic damage, unless failure has occurred due to defect in materials or workmanship,
  10. \n\n
  11. defects or damage resulting from the use of products in conjunction or connection with accessories, products or ancillary/peripheral equipment not furnished or approved by SmartResQ/CorPatch®,
  12. \n\n
  13. defects or damage resulting from improper testing, operation, maintenance, installation, service, or adjustment not furnished or approved by SmartResQ/CorPatch®,
  14. \n\n
  15. damage caused by operating the SmartResQ/CorPatch® product outside the published guidelines,
  16. \n\n
  17. demonstration / installation of the product purchased,
  18. \n\n
  19. defects or damage resulting from external causes such as collision with an object, fire, flooding, dirt, windstorm, lightning, earthquake, exposure to weather conditions, theft, blown fuse, or improper use of any electrical source,
  20. \n\n
  21. defects or damage resulting from transmission or viruses, or other software problems introduced into the Products,
  22. \n\n
  23. if the batteries are charged by chargers other than those compliant with CorPatch® Trainer,
  24. \n\n
  25. any of the seals on the battery enclosure or cells are broken or show evidence of tampering,
  26. \n\n
  27. products repaired by, used, or purchased from another company than SmartResQ/CorPatch®,
  28. \n\n
  29. if SmartResQ/CorPatch® receives information from relevant public authorities that the product is stolen or if you are unable to deactivate passcode-enabled or other security measures designed to prevent unauthorised access to the product or you cannot prove that you are the authorised user of the product,
  30. \n\n
  31. if the products are used outside of the specified conditions stated in the manuals, e.g., temperature range, pressure, and humidity.
  32. \n
\n \n\n

Batteries and chargers

\n\n

SmartResQ/CorPatch® products contain either non-replaceable batteries (CorPatch®) or rechargeable batteries (CorPatch® Trainer). The types of batteries used in our products are described under each, individual product. SmartResQ/CorPatch® takes no responsibility if the rechargeable batteries are not handled correctly according to the manual for use.

\n\n \n\n

In connection with the sale of devices that contain batteries, we are under obligation to bring the following to your attention: \n
\nAs the end user, you are legally under obligation to dispose them correctly. The symbol of the crossed-out dustbin means that the battery may not be discarded with the household waste.

\n \n
\n \n\n
\n\t\n

Ordering

\n

The Corpatch.com webshop is open 24 hours a day and you can buy at almost any time. However, we may close the shop for maintenance. Purchase in large volume may occur directly with SmartResQ/CorPatch®.

\n\n\n

SmartResQ/CorPatch® does not offer products for sale to minors. Products intended for children can only be bought by adults. To purchase from SmartResQ/CorPatch® you must be at least 18 years old and possess a valid credit card or other means of payment that we accept.

\n\n \n\n

The presentation of the products in the online shop is not a legally binding offer, but a non-binding online catalogue. When you are ready to shop, select the items you want to buy and put them in the ‘shopping cart’. You can edit the contents of the shopping cart right up to the time of order. Any extra payments such as shipping, or debit card charges will be calculated immediately before you pay.

\n\n \n\n

When you are ready to order, click on ‘Checkout’ and enter relevant information. You can change the contents of the shopping cart right up until you confirm your purchase by clicking on the button ‘Pay’. After this, you place a binding order for the goods contained in the shopping cart that can no longer be changed. \n
\nSmartResQ/CorPatch® can accept the order by sending an order confirmation by e-mail or by delivering the goods within the delivery period.

\n\n \n\n

Certain countries may prevent the use and ownership of our products. You are solely responsible for finding out whether this product is legal to import and/or use in your country. We will send you the products you order and cannot accept any liability for customs issues or any implications of your ownership or usage of this device.

\n\n \n
\n\n\n
\n\t\n

Payment

\n

Our website(s), app(s), and webshop(s)

\n\n

Our website(s) and app(s) are free to use as long as our legal policies are accepted and complied with. Be aware that purchases of our products might be available in the webshop(s) on our website(s) and in app(s).

\n\n \n\n

Our products

\n\n

SmartResQ/CorPatch® uses QuickPay as a payment gateway. QuickPay is certified by the Payment Card Industry (PCI) Security Standards Council following the latest release of PCI Data Security Standard (DSS) Level 1, which includes: (a) an annual report - ‘Report on Compliance’ (ROC) conducted by a Qualified Security Assessor (QSA), (b) quarterly network scans performed by Approved Scan Vendor (ASV), and (c) a large number of rules and guidelines for workflow and the processing of data.

\n\n \n\n

We accept payment by:

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • Mastercard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n\t\t \n\n

Payments will be deducted from your account upon shipment of goods. All amounts are in Euro and the statutory value added tax is already included in all the prices mentioned. All credit/debit card holders are subject to validation checks and authorisation by the card issuer or payment provider. SmartResQ/CorPatch® is not responsible in the event that your payment card provider refuses to authorise payments.

\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n

We use encryption for credit card information through the Secure Socket Layer (SSL) protocol. This ensures that others cannot intercept the credit card number or other information during the transaction with our provider.

\n\n \n\n

Before finishing the contract, the customer must review and accept the shipping and logistic costs added to the purchase price, as the customer is charged these costs. After placing an order, you will receive an e-mail from us acknowledging that we have received your order. Please note that this does not mean that your order has been accepted. Your order constitutes an offer to SmartResQ/CorPatch® to buy a product (and SmartResQ/CorPatch® reserves the right to refuse orders for products). No contract will exist in relation to the products until we have confirmed to you by e-mail that the product(s) has been dispatched. Our acceptance to your offer will be deemed complete and the contract between us shall be formed when we send you a dispatch confirmation mail.

\n\n \n\n

The shipping costs are always shown in relation to each individual order.

\n\n \n\n

SmartResQ/CorPatch® retains ownership of the purchased item until the invoice amount has been fully paid by the customer and automatically ‘drawn’ just before shipping.

\n\n \n\n

Customers are only entitled to offset if their counterclaims have been legally established or are undisputed or recognised by SmartResQ/CorPatch®. In addition, customers only have a right of retention if and insofar as their counterclaim is based on the same contractual relationship.

\n\n \n\n

If the customer is in arrears with us with any payment obligations, all existing claims become due immediately.

\n\n \n\n

Surcharging fees

\n\n

As per 1 January 2018, the rules regarding surcharging have been changed. Therefore, it is no longer legal to surcharge fees on payments from consumer cards if they are issued by banks/card issuers within the EU. This applies for both debit and credit cards. Consumer cards are cards issued to a private consumer. \n
\nHowever, if the card is either a corporate card or consumer card issued outside the EU, the transaction fee will be surcharged. This means that the cardholder pays the transaction fee automatically. \n
\nThe fee will not be higher than what SmartResQ/CorPatch® is charged by the acquirer. The fee will clearly be shown as a separate post in the payment window.

\n\n\n\n
\n\n

Delivery

\n

We endeavour to ship orders from working day to working day and use an internationally trusted shipping agency. You will find the total price for your purchase including delivery at checkout before you accept your final order.

\n\n \n\n

If the customer does not accept the goods, SmartResQ/CorPatch® can withdraw from the contract or receive compensation for non-performance after a period of two weeks to cover handling and shipping costs.

\n\n \n\n

If the customer has given incorrect details about the address for delivery, it is possible to pick up the package at the package shop named in our webshop, otherwise the package is lost.

\n\n \n\n

The customer will never receive partial deliveries unless explicitly stated by SmartResQ/CorPatch®.

\n\n \n\n

Risk of loss

\n\n

The risk ownership of the product is transferred to the buyer when the product is made available to the buyer according to this agreement. If the time of delivery has passed and the buyer fails to receive a product that is made available for him/her or at his/her disposal according to the agreement, the buyer holds the risk of loss or damage caused by characteristics of the product itself.

\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n \n
\n \n\n\n\n
\n

Cancellation and returns

\n\n

When you shop with SmartResQ/CorPatch® online or offline, you have 14 days to regret and cancel where you can inform us that you have changed your mind and return the item to us in the same state as received. \n
\nWe only accept returns of unused items in original, sealed, and unharmed packaging and they must be properly packed for shipment, otherwise the products will be considered used, and no partial refunds will apply. The cancellation right only applies to unsealed products upon receipt.

\n\n \n\n

Acceptable reasons for returning a product

\n
    \n
  • Use of the 14 days cancellation right
  • \n\n
  • Product not as described (warranty)
  • \n\n
  • Product is faulty
  • \n
\n \n\n

Terms for returning CorPatch® is following the standard EU rules.

\n\n \n\n \n\n

If returning the product, keep the original packaging and do not damage, stick on or write on it. Obtain and use a dedicated return packaging, e.g., cardboard box.

\n\n \n\n

For CorPatch® Trainer, the withdrawal terms for this product are following the standard EU rules.

\n\n \n\n

To exercise the right to cancellation, you must notify us within 14 days of receipt of the items. Cancellation requests shall be sent by e-mail to info@corpatch.com, clearly stating that you wish to use your cancellation rights and why.

\n\n \n\n

We expect you to return the items as soon as possible after you have given cancellation notice and no later than 14 days after you have informed us by e-mail.

\n\n \n\n

We can reject the repayment until you have returned the items or proven that you have returned the items. For this repayment we will use the same payment method as used in the original transaction.

\n \n\n

Non-acceptable reasons for returning a product

\n
    \n
  • Change of mind after the 14-day cancellation right.
  • \n\n
  • If the product has been activated.
  • \n\n
  • If the product is used or harmed in any other way.
  • \n\n
  • If the software/free app is downloaded, connected to, installed, or in any other way combined with the physical product(s).
  • \n
\n \n\n

How to return

\n\n

We only accept returns of unopened items in original and unharmed packaging, and they must be properly packed for shipment, otherwise the products will be considered used and no refunds will apply.

\n\n \n\n

Unless otherwise stated, returns must be sent to:\n
\nSmartResQ ApS (CorPatch®) \n
\nLundevej 26 \n
\nDK-5700 Svendborg \n
\nDenmark \n

\n \n\n

IMPORTANT! You are sole responsible for the packaging quality and the items until received by us. Please keep the postal receipt including information on shipping costs and if applicable the track and trace number. We do not cover return shipping costs and we do not accept packages sent ‘Cash on Delivery (COD)’ or similar. \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n

\n \n\n
\n

Refunds

\n\n

SmartResQ/CorPatch® is obliged to repair, replace, or give a price reduction or a full refund if the item turns out to be faulty within 2 years after you purchased the item. \n
\nThe customer is not entitled to a refund if the problem is minor, such as scratches on the item or the like. \n
\nOnce SmartResQ/CorPatch® receives the customer’s item, a refund is initiated. The value of the refund amount depends on the state of the products when received at SmartResQ/CorPatch®.

\n\n \n\n

The way the customer’s refund is processed depends on the original payment method. If the customer paid by credit or debit card, refunds will be sent to the card-issuing bank within 5 business days of receipt of the returned item or cancelation request. Please contact the card-issuing bank with questions about when the credit will be posted to your account.

\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n \n
\n \n\n\n
\n

Data processing of personal information

\n\n

At SmartResQ/CorPatch® we value your personal data through our three-step data compliance effort: a. keeping a detailed map of our dataflow, b. undertaking legal assessment based on the dataflow in order to, c. implement the necessary security measures to keep your data safe.

\n\n \n\n

In order to use our webshop you must at least give the following information:

\n
    \n
  • Name
  • \n
  • Address
  • \n
  • E-mail address
  • \n
  • Phone number
  • \n
\n \n\n

The collection of personal customer information takes place within the framework of existing legislation and EU General Protection Regulation (GDPR) legislation.

\n\n \n\n

If you want to know more about our processing of your personal data, please read our Privacy Policy.

\n \n
\n \n\n
\n

Complaints

\n\n

How to complain to us

\n\n

If there is something wrong with the product, you can either have a faulty product repaired or replaced, receive a refund or reduction in price, depending on the specific situation. \n
\nOf course, it is a requirement that the complaint is justified and that the defect is not caused by incorrect use of the product or other incorrect conduct.

\n\n \n\n

We recommend that you claim as soon as possible and within one week of the defect being discovered.  \n
\nPlease do not hesitate to contact us with any question, comment, or complaints by contacting us via e-mail: info@corpatch.com

\n\n

Complain to other entities within the EU

\n\n

Please visit the official website of the European Union to complain to other entities within the EU. Find information here.

\n \n
\n \n\n
\n

Changes to this document

\n\n

On website(s), app(s), and policies

\n\n

SmartResQ/CorPatch® reserves the right to make changes, delete, modify, or supplement our website(s), app(s), policies and documents at any time for any reason without any notice to anyone. \n
\nIf any of these conditions shall be deemed invalid, void or for any reason unenforceable, that condition shall be deemed severable and shall not affect the validity and enforceability of any remaining condition.

\n\n \n\n

If we change our policies, we will publish the revised policies online with an updated revision date. We encourage you to review the policies regularly. If we make material changes to our policies that significantly changes our policy practices, we may also notify you in other ways, for example, by sending an e-mail or by posting a notice on our website and/or social media before the changes take effect.

\n\n \n\n

Relating a specific purchase

\n\n

When purchasing a product, you will be asked to accept a version of certain documents as they are at that exact point in time – that version will not be changed after that point in time and will dictate the terms of our relationship with you regarding that exact purchase.

\n \n
\n \n\n
\n

Law and jurisdiction

\n\n

The laws of Denmark and the District Court of Svendborg

\n\n \n\n

SmartResQ/CorPatch® applies Danish law and venue for any legal disputes but not CISG. \n
\nAny dispute relating in any way to your visit to SmartResQ/CorPatch® or to products you purchase through SmartResQ/CorPatch® shall be submitted to confidential in Denmark, except that, to the extent you have in any manner violated or threatened to violate SmartResQ/CorPatch® intellectual property rights, SmartResQ/CorPatch® may seek injunctive or other appropriate relief in any country and you consent to exclusive jurisdiction and venue in such courts.

\n\n \n\n

If the ‘Terms and Conditions’ agreement is breached, legal action will be taken, and a lawsuit may be filed in court.

\n\n

Disputes between us and any consumer is subject to the District Court of Svendborg, Christiansvej 41, 5700 Svendborg, Denmark.

\n\n\n
\n \n \n\n
\n

Contact information

\n\n

Thank you for reading SmartResQ/CorPatch® ‘Terms and Conditions’. \n
\nIf you have any questions, comments, or complaints, please feel free to contact us.

\n\n \n\n

Our company is located at: Lundevej 26, 5700 Svendborg, Denmark

\n\n \n\n

You can find us in the Central Business Register under VAT No. DK 38674102

\n\n \n\n

You can call us on Telephone number +45 62 200 100

\n\n \n\n

or

\n\n

e-mail us at: info@corpatch.com

\n\n \n\n

© SmartResQ ApS – All rights reserved \n
\nDenmark, Version 2.1 – Issued 2023.04.25

\n
\n\n \n \n \n \n \n \n \n\n
\n

SmartResQ / CorPatch® Privacy Policy

\n \n \n

We handle your data in compliance with GDPR

\n\n

SmartResQ/CorPatch® respects your privacy. This privacy statement describes your privacy rights and our commitment to secure your personal information.

\n\n

If you have any questions about our processing of your personal data, please contact us. The data controller is:

\n\n

Company: SmartResQ ApS (CorPatch®)

\n\n

Address:\n
\nLundevej 26 \n
\n5700 Svendborg \n
\nDenmark

\n\n

CVR No.: 38674102

\n\n

Telephone no.: +45 62 200 100

\n\n

E-mail: info@corpatch.com

\n\n

SmartResQ/CorPatch® is a Danish/European company with legal entities, business processes, management structures and technical systems, across national borders. SmartResQ/CorPatch® provides products, software and services to public/private companies in Europe.

\n\n

The head office is located in Denmark and SmartResQ/CorPatch® is subject to European data protection legislation, including the General Data Protection Regulation (GDPR). All major decisions in SmartResQ/CorPatch® concerning the protection of personal data is taken at Management Level under the supervision of the Data Protection Officer.

\n\n

This privacy statement is available on our websites and in our apps.

\n\n

Please do not use SmartResQ/CorPatch® pages, apps or our services if you do not agree to the way we process personal data under this privacy statement.

\n
\n \n \n \n
\n

The type of personal information we collect

\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n

When a handler determines the purposes and means of the processing of your personal data, the handler shall act as the controller. This includes scenarios where SmartResQ/CorPatch® collects personal data in the context of you being a job seeker, a representative of a customer or a lead, or when you are a software user.

\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n

SmartResQ is processing personal information for a variety of purposes, depending on the relationship we have with you.

\n\n

We may process:

\n
    \n
  1. basic contact information, such as name, address, phone number (mobile and/or landline) and e-mail,
  2. \n\n
  3. employment information such as employer, title, position, including preferences and interests in a professional context,
  4. \n\t\t \n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n
  5. feedback, comments or questions about SmartResQ/CorPatch® or our products and services,
  6. \n\n
  7. photos or video recorded at our sites,
  8. \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n
  9. content you have uploaded, such as photos, videos and performance over time,
  10. \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n
  11. unique user information such as login ID, username, password and security question,
  12. \n\t\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n
  13. financial information, where you agree to us using your information e.g. for storing your payment card details,
  14. \n\t\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\n
  15. traffic information provided by your web browser, such as the type of browser, device, language and the address of the website you came from and other traffic information including IP address,
  16. \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\n
  17. clickstream-behaviour and activity on SmartResQ/CorPatch® IDs and in our products and services,
  18. \n\t\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t \n\t\t\t\t\t\t\n\t\t\t\t\n\t\t \n\n
  19. e-mail behaviour, such as e-mail messages from SmartResQ/CorPatch® you open when and how,
  20. \n\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\n
  21. other personal information contained in your profile that you have freely placed on third party social networks, such as LinkedIn, Facebook, Google etc.,
  22. \n\n
  23. information used for scientific purposes to improve survival after cardiac arrest collected via our website(s) and apps,
  24. \n\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n
  25. information about users to deliver products to comply with quality and safety requirements, to provide services to the users, and to maintain and improve our offerings,
  26. \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n
  27. information about job applicants to handle job applications, to communicate about future job offerings and to maintain and improve our recruiting processes,
  28. \n\t\t \n\n
  29. information about persons that have signed up to receive newsletters and other materials to deliver the materials and to maintain and improve our offerings,
  30. \n\t\t\t\t\t \n\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n
  31. cookie information to provide tailored advertising on social media and websites.
  32. \n
\n
\n\n
\n

Data collected and handled in the CorPatch® Services platform and apps

\n\n

SmartResQ handle, collect and store the following personal data when you use CorPatch® Services platform or apps.

\n\n

All users (Institute Admin, Trainer, Trainee/end user)

\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n
    \n
  • First name (if entered)
  • \n\n
  • Last name (if entered)
  • \n\n
  • Nicknames (if entered)
  • \n\n
  • E-mail address (mandatory)
  • \n\n
  • Preferred language of communication (mandatory)
  • \n\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\n
  • Password hash (mandatory)
  • \n\n
  • Whether the e-mail address has been validated (mandatory)
  • \n
\n \n\t\t \n\n

Additionally for trainees/end users (mandatory)

\n\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \n\n

Data on the mobile phone used:

\n\n

Operating system (Android/iOS):

\n
    \n
  • Operating system version (e.g. 9)
  • \n\n
  • Manufacturer (e.g. Samsung)
  • \n\n
  • Model (e.g. SM-T518)
  • \n\n
  • App version (e.g. 1.2.4)
  • \n\n
  • Time of the last foreground activity of the app
  • \n\n
  • Time of the last background activity of the app
  • \n
\n\n

Data on the CorPatch® (CPS) used:

\n
    \n
  • Serial number/MAC address
  • \n\n
  • Firmware version
  • \n\n
  • Model name (e.g. CPS_01)
  • \n\n
  • Manufacturer (currently always SRQ)
  • \n\n
  • Name (currently always CorPatch®)
  • \n\n
  • Battery condition
  • \n\n
  • Defects
  • \n
\n \n\n

User onboarding data:

\n
    \n
  • Tutorial completed (yes/no)
  • \n\n
  • Terms of use accepted (yes/no)
  • \n\n
  • Self-assessment completed (yes/no)
  • \n\n
  • Test training completed (yes/no)
  • \n\n
  • First login successful (yes/no)
  • \n\n
  • Was a CPS connected (yes/no)
  • \n
\n \n\n

Data collected through training:

\n
    \n
  • Date, time, and length of the training
  • \n\n
  • Training result
  • \n\n
  • Training type or training settings
  • \n\n
  • In case of a training within an institute, additional information about the course, trainer, and institute
  • \n
\n \n \n\n

Server logs

\n\n

The following data is stored in the web server logs:

\n
    \n
  • IP address of the accessing party
  • \n\n
  • Browser version of the accessing party
  • \n\n
  • Date/time of access
  • \n\n
  • URL of access
  • \n
\n

External services that process data:

\n
    \n
  • Google/Firebase for remote logging, crash and error analysis
  • \n\n
  • Google/Firebase for sending notifications
  • \n\n
  • Sendgrid for sending e-mails
  • \n\n
  • Hetzner Online GmbH for hosting web backend and database
  • \n
\n \n\n

What happens when a user is deleted

\n
    \n
  • The user deletes himself/herself from our system on the CorPatch® Services homepage https://app.corpatch.com.
  • \n\n
  • The user is marked as deleted. After that he can no longer log in, is no longer visible for admins, etc. but the user still exists in the database.
  • \n\n
  • After 14 days the user’s data is automatically deleted from the database.
  • \n\n
  • For the purpose of scientific evaluation and functionality improvement, data of trainings and use of CorPatch® will still exist in the database after deletion of the user, but the reference (the ID) to the user will be empty, and all references to personal data will be removed.
  • \n
\n
\n\n
\n

How we collect your personal information

\n\n

Most of the personal information we process is provided to us directly by you. We collect data and process data when you:

\n
    \n
  • register online or place an order for any of our products or services; e.g. demographic data, e-mail address, payment information, items, order amount, discount level and frequency. Including sending transactional e-mails, e.g. order confirmation, shipping confirmation and refund confirmation,
  • \n\n
  • engage in the sent communication (e-mail, SMS, direct mail or phone); e.g. open rate, click rate and time spend reading the e-mails, sender domain and type of e-mail client,
  • \n\n
  • voluntarily complete a customer survey or provide feedback on any of our message boards or via e-mail.
  • \n
\n \n\n

We might also receive personal information indirectly, from the following sources in the following scenarios:

\n
    \n
  • From cookies: when you visit our websites or apps; e.g. IP address, country, viewed pages, viewed products, interaction/clicks and searches.
  • \n\n
  • From you or any other person affiliated with our customer. These people can be a manager or a colleague. If the customer you are working for buys products or services from SmartResQ/CorPatch® through a partner company to SmartResQ/CorPatch®, we may collect information about you from the partner company.
  • \n\n
  • SmartResQ/CorPatch® Marketing partners, public sources or social networks of third parties.
  • \n\n
  • SmartResQ/CorPatch® will be able to combine personal data about you collected from one source with information obtained from another source. This gives us a more complete picture of you, which also allows us to serve you in a more relevant way with a higher level of personalization.
  • \n
\n
\n\n\n
\n

How we use your data

\n\n

In order to generally manage our customer relationships and to meet our customer commitments, SmartResQ/CorPatch® needs information about you in your role as a customer or when you use a service. The purposes of processing such personal data are:

\n
    \n
  • Process your order, manage your account,
  • \n
  • e-mail you with special offers on other products and services we think you might like,
  • \n\n
  • performing the sales and contract process for customers,
  • \n\n
  • to deliver the requested products and services to customers,
  • \n\n
  • to conduct deliveries in accordance with agreements concluded with you or customers,
  • \n\n
  • to offer support to users of our products and services,
  • \n\n
  • improve and develop the quality, functionality and user experience of our products, services and SmartResQ/CorPatch® website(s) and apps,
  • \n\n
  • detect, limit, and prevent security threats and perform maintenance and troubleshooting and debugging,
  • \n\n
  • preventing the misuse of our products and services,
  • \n\n
  • to process orders, invoicing, payments or another financial follow-up,
  • \n\n
  • create interest profiles to promote relevant products and services,
  • \n\n
  • to establish user communities to educate and to facilitate interaction between users and SmartResQ/CorPatch®.
  • \n
\n \n\n

About leads

\n\n

SmartResQ/CorPatch® processes personal data on leads for marketing purposes. In order to provide targeted and relevant content to prospective customers, SmartResQ/CorPatch® builds an interest profile based on your activity and your choices and actions on SmartResQ/CorPatch® pages, as well as your response to marketing content. The legal basis for such processing is primarily your consent.

\n\n

About jobseekers

\n\n

If you are an applicant for jobs, we process personal data to evaluate your potential as a SmartResQ/CorPatch® employee. Our secure, online career platform ensures that we comply with the latest laws and regulations in relation to data privacy. The legal basis for such processing is your consent.

\n\n

About website visitors

\n\n

In order to monitor access to our sites, we process personal information about visitors. The processing is based on our legitimate interest in protecting our business secrets, employees, locations and you as a visitor. You will be informed of your rights in this context when you register with our electronic system for visitors.

\n\n

To improve quality of CPR, especially through CPR training, SmartResQ/CorPatch® might share your data with our partner companies (Training Institutes) so that they may offer you their products and services.

\n\n

When we process your order, our system may send your data to, and also use the resulting information from, credit reference agencies to prevent fraudulent purchases.

\n
\n\n
\n

How we store your personal information

\n\n

SmartResQ/CorPatch® takes the trust you and our customers show us very seriously. SmartResQ/CorPatch® undertakes to avoid unauthorized access, disclosure or other aberrant processing of personal data. SmartResQ/CorPatch® shall ensure the confidentiality of the personal data we process, maintain the integrity of personal data and ensure its accessibility in accordance with applicable privacy laws.

\n\n

As part of our commitments, we take reasonable and adequate organizational, technical and physical procedures and measures to protect the information we collect and process. We are taking into account the type of personal data and the risk that our customers are exposed to by any security breach, as there is a high likelihood that the root causes of personal data breaches can be found internally, we believe that the building of a strong corporate culture in which respect and vigilance about data protection among our employees is fundamental to ensuring the legal processing and protection of your information. In case of a data breach, SmartResQ/CorPatch® will follow practices laid out by the Danish Datatilsynet.

\n\n

Your information is securely stored according to GDPR regulations.

\n
\n\n
\n

How long do we keep your personal data?

\n\n

SmartResQ/CorPatch® retains your personal data only for as long as it is necessary for the purposes stated, while taking into account our need to respond to queries and resolve issues and comply with legal requirements under applicable law.

\n\n

This means that SmartResQ/CorPatch® may store your personal information for a reasonable period after your and our customer’s last interaction with us. When the personal data we have collected is no longer necessary, we delete it. We may process data for statistical and/or scientific purposes, but in such cases the data will be pseudonymized or anonymized.

\n\n \n \n\n

Time frame for data storage

\n\n

We will retain your personal information for the period necessary to fulfil the purposes outlined in these Privacy Policy unless a longer retention period is required or permitted by law, for legal, tax or regulatory reasons or other legitimate and lawful business purposes.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Purpose Time frame
Customer service and accounting regulation 5 years or as long as we are obligated to meet the needed legal requirement.\n
\nWe delete your registration data as soon as you delete your user account with us, or once the statutory retention period expires. \n
Career platform 6 months for application documents that do not result in hiring of the job applicant.\n
\nRenewal each 6 months if you wish to be considered for future job openings and you consent to longer storage period. \n
Marketing purpose 3 years after your latest activity e.g. visit on our websites, purchase or engagement in communication.\n
\nIf you have given your marketing permission (e-mail, SMS, phone etc.) and as long as we have your permission to contact you. \n
\nWe delete your e-mail address in newsletter automatically, once you delete your user account or if you unsubscribe from our newsletter. \n
Storage of order history and obligations to fulfil orders 5 years or as long as we are obligated to meet the needed legal requirements
Customer experience 3 years after your latest activity e.g. visit on our websites, purchase or engagement in communication.\n
\nIf you have given your marketing permission (e-mail, SMS, phone etc) and as long as we have your permission.\n
Fraud risk assessment 5 years or as long as we are obligated to meet the needed legal requirement.
\n
\n \n \n\n
\n

Marketing communications

\n\n

You have the right to opt out of receiving marketing communications from SmartResQ/CorPatch® and can do it either by:

\n
    \n
  • following the opt-out instructions in the relevant marketing communications,
  • \n\n
  • changing preferences under the relevant editing section for the account, if you have an account with SmartResQ/CorPatch®,
  • \n\n
  • contacting us by e-mail at info@corpatch.com.
  • \n
\n \n\n

Please note that even if you opt out of receiving marketing communications, you may still receive administrative messages from SmartResQ/CorPatch®, such as order confirmations and notices necessary to manage your account or the services provided to our customers through e.g. mobile services or apps.

\n
\n\n
\n

Your data protection rights

\n\n

It is important for SmartResQ/CorPatch® that you are fully aware of all your data protection rights.

\n\n

Some data protection laws, including the European Union’s General Data Protection Regulation (GDPR), corresponding legislation in Germany Bundesdatenschutzgesetz (BDSG), in Switzerland and in the United Kingdom, and some U.S. state laws, provide you with certain rights in connection with personal data you have shared with us. If you are a resident in the European Economic Area, you may have the following rights:

\n
    \n
  1. Your right of access – You have the right to ask us for copies of your personal information.
  2. \n\n
  3. Your right to rectification – You have the right to request that we correct any personal information you believe is inaccurate. You also have the right to request us to complete information you believe is incomplete.
  4. \n\n
  5. Your right to erasure – You have the right to request us to erase your personal information under certain conditions.
  6. \n\n
  7. Your right to restrict processing – You have the right to request us to restrict the processing of your personal information under certain conditions.
  8. \n\n
  9. Your right to object to processing – You have the right to object to the processing of your personal information under certain conditions.
  10. \n\n
  11. Your right to data portability – You have the right to request that we transfer the personal information that we have collected to another organisation, or directly to you under certain conditions.
  12. \n
\n \n\n

If you would like to exercise any of these rights, please contact us at our e-mail info@corpatch.com.

\n
\n\n
\n

What are cookies?

\n\n

Cookies are small text files that contain a character string and create a unique identifier for a user. They are returned to the website and/or third parties. Most browsers are initially set up to accept cookies, since most websites are required to access them. However, you can change your browser settings so that your browser can generally reject cookies, block third-party cookies or specify when a cookie is being sent.

\n \n \n\n

SmartResQ/CorPatch® is committed to ensuring your right to adjust your interests and to manage the scope of digital marketing from us through a system of preferential management.

\n
\n\n
\n

How we use cookies

\n\n

SmartResQ/CorPatch® uses cookies in a range of ways to improve your experience on our websites, apps and services for different reasons e.g.:

\n
    \n
  • Functionality – we use these cookies to recognize you on our website and remember your previously selected preferences. These would include that language you prefer and location you are in. A mix of first-party and third-party cookies are used.
  • \n\n
  • Advertising – we use these cookies to collect information about your visit to our websites, app(s), the content you viewed, the links you followed and information about your browser, device and your IP address. Sometimes we share some limited aspects of this data with third parties for advertising purposes. We may also share online data collected through cookies with our advertising partners. This means that when you visit another website, you may be shown advertising based on your browsing patterns on our website.
  • \n
\n
\n\n
\n

The type of cookies we use

\n\n

Our website(s) use the following types of cookies:

\n
    \n
  • Google Analytics: This cookie allows us to view information about website activities for users, including but not limited to page views, source, and time spent on a website. The information is anonymized and is displayed as numbers, which means that it cannot be traced back to individuals. This helps protect your privacy. By using Google Analytics, we can see what content is popular on our pages, and we strive to give you more of what you like to read and see.
  • \n\n
  • Google Analytics remarketing: Places cookies on your computer, which means that when you leave our site, Google may show you ads about SmartResQ/CorPatch® that you may be interested in based on your previous behavior on our website. This information is not personally identifiable.
  • \n\n
  • Google Ads: By using Google Ads, we are able to see which pages were helpful in leading to submissions via our contact form. This information is not personally identifiable, but the data provided in the contact form is.
  • \n\n
  • Google Ads remarketing: Places cookies on your computer, which means that when you leave our site, Google may show you ads about SmartResQ/CorPatch® that you may be interested in based on your previous behavior on our website. This information is not personally identifiable.
  • \n\n
  • Facebook remarketing: Facebook’s tracking pixel places cookies on your computer that tell Facebook that you’ve checked the site. We then assume that you have an interest in SmartResQ/CorPatch® and the content on this site. When you visit Facebook, you will then be exposed to information or advertisements with similar content. Please use your privacy settings on Facebook to limit the exposure to marketing of this type.
  • \n\n
  • YouTube: We integrate videos from the YouTube platform provided by Google (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA). Privacy policy: https://www.google.com/policies/privacy/.
  • \n
\n
\n \n \n\n
\n

How to manage cookies

\n\n

You can set your browser not to accept or to delete cookies. However, some of our website features may not function as a result. See how to avoid cookies in specific browsers:

\n\n \n\n

SmartResQ/CorPatch® uses some trusted third-party services on our pages. These services might use cookies. You can choose to reject third-party cookies in your browser by following this link.

\n\n

You may prevent the information generated by the Google cookie about your use of our sites from being collected and processed by Google by downloading and installing the Google Analytics opt-out browser add-on for your current web browser. This add-on is available here.

\n
\n\n
\n

Privacy policies of other websites

\n\n

SmartResQ/CorPatch® websites contain links to other websites. Our privacy policy applies only to our website, so if you click on a link to another website, you should read their privacy policy.

\n
\n\n
\n

Changes to our privacy policy

\n\n

If we change our privacy statement, we will publish the revised statement here with an updated revision date. We encourage you to review the statement regularly. If we make material changes to our statement that significantly changes our privacy practices, we may also notify you in other ways, for example, by sending an e-mail or by posting a notice on our website and/or social media before the changes take effect.

\n
\n\n
\n

How to contact SmartResQ ApS

\n\n

If you have any questions about SmartResQ/CorPatch® privacy policy, the data we hold on you, or you would like to exercise one of your data protection rights, please do not hesitate to contact us.

\n\n

E-mail: info@corpatch.com

\n\n

Website: https://corpatch.com

\n\n
\n\n\n
\n

How to contact the appropriate authority

\n\n

Should you wish to report a complaint or if you feel that SmartResQ/CorPatch® has not addressed your concern in a satisfactory manner, you may contact the Information Commissioner’s Office (ICO).

\n\n

The ICO’s address: \n

\nInformation Commissioner’s Office \n
\nWycliffe House \n
\nWater Lane \n
\nWilmslow \n
\nCheshire \n
\nSK9 5AF

\n\n \n\n

Helpline number: +44 303 123 1113

\n\n

ICO website: https://www.ico.org.uk

\n\n

© SmartResQ ApS – All rights reserved \n
\nDenmark, Version 1.3 – Issued 2023.04.25

\n\n
\n
\n\n`\n\nexport const termsOfUse_de_DE: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n\n
\n\n \n \n \n
\n

Allgemeine Geschäftsbedingungen & Datenschutzrichtlinie

\n

SmartResQ ApS / CorPatch®

\n
\n\n
\n

Allgemeine Geschäftsbedingungen – SmartResQ ApS / CorPatch®

\n\n

Zweck dieses Dokuments

\n\n

Willkommen bei SmartResQ/CorPatch®!

\n\n \n\n

Du liest gerade unsere Allgemeinen Geschäftsbedingungen; ein Dokument mit Informationen über deine Beziehung zu SmartResQ ApS, die begonnen hat, als du unsere Website besucht, unsere kostenlose(n) App(s) heruntergeladen, eines unserer Produkte gekauft oder ähnliches getan hast.

\n\n \n\n

SmartResQ/CorPatch® und unsere Partner stellen dir unsere Produkte und Dienstleistungen zu den folgenden Bedingungen zur Verfügung. Wenn du unsere Website(s) oder App(s) nutzt oder dort einkaufst, akzeptierst du diese Bedingungen. Wir empfehlen dir dringend, sie sorgfältig zu lesen, bevor du unsere Produkte oder Dienstleistungen nutzt.

\n\n \n\n

Dieses Dokument umfasst:

\n
    \n
  • Wie du SmartResQ kontaktierst
  • \n\n
  • Produkte, Eigenschaften und ordnungsgemäße Nutzung
  • \n\n
  • Haftungsausschlüsse und Garantien
  • \n\n
  • Bestellung
  • \n\n
  • Zahlung
  • \n\n
  • Lieferung
  • \n\n
  • Verantwortlichkeiten und Rechte in Bezug auf den Verkauf
  • \n\n
  • Rücksendungen
  • \n\n
  • Datenverarbeitung persönlicher Daten
  • \n\n
  • Beschwerden
  • \n\n
  • Änderungen an diesem Dokument
  • \n\n
  • Recht und Gerichtsbarkeit
  • \n\n
  • Kontaktinformationen
  • \n\n \n
\n

Wenn du Fragen zu den Allgemeinen Geschäftsbedingungen von SmartResQ hast, kontaktiere uns bitte.

\n\n \n\n

Wie du SmartResQ kontaktierst

\n\n

Das Ziel von SmartResQ ist es, die Überlebenschancen von Menschen mit Herzstillstand durch qualifizierte HLW zu erhöhen. Wir wollen Umstehende darauf vorbereiten und anleiten, in den ersten Minuten nach einem Herzstillstand zu handeln. Deshalb haben wir CorPatch® entwickelt – Wir helfen dir, um ein Leben zu retten.

\n\n \n\n

Unser Unternehmen befindet sich in Lundevej 26, 5700 Svendborg, Dänemark

\n\n \n\n

Du findest uns im Zentralen Unternehmensregister unter der Umsatzsteuernummer DK 38674102

\n\n \n\n

Du kannst uns anrufen unter der Telefonnummer +45 62 200 100

\n\n \n\n

oder

\n\n \n\n

schreib uns eine E-Mail an: info@corpatch.com.

\n\n \n\n

Hast du Fragen, Kommentare oder Beschwerden?

\n\n

Wir freuen uns über deine Meinung, also kontaktiere uns bitte über die oben genannten Kontaktinformationen oder benutze das Kontaktformular auf unserer/unseren Website(s) oder App(s).

\n\n \n
\n\n\n
\n

Produkte, Eigenschaften und ordnungsgemäße Nutzung

\n\n

Unsere Website(s), Apps und Produkte

\n\n

Die folgenden Abschnitte beschreiben wesentliche Eigenschaften, Rechte und Pflichten im Zusammenhang mit der Nutzung der Dienste, Apps und Produkte von SmartResQ/CorPatch®. \n
\nWir bemühen uns nach Kräften, auf der/den Website(s) und in den Apps genaue und aktuelle Informationen bereitzustellen. SmartResQ/CorPatch® gibt jedoch keine Garantien oder Zusicherungen hinsichtlich der Richtigkeit der Informationen. Wir übernehmen keine Haftung oder Verantwortung für Fehler oder Auslassungen in den Inhalten der Website, Produkte und Apps. Die auf dieser Website oder in den Apps bereitgestellten Informationen sind kein Ersatz für eine medizinische Versorgung. Wir übernehmen die Verantwortung für unsere Produkte und Apps gemäß der Medizinprodukterichtlinie EU 745/2017 (MDR).

\n\n \n\n

Copyright

\n\n

Alle auf dieser Website enthaltenen Inhalte wie Texte, Grafiken, Logos, Schaltflächensymbole, Bilder, Audioclips, digitale Downloads, Datenzusammenstellungen und Software sind das Eigentum von SmartResQ/CorPatch® oder deren Inhaltslieferanten und durch internationale Urheberrechtsgesetze geschützt. Die Zusammenstellung aller Inhalte auf dieser Seite ist das ausschließliche Eigentum von SmartResQ/CorPatch®, wobei die Urheberschaft für diese Sammlung bei SmartResQ/CorPatch® liegt und durch internationale Urheberrechtsgesetze geschützt ist.

\n\n \n\n

Eingetragene Marken und Design

\n\n

SmartResQ/CorPatch® Marken, Handelsaufmachungen und Produktdesigns dürfen nicht in Verbindung mit einem Produkt oder einer Dienstleistung verwendet werden, die nicht von SmartResQ/CorPatch® stammt, oder in einer Weise, die bei den Kunden zu Verwechslungen führen kann oder SmartResQ/CorPatch® in Verruf bringt oder diskreditiert. Alle anderen Marken, die nicht im Besitz von SmartResQ/CorPatch® oder seinen Tochtergesellschaften sind und auf dieser Seite erscheinen, sind das Eigentum ihrer jeweiligen Besitzer, die mit SmartResQ/CorPatch® oder seinen Tochtergesellschaften verbunden sind oder von ihnen gesponsert werden können.

\n\n \n\n

Lizenz und Zugang zur Website

\n\n

SmartResQ/CorPatch® gewährt dir eine eingeschränkte Lizenz für den Zugriff und die persönliche Nutzung unserer Website(s) und Apps. Du darfst die Website oder Teile davon nicht herunterladen (außer zum Zwischenspeichern von Seiten) oder verändern, es sei denn, du hast die ausdrückliche schriftliche Genehmigung von SmartResQ/CorPatch®. Diese Lizenz umfasst nicht den Weiterverkauf oder die kommerzielle Nutzung dieser Website(s) oder Apps oder ihrer Inhalte: (a) jede Sammlung und Nutzung von Produktlisten, Beschreibungen oder Preisen: (b) jede abgeleitete Nutzung dieser Seite oder ihrer Inhalte: (c) jegliches Herunterladen oder Kopieren von Kontoinformationen zum Nutzen eines anderen Händlers: oder (d) jegliche Nutzung von Data Mining, Robotern oder ähnlichen Tools zur Datensammlung und -extraktion.

\n\n \n\n

Diese Website oder App oder Teile davon dürfen ohne ausdrückliche schriftliche Zustimmung von SmartResQ/CorPatch® nicht reproduziert, nachgebaut, vervielfältigt, kopiert, verkauft, weiterverkauft, besucht oder anderweitig für kommerzielle Zwecke genutzt werden. Du darfst ohne ausdrückliche schriftliche Zustimmung von SmartResQ/CorPatch® und unseren Partnern keine Framing-Techniken verwenden, um Marken, Logos oder andere urheberrechtlich geschützte Informationen (einschließlich Bilder, Text, Seitenlayout oder Form) einzubinden.

\n\n \n\n

Du darfst ohne die ausdrückliche schriftliche Zustimmung von SmartResQ/CorPatch® keine Meta-Tags oder anderen „versteckten Text“ verwenden, der den Namen oder die Marken von SmartResQ/CorPatch® nutzt. Jede unbefugte Nutzung beendet die von SmartResQ/CorPatch® erteilte Erlaubnis oder Lizenz.

\n\n \n\n

Dir wird ein begrenztes, widerrufliches und nicht-exklusives Recht gewährt, einen Hyperlink zur Homepage von SmartResQ/CorPatch® zu erstellen, solange der Link SmartResQ/CorPatch®, seine Partner oder deren Produkte oder Dienstleistungen nicht in einer falschen, irreführenden, abwertenden oder anderweitig anstößigen Weise darstellt. Du darfst ohne ausdrückliche schriftliche Genehmigung kein SmartResQ/CorPatch® Logo oder eine andere geschützte Grafik oder Marke als Teil des Links verwenden. \n
\nBei einem Verstoß gegen die Vereinbarung über die Lizenz und den Website-Zugang werden rechtliche Schritte eingeleitet, und es kann eine Klage vor Gericht eingereicht werden.

\n\n

Elektronische Kommunikation

\n\n

Wenn du die Homepage und die Social-Media-Kanäle von SmartResQ/CorPatch® besuchst oder E-Mails an uns schickst, kommunizierst du elektronisch mit uns. Du erklärst dich damit einverstanden, dass wir dir auf elektronischem Wege Nachrichten zusenden. Wir kommunizieren mit dir per E-Mail oder durch Hinweise auf unseren Websites oder in den Apps in Form von Pop-ups oder Benachrichtigungen. Du erklärst dich damit einverstanden, dass alle Vereinbarungen, Mitteilungen, Bekanntmachungen und andere Kommunikationen, die wir dir elektronisch zukommen lassen, alle gesetzlichen Anforderungen an die Schriftform erfüllen. Unsere Datenschutzrichtlinie findest du in einem separaten Dokument auf unserer Homepage.

\n\n \n\n

Besucher unserer Website und unserer Social-Media-Kanäle können Bewertungen, Kommentare und andere Inhalte, z. B. Vorschläge, Ideen, Kommentare, Fragen oder andere Informationen einreichen, solange der Inhalt nicht illegal, obszön, bedrohlich, verleumderisch, die Privatsphäre verletzend, geistige Eigentumsrechte verletzend oder anderweitig Dritten gegenüber verletzend oder anstößig ist und nicht aus Software-Viren, politischen Kampagnen, kommerzieller Werbung, Kettenbriefen, Massenmailings oder irgendeiner Form von „Spam“ besteht oder diese enthält.

\n\n \n\n

Du darfst keine falsche E-Mail-Adresse verwenden, dich als eine andere Person oder Organisation ausgeben oder auf andere Weise über die Herkunft einer Karte oder anderer Inhalte täuschen. SmartResQ/CorPatch® behält sich das Recht (aber nicht die Pflicht) vor, solche Inhalte zu entfernen oder zu bearbeiten, überprüft aber nicht regelmäßig die eingestellten Inhalte. Wenn du Inhalte einstellst oder Inhalte einreichst, gewährst du SmartResQ/CorPatch® und seinen Partnern ein nicht-exklusives, lizenzfreies, unbefristetes, unwiderrufliches und vollständig unterlizenzierbares Recht, diese Inhalte weltweit in allen Medien zu nutzen, zu vervielfältigen, zu verändern, anzupassen, zu veröffentlichen, zu übersetzen, davon abgeleitete Werke zu erstellen, zu verbreiten und darzustellen, sofern wir nichts anderes angeben. Du gewährst SmartResQ/CorPatch® und seinen Partnern und Unterlizenznehmern das Recht, den Namen, den du in Verbindung mit solchen Inhalten einreichst, zu verwenden, wenn sie dies wünschen.

\n\n \n\n

Du erklärst und garantierst, dass du alle Rechte an dem von dir eingestellten Inhalt besitzt oder anderweitig kontrollierst; dass der Inhalt korrekt ist; dass die Verwendung des von dir bereitgestellten Inhalts nicht gegen diese Richtlinie verstößt und keine Personen oder Unternehmen verletzt; und dass du SmartResQ/CorPatch® oder seine Partner für alle Ansprüche, die sich aus dem von dir bereitgestellten Inhalt ergeben, schadlos halten wirst. SmartResQ/CorPatch® hat das Recht, aber nicht die Pflicht, jegliche Aktivitäten oder Inhalte zu überwachen und zu bearbeiten oder zu entfernen. SmartResQ/CorPatch® übernimmt keine Verantwortung und keine Haftung für Inhalte, die von dir oder einer dritten Partei eingestellt werden.

\n\n \n
\n\n
\n

Haftungsausschlüsse und Garantien

\n\n

Produktinformation – CorPatch® und CorPatch® Trainer

\n\n

Für die korrekte Nutzung eines Produkts oder Dienstes von SmartResQ/CorPatch® musst du immer die aktuellen Benutzerhandbücher, Anweisungen und Beschreibungen beachten. Diese findest du auf unserer Website und unter jeder Produktbeschreibung.

\n\n \n\n

Das Produkt CorPatch® ist als Medizinprodukt zertifiziert. Bei einem Notfall mit einer erwachsenen Person, die einen Herzstillstand erleidet, muss das Produkt aus seinem Gehäuse genommen und korrekt auf der Brust des Opfers platziert und befestigt werden. Das Produkt kann Daten über Kompression, Tiefe, Frequenz und Rückstoß sammeln und diese möglicherweise über Bluetooth® an mögliche Geräte übertragen. Kostenlose Apps auf den Geräten können den Umstehenden bei der Durchführung der HLW anleiten und Flow-Anteil, Tiefe, Rückstoß und Frequenz anzeigen, wenn sie aktiviert und richtig installiert sind, d. h. Bluetooth®, Smartphone, App, Batteriestrom usw. SmartResQ/CorPatch® ist nicht verantwortlich für externe Faktoren, z. B. gestörte Kommunikationssignale, mangelnde Datenabdeckung, fehlende Batterie, falsche Hardware- oder Softwareeinstellungen, die das Benutzererlebnis beeinträchtigen können oder ähnliches.

\n\n \n\n

Ebenso ist SmartResQ/CorPatch® nicht für körperliche Schäden verantwortlich, die während der Verwendung des Produkts entstehen, wenn es nicht gemäß den Anweisungen angewendet oder benutzt wird, z. B. wenn du die Herzdruckmassage nicht ergonomisch durchführst oder eine ungeeignete Handhaltung einnimmst. SmartResQ/CorPatch® hat die technischen Risiken im Rahmen des gesetzlich vorgeschriebenen Risikomanagements für Medizinprodukte bewertet, übernimmt aber keine Garantie für darüber hinausgehende Fehler. Bei unerwarteten Fehlfunktionen oder nicht plausiblem Verhalten eines SmartResQ/CorPatch® Systems muss der Benutzer die HLW manuell durchführen. In diesem Fall ist SmartResQ/CorPatch® nicht haftbar, da dies außerhalb der Kontrolle von SmartResQ/CorPatch® liegt.

\n\n

SmartResQ/CorPatch® überwacht den Batteriestand und den Gesundheitszustand, aber wenn die Batterie leer ist, funktioniert das Produkt nicht. Es liegt in der alleinigen Verantwortung des Benutzers, dafür zu sorgen, dass das Gerät auf dem neuesten Stand ist, nicht beschädigt wird und über genügend Batterie verfügt, um korrekt zu funktionieren. Dies kann ganz einfach durch ein Training geschehen, das die korrekte Funktionsweise bestätigt. Wir empfehlen, alle 3 Monate ein 4-minütiges Training mit deinem CorPatch® durchzuführen.

\n\n \n\n

Wichtig! Das Produkt CorPatch® darf ausschließlich an einer Person in einer realen Situation und nur dann verwendet werden, wenn eine Person einen Herzstillstand erleidet. Es darf nicht bei Personen verwendet werden, die z. B. an einem Schlaganfall, Herzinfarkt oder anderen gesundheitlichen Erkrankungen leiden, die nicht mit einem Herzstillstand einhergehen. Der CorPatch® darf nicht verwendet werden, wenn die Person auf einer weichen Oberfläche liegt, z. B. auf einer Couch oder einem Bett, da die Tiefenrückmeldung unter solchen Bedingungen ungenau sein könnte. Die SmartResQ/CorPatch® Lösungen sind nicht für die Verwendung in einer sich bewegenden Umgebung vorgesehen, z. B. in einem Krankentransport in der Luft, auf dem Wasser oder auf der Straße. Wenn das Gerät während des Patiententransports verwendet oder während der HLW vom Körper gehoben/entfernt wird, kann es ungenaue Rückmeldungen geben. Der CorPatch® muss mit dem Patch auf der Brust des Patienten/der Patientin befestigt werden. Vergewissere dich, dass der Patient/die Patientin auf einer festen, ebenen und unbeweglichen Unterlage liegt und dass das CorPatch® mit dem Patch auf dem Brustkorb befestigt ist.

\n\n \n\n

Das Produkt CorPatch® Trainer darf ausschließlich an Übungspuppen oder ähnlichen Objekten in Training Sessions verwendet werden und niemals in einer realen Situation an einer echten Person, die einen Herzstillstand oder eine andere gesundheitsbezogene Krankheit hat.

\n\n \n\n

Mit dem CorPatch® Trainer kannst du deine HLW-Leistung in Bezug auf Herzdruckmassagen regelmäßig trainieren. Wir empfehlen dir, an einer Übungspuppe zu trainieren. Wenn du jedoch keinen Zugang zu einer Übungspuppe hast, kann ein Bürostuhl mit ausreichendem Rückstoß oder eine harte Liege als Ersatz verwendet werden. Achte auf die Elastizität und Härte des Objekts, mit dem du trainierst. SmartResQ rät davon ab, weiche Gegenstände, wie z. B. Kissen oder weiche Sofas, für das Training zu verwenden, da der/die Benutzer/in dann nicht die richtige Erfahrung macht.

\n\n\n

Wenn du keine Übungspuppe oder keinen Ersatzgegenstand für das Training finden kannst, solltest du die Situation trainieren, die eintritt, bevor du mit der Herzdruckmassage beginnst. Das könnte das Befolgen der Informationen der kostenlosen App zur Erkennung eines Herzstillstands und zum Absetzen eines Notrufs und das Auspacken des CorPatch® aus dem Schlüsselanhänger sein. In diesem Fall bist du bereit, den CorPatch® schnell anzuwenden, falls du Zeuge eines Herzstillstands wirst.

\n\n \n\n

Verwende das SmartResQ/CorPatch® System nicht zum Training oder „zum Spaß“ an Personen (lebend oder tot), Haustieren oder anderen Lebewesen.

\n\n \n\n

Haftungsausschluss für Produkte, Website(s) und Apps

\n\n

SmartResQ/CorPatch® gibt keine Zusicherungen oder Garantien ab und ist nicht verantwortlich für die Kompetenz einer Person, die durch das System oder auf der Grundlage des Systems pädagogische Informationen und/oder medizinisches Training erhält, oder für die Ausübung ihrer Fähigkeiten durch diese Person nach Abschluss eines Trainings, Kurses oder Lehrplans unter Verwendung des Systems. SmartResQ/CorPatch® garantiert nicht, dass eine Person, die Bildungsinformationen und/oder medizinisches Training aus dem System erhält, ein bestimmtes Fähigkeitsniveau oder die notwendigen Fähigkeiten erreicht, um sich für eine Lizenz, ein Zertifikat oder eine Bewertung zu qualifizieren, die von einer Aufsichtsbehörde oder einer Regierungsbehörde ausgestellt werden.

\n\n \n\n

SmartResQ/CorPatch® und seine Mitarbeiter/innen versuchen, so genau wie möglich zu sein. SmartResQ/CorPatch® übernimmt jedoch keine Gewähr dafür, dass das System und die darin enthaltenen Informationen, Produkte und Trainings: (a) immer oder überhaupt verfügbar sind; oder (b) fehlerfrei, vollständig, genau, wahrheitsgemäß, aktuell und/oder nicht irreführend sind. Wenn du das System benutzt, ist dir bewusst, dass du auf jegliche Ansprüche gegenüber SmartResQ/CorPatch® verzichtest, die sich aus dem Vertrauen auf die über das System bereitgestellten Informationen oder Trainings ergeben könnten.

\n\n \n\n

Unsere Produkte sind nicht für die Verwendung durch Kinder gedacht. Die Produkte sind klein und bunt und können mit Spielzeug verwechselt werden, aber SmartResQ/CorPatch® Produkte sind kein Spielzeug! Wir empfehlen, die Produkte nicht im Freien und für Kinder unzugänglich aufzubewahren. SmartResQ/CorPatch® übernimmt keine Verantwortung in Bezug auf die Verwendung der Produkte durch Kinder. Jegliche Nutzung von CorPatch® durch Kinder oder Jugendliche muss von verantwortlichen Erwachsenen, z. B. Eltern, Familienmitgliedern oder Lehrern, erlaubt und überwacht werden.

\n\n \n\n

Haftungsausschluss und Haftungsbeschränkung, diese Seite wird von SmartResQ/CorPatch® auf einer „wie besehen“ und „wie verfügbar“ Basis bereitgestellt. SmartResQ/CorPatch® gibt keine ausdrücklichen oder stillschweigenden Zusicherungen oder Gewährleistungen in Bezug auf den Betrieb dieser Seite oder die Informationen, Material, Inhalte oder Produkte auf dieser Seite. Du erklärst dich ausdrücklich damit einverstanden, dass die Nutzung dieser Seite auf dein eigenes Risiko erfolgt. \n
\nSmartResQ/CorPatch® lehnt, soweit dies nach geltendem Recht zulässig ist, alle ausdrücklichen oder stillschweigenden Garantien ab, einschließlich, aber nicht beschränkt auf stillschweigende Garantien der Marktgängigkeit und der Eignung für einen bestimmten Zweck. SmartResQ/CorPatch® garantiert nicht, dass diese Seite, ihre Server oder von SmartResQ/CorPatch® versandte E-Mails frei von Viren/Spam oder anderen schädlichen Komponenten sind.

\n\n \n\n

SmartResQ/CorPatch® ist nicht haftbar für Schäden jeglicher Art, die aus der Nutzung dieser Seite oder ihrer Produkte entstehen, einschließlich, aber nicht beschränkt auf direkte, indirekte, zufällige, strafende und Folgeschäden. \n
\nIn einigen Staaten sind Beschränkungen von stillschweigenden Garantien oder der Ausschluss oder die Beschränkung bestimmter Schäden nicht zulässig. Wenn diese Gesetze auf dich zutreffen, gelten einige oder alle der oben genannten Haftungsausschlüsse oder Beschränkungen möglicherweise nicht für dich, und du hast möglicherweise zusätzliche Rechte.

\n\n \n\n

Die auf dieser Website enthaltenen Informationen sind nicht als professionelle Beratung zu verstehen. Bevor du eine Entscheidung triffst, solltest du immer professionellen Rat von einer Person einholen, die mit deiner tatsächlichen Situation vertraut ist, um dich in bestimmten Angelegenheiten beraten zu lassen.

\n\n \n\n

Die Website kann Links enthalten, die zu Websites führen, die von Personen oder Organisationen unterhalten werden, über die SmartResQ/CorPatch® keine Kontrolle hat. SmartResQ/CorPatch® gibt keine Zusicherungen und Garantien in Bezug auf die Richtigkeit oder andere Aspekte der Informationen auf solchen Websites.

\n\n \n\n

Die Verantwortung für Meinungen, Ratschläge, Aussagen oder andere Informationen, die in Artikeln oder Texten auf dieser Website enthalten sind, liegt allein beim Autor und spiegelt nicht notwendigerweise die Meinung und Grundsätze von SmartResQ/CorPatch® selbst wider.

\n\n \n\n

Rechtlicher Hinweis

\n\n

Durch den Kauf, die Lizenzierung, das Anzeigen, die Nutzung und/oder den Zugriff auf unsere Website(s), Produkte und Apps erkennst du an und stimmst zu, dass:

\n
    \n
  1. Die von SmartResQ/CorPatch® bereitgestellten Systeme spezifische Produkte sind, die ausschließlich für den im Manual des Produkts angegebenen Verwendungszweck verwendet werden dürfen. Bitte lies die Benutzeranleitungen und Manuals sorgfältig durch und vergewissere dich, dass du mit unseren medizinischen Produkten vertraut bist, bevor du sie in Gebrauch nimmst.
  2. \n\n
  3. Die von SmartResQ/CorPatch® bereitgestellten Systeme sind spezifische Bildungs- und medizinische Schulungsprodukte und -instrumente, die nicht als Medizinprodukt zertifiziert sind, es sei denn, dies ist ausdrücklich vermerkt; sie sind nicht für klinische oder diagnostische Zwecke bestimmt und dienen ausschließlich dem medizinischen Training und der Leistungssteigerung.
  4. \n\n
  5. Du wirst das System jederzeit ausschließlich in Verbindung mit solchen medizinischen Trainings- und Leistungsverbesserungszwecken verwenden und darauf zugreifen, unter Einhaltung aller geltenden Gesetzen und Vorschriften und in Übereinstimmung mit Benutzerdokumentationen, Bedienungsanleitungen, Guides und/oder Anforderungen, die wir dir elektronisch oder persönlich zur Verfügung stellen.
  6. \n\n
  7. Ein SmartResQ/CorPatch® System kann allein zu keinem Zeitpunkt den Zustand eines Menschen oder in einer lebensrettenden Situation diagnostizieren, behandeln oder heilen, professionelle medizinische Entscheidungen, Diagnosen oder Behandlungen unterstützen oder eine Diagnose, Empfehlung, einen Ratschlag, eine Behandlung oder eine Entscheidung einer entsprechend ausgebildeten und zugelassenen medizinischen Fachkraft ersetzen.
  8. \n\n
  9. Die Verbindung eines Geräts mit einem Schaden oder einem Ergebnis für den Patienten/die Patientin bedeutet nicht, dass das Gerät den Schaden oder das Ergebnis verursacht hat.
  10. \n\n
  11. SmartResQ/CorPatch® übernimmt keine Verantwortung für Schäden, die aus einer unangemessenen Verwendung unserer Produkte oder einer Verwendung außerhalb des vorgesehenen Verwendungszwecks des Produkts resultieren.
  12. \n\n \n
\n

Leistungsinformationen

\n\n

Die hier enthaltenen Informationen dienen lediglich als Guide für die Anwendung der SmartResQ/CorPatch® Produkte. SmartResQ/CorPatch® arbeitet kontinuierlich daran, die Qualität und Zuverlässigkeit seiner Produkte zu verbessern. Dennoch können unsere Geräte aufgrund ihrer inhärenten elektrischen Empfindlichkeit und Anfälligkeit für physischen Stress und ungünstige Kommunikationssignale Fehlfunktionen aufweisen oder ausfallen. Es liegt in der Verantwortung des Käufers, bei der Verwendung von SmartResQ/CorPatch® Produkten die Sicherheits- und Prüfstandards einzuhalten und Situationen zu vermeiden, in denen eine Fehlfunktion oder ein Ausfall zu Körperverletzungen oder Sachschäden führen könnte.

\n\n \n\n

Standard-Garantie

\n\n

Die eingeschränkte Standardgarantie von SmartResQ/CorPatch® ist an die ordnungsgemäße Nutzung der Produkte, der Website(s) und der Apps gebunden. \n
\nDiese Garantie gilt nur für den/die Erstkäufer/in des Produkts und nur dann, wenn das Produkt von einem autorisierten SmartResQ/CorPatch® Händler erworben wurde. Andere Hersteller, Lieferanten oder Verlage als SmartResQ/CorPatch® können dir ihre eigenen Garantien anbieten – bitte kontaktiere sie für weitere Informationen.

\n\n \n\n

Die Garantie gilt nicht für:

\n
    \n
  1. Defekte oder Schäden, die durch Unfälle, unsachgemäßen Gebrauch, anormale Bedingungen, unsachgemäße Lagerung, Einwirkung von Flüssigkeiten, Feuchtigkeit, Nässe, Sand oder Schmutz, Vernachlässigung oder ungewöhnliche physische, elektrische oder elektromechanische Belastungen entstehen,
  2. \n\n
  3. Defekte oder Schäden, die durch übermäßige Gewaltanwendung oder den Gebrauch von Metallgegenständen entstanden sind,
  4. \n\n
  5. Geräte, bei denen die Produktionsnummer oder der Erweiterungsdatencode entfernt, verunstaltet, beschädigt, verändert oder unlesbar gemacht wurde,
  6. \n\n
  7. normalen Verschleiß oder normale Alterung des Produkts,
  8. \n\n
  9. Kratzer, Dellen und kosmetische Schäden, es sei denn, der Ausfall ist auf einen Material- oder Verarbeitungsfehler zurückzuführen,
  10. \n\n
  11. Mängel oder Schäden, die durch die Verwendung der Produkte in Verbindung mit Zubehör, Produkten oder Zusatz-/Peripheriegeräten entstehen, die nicht von SmartResQ/CorPatch® geliefert oder genehmigt wurden,
  12. \n\n
  13. Defekte oder Schäden, die durch unsachgemäße Tests, Betrieb, Wartung, Installation, Service oder Einstellung entstehen, die nicht von SmartResQ/CorPatch® geliefert oder genehmigt wurden,
  14. \n\n
  15. Schäden, die durch den Betrieb des SmartResQ/CorPatch® Produkts außerhalb der veröffentlichten Richtlinien entstehen,
  16. \n\n
  17. Vorführung/Installation des erworbenen Produkts,
  18. \n\n
  19. Defekte oder Schäden, die auf äußere Ursachen zurückzuführen sind, wie z. B. Zusammenstoß mit einem Gegenstand, Feuer, Überschwemmung, Verschmutzung, Sturm, Blitzschlag, Erdbeben, Witterungseinflüsse, Diebstahl, durchgebrannte Sicherungen oder unsachgemäße Verwendung einer Stromquelle,
  20. \n\n
  21. Mängel oder Schäden, die durch Übertragungen, Viren oder andere Softwareprobleme entstehen, die in die Produkte eingeschleust wurden,
  22. \n\n
  23. wenn die Batterien mit anderen als den mit CorPatch® Trainer kompatiblen Ladegeräten geladen werden,
  24. \n\n
  25. eine der Versiegelungen des Batteriegehäuses oder der Zellen gebrochen ist oder Anzeichen von Manipulation aufweist,
  26. \n\n
  27. Produkte, die von einem anderen Unternehmen als SmartResQ/CorPatch® repariert, verwendet oder gekauft wurden,
  28. \n\n
  29. wenn SmartResQ/CorPatch® von den zuständigen Behörden Informationen erhält, dass das Produkt gestohlen wurde, oder wenn du nicht in der Lage bist, den Passcode oder andere Sicherheitsmaßnahmen zu deaktivieren, die den unbefugten Zugriff auf das Produkt verhindern sollen, oder wenn du nicht nachweisen kannst, dass du der/die autorisierte Benutzer/in des Produkts bist,
  30. \n\n
  31. wenn die Produkte außerhalb der in den Manuals angegebenen Bedingungen verwendet werden, z. B. Temperaturbereich, Druck und Feuchtigkeit.
  32. \n\n \n
\n

Akkus und Ladegeräte

\n\n

SmartResQ/CorPatch® Produkte enthalten entweder nicht austauschbare Batterien (CorPatch®) oder wiederaufladbare Batterien (CorPatch® Trainer). Die Batterietypen, die in unseren Produkten verwendet werden, sind unter jedem einzelnen Produkt beschrieben. SmartResQ/CorPatch® übernimmt keine Verantwortung, wenn die wiederaufladbaren Batterien nicht entsprechend des Manuals behandelt werden.

\n\n \n\n

Im Zusammenhang mit dem Verkauf von Geräten, die Batterien enthalten, sind wir verpflichtet, dich auf Folgendes hinzuweisen: \n
\nAls Endbenutzer/in bist du gesetzlich verpflichtet, sie richtig zu entsorgen. Das Symbol der durchgestrichenen Mülltonne bedeutet, dass die Batterie nicht über den Hausmüll entsorgt werden darf.

\n\n \n
\n \n\t
\n\t

Bestellung

\n\n

Der Corpatch.com Onlineshop ist 24 Stunden am Tag geöffnet und du kannst fast jederzeit einkaufen. Es kann jedoch vorkommen, dass wir den Shop wegen Wartungsarbeiten schließen. Einkäufe in großen Mengen können direkt bei SmartResQ/CorPatch® getätigt werden.

\n\n \n\n

SmartResQ/CorPatch® bietet keine Produkte zum Verkauf an Minderjährige an. Produkte, die für Kinder bestimmt sind, können nur von Erwachsenen gekauft werden. Um bei SmartResQ/CorPatch® zu kaufen, musst du mindestens 18 Jahre alt sein und eine gültige Kreditkarte oder ein anderes von uns akzeptiertes Zahlungsmittel besitzen.

\n\n \n\n

Die Präsentation der Produkte im Online-Shop ist kein rechtsverbindliches Angebot, sondern ein unverbindlicher Online-Katalog. Wenn du einkaufen möchtest, wählst du die Artikel aus, die du kaufen möchtest, und legst sie in den „Einkaufswagen“. Du kannst den Inhalt des Warenkorbs bis zum Zeitpunkt der Bestellung bearbeiten. Alle zusätzlichen Zahlungen, wie z. B. Versand- oder Kreditkartengebühren, werden sofort berechnet, bevor du bezahlst.

\n\n \n\n

Wenn du bereit bist zu bestellen, klickst du auf „Zur Kasse“ und gibst die relevanten Informationen ein. Du kannst den Inhalt des Warenkorbs bis zur Bestätigung deines Kaufs ändern, indem du auf die Schaltfläche „Bezahlen“ klickst. Danach gibst du eine verbindliche Bestellung für die im Warenkorb enthaltenen Waren ab, die nicht mehr geändert werden kann.\n
\nSmartResQ/CorPatch® kann die Bestellung durch Zusendung einer Auftragsbestätigung per E-Mail oder durch Auslieferung der Ware innerhalb der Lieferfrist annehmen.

\n\n \n\n

Bestimmte Länder können die Verwendung und den Besitz unserer Produkte verbieten. Du bist allein dafür verantwortlich, herauszufinden, ob das Produkt in deinem Land legal eingeführt und/oder verwendet werden darf. Wir senden dir die von dir bestellten Produkte zu und übernehmen keine Haftung für Zollprobleme oder Auswirkungen, die sich aus dem Besitz oder der Nutzung dieses Geräts ergeben.

\n\n
\n\n \n
\n

Zahlung

\n\n

Unsere Website(s), App(s) und Onlineshop(s)

\n\n

Die Nutzung unserer Website(s) und App(s) ist kostenlos, solange du unsere rechtlichen Bestimmungen akzeptierst und einhältst. Sei dir bewusst, dass du unsere Produkte möglicherweise in den Onlineshops auf unserer/unseren Website(s) und in der/den App(s) kaufen kannst.

\n\n \n\n

Unsere Produkte

\n\n

SmartResQ/CorPatch® nutzt QuickPay als Zahlungsgateway. QuickPay ist vom Payment Card Industry (PCI) Security Standards Council nach der neuesten Version des PCI Data Security Standard (DSS) Level 1 zertifiziert, was Folgendes beinhaltet: (a) einen jährlichen Bericht – „Report on Compliance“ (ROC), der von einem Qualified Security Assessor (QSA) erstellt wird; (b) vierteljährliche Netzwerkscans, die von Approved Scan Vendor (ASV) durchgeführt werden, und (c) eine große Anzahl von Regeln und Richtlinien für Arbeitsabläufe und die Verarbeitung von Daten.

\n\n \n\n

Wir akzeptieren Zahlungen per:

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • MasterCard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n \n\n

Die Zahlungen werden bei Versand der Ware von deinem Konto abgebucht. Alle Beträge sind in Euro angegeben und die gesetzliche Mehrwertsteuer ist in allen genannten Preisen bereits enthalten. Alle Kredit-/Debitkarteninhaber/innen unterliegen der Validierungsprüfung und Autorisierung durch den Kartenaussteller oder Zahlungsanbieter. SmartResQ/CorPatch® ist nicht verantwortlich für den Fall, dass dein Zahlungskartenanbieter sich weigert, Zahlungen zu autorisieren.

\n \n\n

Wir verwenden eine Verschlüsselung der Kreditkartendaten durch das Secure Socket Layer (SSL) Protokoll. Dadurch wird sichergestellt, dass andere die Kreditkartennummer oder andere Informationen während der Transaktion mit unserem Anbieter nicht abfangen können.

\n\n \n\n

Vor Vertragsabschluss muss der Kunde/die Kundin die zum Kaufpreis hinzugefügten Versand- und Logistikkosten überprüfen und akzeptieren, da diese Kosten dem Kunden/der Kundin in Rechnung gestellt werden. Nachdem du eine Bestellung aufgegeben hast, erhältst du von uns eine E-Mail, in der wir bestätigen, dass wir deine Bestellung erhalten haben. Bitte beachte, dass dies nicht bedeutet, dass deine Bestellung angenommen wurde. Deine Bestellung stellt ein Angebot an SmartResQ/CorPatch® zum Kauf eines Produkts dar (und SmartResQ/CorPatch® behält sich das Recht vor, Bestellungen für Produkte abzulehnen). Es besteht kein Vertrag in Bezug auf die Produkte, bis wir dir per E-Mail bestätigt haben, dass das/die Produkt(e) versandt wurde(n). Unsere Annahme deines Angebots gilt als vollständig und der Vertrag zwischen uns kommt zustande, wenn wir dir eine Versandbestätigungsmail schicken.

\n\n \n\n

Die Versandkosten werden immer in Bezug auf jede einzelne Bestellung angegeben.

\n\n \n\n

SmartResQ/CorPatch® behält sich das Eigentum an dem gekauften Artikel vor, bis der Rechnungsbetrag vom Kunden/von der Kundin vollständig bezahlt und kurz vor dem Versand automatisch „abgezogen“ wurde.

\n\n \n\n

Kunden sind nur dann zur Aufrechnung berechtigt, wenn ihre Gegenforderungen rechtskräftig festgestellt, unbestritten oder von SmartResQ/CorPatch® anerkannt sind. Darüber hinaus haben Kunden nur dann ein Zurückbehaltungsrecht, wenn und soweit ihr Gegenanspruch auf demselben Vertragsverhältnis beruht.

\n\n \n\n

Befindet sich der Kunde/die Kundin mit irgendwelchen Zahlungsverpflichtungen uns gegenüber im Rückstand, werden alle bestehenden Forderungen sofort fällig.

\n\n \n\n

Zuschläge für Gebühren

\n\n

Ab dem 1. Januar 2018 wurden die Regeln für die Erhebung von Zuschlägen geändert. Es ist daher nicht mehr zulässig, Aufschläge auf Zahlungen mit Verbraucherkarten zu erheben, wenn diese von Banken/Kartenausstellern innerhalb der EU ausgegeben werden. Das gilt sowohl für Debit- als auch für Kreditkarten. Verbraucherkarten sind Karten, die an eine/n private/n Verbraucher/in ausgegeben werden.

\n\n

Handelt es sich jedoch um eine Unternehmenskarte oder eine Verbraucherkarte, die außerhalb der EU ausgegeben wurde, wird ein Aufschlag auf die Transaktionsgebühr erhoben. Das bedeutet, dass der/die Karteninhaber/in die Transaktionsgebühr automatisch bezahlt. \n
\nDie Gebühr wird nicht höher sein als die Gebühr, die SmartResQ/CorPatch® vom Erwerber/von der Erwerberin berechnet wird. Die Gebühr wird im Zahlungsfenster deutlich als separater Posten angezeigt.

\n\n
\n\n \n
\n

Lieferung

\n\n

Wir bemühen uns, Bestellungen von Werktag zu Werktag zu versenden und arbeiten mit einer international vertrauenswürdigen Versandagentur zusammen. Den Gesamtpreis für deinen Einkauf einschließlich Lieferung findest du an der Kasse, bevor du deine endgültige Bestellung akzeptierst.

\n\n \n\n

Nimmt der Kunde/die Kundin die Ware nicht an, kann SmartResQ/CorPatch® nach einer Frist von zwei Wochen zur Deckung der Bearbeitungs- und Versandkosten vom Vertrag zurücktreten oder Schadenersatz wegen Nichterfüllung erhalten.

\n\n \n\n

Wenn der Kunde/die Kundin falsche Angaben zur Lieferadresse gemacht hat, ist es möglich, das Paket in dem in unserem Onlineshop genannten Paketshop abzuholen, andernfalls ist das Paket verloren.

\n\n \n\n

Der Kunde/die Kundin erhält niemals Teillieferungen, es sei denn, dies wird von SmartResQ/CorPatch® ausdrücklich angegeben.

\n\n \n\n

Risiko des Verlusts

\n\n

Das Risiko des Eigentums an der Ware geht auf den/die Käufer/in über, wenn die Ware dem/der Käufer/in gemäß dieser Vereinbarung zur Verfügung gestellt wird. Wenn die Lieferfrist verstrichen ist und der Käufer/in ein Produkt, das ihm/ihr gemäß der Vereinbarung zur Verfügung gestellt wurde, nicht erhält, trägt der/die Käufer/in das Risiko des Verlusts oder der Beschädigung, die durch die Eigenschaften des Produkts selbst verursacht wurden.

\n\n
\n\n \n
\n

Stornierung und Rückgabe

\n\n

Wenn du online oder offline bei SmartResQ/CorPatch® einkaufst, hast du 14 Tage Zeit, um den Kauf zu bedauern und zu widerrufen, indem du uns mitteilst, dass du es dir anders überlegt hast, und den Artikel in demselben Zustand zurückschickst, in dem du ihn erhalten hast. \n
\nWir akzeptieren nur Rücksendungen unbenutzter Artikel in der versiegelten und unbeschädigten Originalverpackung und sie müssen ordnungsgemäß für den Versand verpackt sein, andernfalls gelten die Produkte als gebraucht und es erfolgt keine Teilrückerstattung. Das Widerrufsrecht gilt nur für unversiegelte Produkte bei Erhalt.

\n\n \n\n

Akzeptable Gründe für die Rückgabe eines Produkts

\n
    \n
  • Nutzung des 14-tägigen Widerrufsrechts
  • \n\n
  • Das Produkt entspricht nicht der Beschreibung (Garantie)
  • \n\n
  • Das Produkt ist fehlerhaft
  • \n
\n \n\n

Die Bedingungen für die Rückgabe von CorPatch® richten sich nach den EU-Standardregeln.

\n\n \n\n \n\n

Wenn du das Produkt zurückschickst, bewahre die Originalverpackung auf und beschädige, beklebe oder beschrifte sie nicht. Besorge dir eine geeignete Rücksendeverpackung, z. B. einen Karton, und verwende diese.

\n\n \n\n

Für CorPatch® Trainer gelten die Standard-Widerrufsbedingungen für dieses Produkt gemäß den EU-Vorschriften.

\n\n \n\n

Um von deinem Widerrufsrecht Gebrauch zu machen, musst du uns innerhalb von 14 Tagen nach Erhalt der Ware informieren. Widerrufsanfragen sind per E-Mail an info@corpatch.com, zu senden, aus der klar hervorgeht, dass du von deinem Widerrufsrecht Gebrauch machen möchtest und warum.

\n\n \n\n

Wir erwarten, dass du die Artikel so schnell wie möglich zurückschickst, nachdem du den Widerruf erklärt hast, spätestens aber 14 Tage, nachdem du uns per E-Mail informiert hast.

\n\n \n\n

Wir können die Rückzahlung verweigern, bis du die Artikel zurückgeschickt hast oder nachweisen kannst, dass du die Artikel zurückgeschickt hast. Für diese Rückzahlung verwenden wir dasselbe Zahlungsmittel, das du bei der ursprünglichen Transaktion eingesetzt hast.

\n\n \n\n

Nicht akzeptable Gründe für die Rückgabe eines Produkts

\n
    \n
  • Änderung der Meinung nach dem 14-tägigen Widerrufsrecht.
  • \n\n
  • Wenn das Produkt aktiviert worden ist.
  • \n\n
  • Wenn das Produkt auf irgendeine andere Weise benutzt oder beschädigt wird.
  • \n\n
  • Wenn die Software/die kostenlose App heruntergeladen, verbunden, installiert oder auf andere Weise mit dem/den physischen Produkt(en) kombiniert wird.
  • \n
\n \n\n

Rückgabeverfahren

\n\n

Wir nehmen nur ungeöffnete Artikel in der unbeschädigten Originalverpackung zurück. Sie müssen für den Versand ordnungsgemäß verpackt sein, sonst gelten die Produkte als gebraucht und werden nicht erstattet.

\n\n \n\n

Wenn nicht anders angegeben, müssen die Rücksendungen an folgende Adresse geschickt werden: \n
\nSmartResQ ApS (CorPatch®) \n
\nLundevej 26 \n
\nDK-5700 Svendborg \n
\nDänemark \n

\n \n\n

WICHTIG! Du bist allein für die Qualität der Verpackung und die Artikel verantwortlich, bis sie bei uns eingegangen sind. Bitte bewahre den Postbeleg auf, der Informationen zu den Versandkosten und ggf. die Track & Trace-Nummer enthält. Wir übernehmen keine Rücksendekosten und wir akzeptieren keine Pakete, die per Nachnahme oder ähnlichem verschickt werden.

\n\n
\n\n\n
\n

Rückerstattungen

\n\n

SmartResQ/CorPatch® ist verpflichtet, den Artikel zu reparieren, zu ersetzen oder einen Preisnachlass oder eine vollständige Rückerstattung zu gewähren, wenn sich der Artikel innerhalb von 2 Jahren nach dem Kauf als fehlerhaft erweist. \n
\nDer Kunde/die Kundin hat keinen Anspruch auf eine Rückerstattung, wenn es sich um ein geringfügiges Problem handelt, wie z. B. Kratzer auf dem Artikel oder Ähnliches. \n
\nSobald SmartResQ/CorPatch® den Artikel des Kunden/der Kundin erhalten hat, wird eine Rückerstattung eingeleitet. Die Höhe des Rückerstattungsbetrags hängt vom Zustand der Produkte ab, wenn sie bei SmartResQ/CorPatch® eingehen.

\n\n \n\n

Die Art und Weise, wie die Rückerstattung für den Kunden/die Kundin bearbeitet wird, hängt von der ursprünglichen Zahlungsmethode ab. Wenn der Kunde/die Kundin mit einer Kredit- oder Debitkarte bezahlt hat, wird die Rückerstattung innerhalb von 5 Werktagen nach Erhalt der zurückgesendeten Ware oder des Stornierungsantrags an die kartenausgebende Bank geschickt. Bitte wende dich an die kartenausgebende Bank, wenn du wissen möchtest, wann die Gutschrift auf deinem Konto verbucht wird.

\n
\n \n\n
\n\n

Verarbeitung von persönlichen Informationen

\n\n\n

Bei SmartResQ/CorPatch® legen wir Wert auf deine persönlichen Daten, indem wir uns in drei Schritten um die Einhaltung der Datenschutzbestimmungen bemühen: a. Wir führen eine detaillierte Karte unseres Datenflusses, b. wir nehmen eine rechtliche Bewertung auf der Grundlage des Datenflusses vor, um c. die notwendigen Sicherheitsmaßnahmen zu ergreifen, damit deine Daten sicher sind.

\n\n \n\n

Um unseren Onlineshop nutzen zu können, musst du mindestens die folgenden Angaben machen:

\n
    \n
  • Name
  • \n\n
  • Adresse
  • \n\n
  • E-Mail-Adresse
  • \n\n
  • Telefonnummer
  • \n
\n \n\n

Die Erhebung von persönlichen Kundendaten erfolgt im Rahmen der bestehenden Gesetzgebung und der EU-Gesetzgebung zur Allgemeinen Datenschutzverordnung (DSGVO).

\n\n \n\n

Wenn du mehr über die Verarbeitung deiner persönlichen Daten erfahren möchtest, lies bitte unsere Datenschutzrichtlinie.

\n\n
\n \n\n
\n

Beschwerden

\n\n

Wie du dich bei uns beschweren kannst

\n\n

Wenn etwas mit dem Produkt nicht in Ordnung ist, kannst du ein fehlerhaftes Produkt entweder reparieren oder ersetzen lassen, eine Rückerstattung oder einen Preisnachlass erhalten, je nach der konkreten Situation. \n
\nVoraussetzung ist natürlich, dass die Beschwerde gerechtfertigt ist und der Mangel nicht durch unsachgemäßen Gebrauch des Produkts oder anderes Fehlverhalten verursacht wurde.

\n\n \n\n

Wir empfehlen dir, die Reklamation so schnell wie möglich und innerhalb einer Woche nach Feststellung des Mangels geltend zu machen.\n
\nBitte zögere nicht, dich mit Fragen, Kommentaren oder Beschwerden an uns zu wenden, indem du dich per E-Mail an uns wendest: info@corpatch.com.

\n\n

Beschwerde bei anderen Stellen innerhalb der EU

\n\n

Bitte besuche die offizielle Website der Europäischen Union, um dich bei anderen Stellen innerhalb der EU zu beschweren. Informationen findest du hier.

\n\n
\n\n\n
\n

Änderungen an diesem Dokument

\n\n

Zu Website(s), App(s) und Richtlinien

\n\n

SmartResQ/CorPatch® behält sich das Recht vor, unsere Website(s), App(s), Richtlinien und Dokumente jederzeit und ohne Angabe von Gründen zu ändern, zu löschen, zu modifizieren oder zu ergänzen, ohne dass jemand davon in Kenntnis gesetzt wird. \n
\nSollte eine dieser Bedingungen ungültig, nichtig oder aus irgendeinem Grund nicht durchsetzbar sein, gilt diese Bedingung als abtrennbar und beeinträchtigt nicht die Gültigkeit und Durchsetzbarkeit der übrigen Bedingungen.

\n\n \n\n

Wenn wir unsere Richtlinien ändern, werden wir die überarbeiteten Richtlinien online mit einem aktualisierten Änderungsdatum veröffentlichen. Wir empfehlen dir, die Richtlinien regelmäßig zu überprüfen. Wenn wir unsere Richtlinien inhaltlich wesentlich ändern, können wir dich auch auf andere Weise benachrichtigen, z. B. per E-Mail oder durch einen Hinweis auf unserer Website und/oder in den sozialen Medien, bevor die Änderungen in Kraft treten.

\n\n \n\n

Bezug auf einen bestimmten Kauf

\n\n

Wenn du ein Produkt kaufst, wirst du aufgefordert, eine Version bestimmter Dokumente zu akzeptieren, wie sie zu diesem Zeitpunkt vorliegt – diese Version wird nach diesem Zeitpunkt nicht mehr geändert und bestimmt die Bedingungen unserer Beziehung zu dir in Bezug auf diesen bestimmten Kauf.

\n\n
\n\n\n
\n

Recht und Gerichtsbarkeit

\n\n

Die Gesetze Dänemarks und das Bezirksgericht von Svendborg

\n\n \n\n

SmartResQ/CorPatch® wendet dänisches Recht und den Gerichtsstand für alle Rechtsstreitigkeiten an, jedoch nicht das CISG. \n
\nAlle Rechtsstreitigkeiten, die in irgendeiner Weise mit deinem Besuch bei SmartResQ/CorPatch® oder mit Produkten, die du über SmartResQ/CorPatch® kaufst, zusammenhängen, werden in Dänemark vertraulich behandelt, außer wenn du in irgendeiner Weise die geistigen Eigentumsrechte von SmartResQ/CorPatch® verletzt hast oder zu verletzen drohst; SmartResQ/CorPatch® kann in jedem Land eine einstweilige Verfügung oder einen anderen angemessenen Rechtsbehelf beantragen, und du stimmst der ausschließlichen Zuständigkeit und dem ausschließlichen Gerichtsstand in diesen Gerichten zu.

\n\n \n\n

Bei einem Verstoß gegen die Vereinbarung über die Allgemeinen Geschäftsbedingungen werden rechtliche Schritte eingeleitet, und es kann eine Klage vor Gericht eingereicht werden.

\n\n \n\n

Für Streitigkeiten zwischen uns und einem Verbraucher ist das Bezirksgericht Svendborg, Christiansvej 41, 5700 Svendborg, Dänemark, zuständig.

\n\n
\n\n\n
\n

Kontaktinformationen

\n\n

Vielen Dank, dass du die Allgemeinen Geschäftsbedingungen von SmartResQ/CorPatch® gelesen hast. \n
\nWenn du Fragen, Kommentare oder Beschwerden hast, kannst du dich gerne an uns wenden.

\n\n \n\n

Unser Unternehmen befindet sich in: Lundevej 26, 5700 Svendborg, Dänemark

\n\n \n\n

Du findest uns im Zentralen Unternehmensregister unter der Umsatzsteuernummer DK 38674102

\n\n \n\n

Du kannst uns unter der Telefonnummer +45 62 200 100 anrufen

\n\n \n\n

oder

\n\n \n\n

schreib uns eine E-Mail an: info@corpatch.com

\n\n \n\n

© SmartResQ ApS – Alle Rechte vorbehalten\n
\nDänemark, Version 2.1 – Veröffentlicht 2023.04.25

\n\n
\n \n \n\n\n\n \n \n\n
\n\n

SmartResQ / CorPatch® Datenschutzrichtlinie

\n \n

Wir behandeln deine Daten in Übereinstimmung mit der DSGVO

\n\n

SmartResQ/CorPatch® respektiert deine Privatsphäre. Diese Datenschutzerklärung beschreibt deine Datenschutzrechte und unsere Verpflichtung zum Schutz deiner persönlichen Daten.

\n\n

Wenn du Fragen zu unserer Verarbeitung deiner persönlichen Daten hast, wende dich bitte an uns. Der Datenverantwortliche ist:

\n\n

Das Unternehmen: SmartResQ ApS (CorPatch®)

\n\n

Adresse: \n
\nLundevej 26 \n
\n5700 Svendborg \n
\nDänemark

\n\n \n\n

CVR-Nr.: 38674102

\n\n

Telefon-Nr.: +45 62 200 100

\n\n

E-Mail: info@corpatch.com

\n\n

SmartResQ/CorPatch® ist ein dänisches/europäisches Unternehmen mit juristischen Einheiten, Geschäftsprozessen, Managementstrukturen und technischen Systemen, über nationale Grenzen hinweg. SmartResQ/CorPatch® bietet Produkte, Software und Dienstleistungen für öffentliche/private Unternehmen in Europa an.

\n\n

Der Hauptsitz befindet sich in Dänemark und SmartResQ/CorPatch® unterliegt der europäischen Datenschutzgesetzgebung, einschließlich der Allgemeinen Datenschutzverordnung (DSGVO). Alle wichtigen Entscheidungen in SmartResQ/CorPatch®, die den Schutz persönlicher Daten betreffen, werden auf Managementebene unter der Aufsicht des Datenschutzbeauftragten getroffen.

\n\n

Diese Datenschutzerklärung ist auf unseren Websites und in unseren Apps verfügbar.

\n\n

Bitte nutze die Seiten, Apps oder Dienste von SmartResQ/CorPatch® nicht, wenn du mit der Art und Weise nicht einverstanden bist, wie wir persönliche Daten gemäß dieser Datenschutzerklärung verarbeiten.

\n\n
\n\n\n
\n\n

Die Art der persönlichen Daten, die wir sammeln

\n\n

Wenn ein/e Verantwortliche/r die Zwecke und Mittel der Verarbeitung deiner persönlichen Daten bestimmt, handelt er/sie als für die Verarbeitung Verantwortliche/r. Dazu gehören Szenarien, in denen SmartResQ/CorPatch® persönliche Daten im Zusammenhang mit dir als Arbeitssuchende/m, Vertreter/in eines Kunden oder eines Kundenkontakts erhebt, oder wenn du ein/e Software-Nutzer/in bist.

\n\n

SmartResQ verarbeitet persönliche Daten für eine Vielzahl von Zwecken, je nachdem, welche Beziehung wir zu dir haben.

\n\n

Wir können Folgendes verarbeiten:

\n
    \n
  1. Grundlegende Kontaktinformationen wie Name, Adresse, Telefonnummer (Handy und/oder Festnetz) und E-Mail,
  2. \n\n
  3. Beschäftigungsinformationen wie Arbeitgeber, Titel, Position, einschließlich Vorlieben und Interessen im beruflichen Kontext,
  4. \n\n
  5. Feedback, Kommentare oder Fragen zu SmartResQ/CorPatch® oder unseren Produkten und Dienstleistungen,
  6. \n\n
  7. Fotos oder Videos, die an unseren Standorten aufgenommen wurden,
  8. \n\n
  9. Inhalte, die du hochgeladen hast, wie Fotos, Videos und Leistungen im Laufe der Zeit,
  10. \n\n
  11. Eindeutige Benutzerinformationen wie Anmelde-ID, Benutzername, Passwort und Sicherheitsfrage,
  12. \n\n
  13. Finanzielle Informationen, wenn du zustimmst, dass wir deine Daten verwenden, z. B. für die Speicherung deiner Zahlungskartendaten,
  14. \n\n
  15. Verkehrsdaten, die von deinem Webbrowser zur Verfügung gestellt werden, wie z. B. die Art des Browsers, das Gerät, die Sprache und die Adresse der Website, von der du gekommen bist, sowie andere Verkehrsdaten, einschließlich der IP-Adresse,
  16. \n\n
  17. Clickstream-Verhalten und Aktivitäten auf SmartResQ/CorPatch® IDs und in unseren Produkten und Diensten,
  18. \n\n
  19. E-Mail-Verhalten, wie z. B. E-Mail-Nachrichten von SmartResQ/CorPatch®, die du wann und wie öffnest,
  20. \n\n
  21. andere persönliche Informationen, die in deinem Profil enthalten sind und die du freiwillig in sozialen Netzwerken Dritter wie LinkedIn, Facebook, Google usw. eingestellt hast,
  22. \n\n
  23. Informationen, die zu wissenschaftlichen Zwecken verwendet werden, um das Überleben nach einem Herzstillstand zu verbessern, die über unsere Website(s) und Apps gesammelt werden,
  24. \n\n
  25. Informationen über Nutzer/innen, um Produkte zu liefern, die den Qualitäts- und Sicherheitsanforderungen entsprechen, um Dienstleistungen für die Nutzer/innen zu erbringen und um unsere Angebote zu pflegen und zu verbessern,
  26. \n\n
  27. Informationen über Stellenbewerber/innen, um Bewerbungen zu bearbeiten, über zukünftige Stellenangebote zu informieren und unsere Rekrutierungsprozesse zu pflegen und zu verbessern,
  28. \n\n
  29. Informationen über Personen, die sich für den Erhalt von Newslettern und anderen Inhalten angemeldet haben, um die Inhalte zu versenden und unser Angebot zu pflegen und zu verbessern,
  30. \n\n
  31. Cookie-Informationen, um maßgeschneiderte Werbung in sozialen Medien und auf Websites bereitzustellen.
  32. \n
\n\n
\n\n\n
\n

Daten, die auf der CorPatch® Services Plattform und in den Apps gesammelt und verarbeitet werden

\n\n

SmartResQ verarbeitet, sammelt und speichert die folgenden persönlichen Daten, wenn du die CorPatch® Services Plattform oder die Apps nutzt.

\n\n \n \n\n

Alle Benutzer/innen (Institute Admin, Trainer/in, Trainee/Endbenutzer/in)

\n
    \n
  • Vorname (falls eingegeben)
  • \n\n
  • Nachname (falls eingegeben)
  • \n\n
  • Benutzernamen (falls eingegeben)
  • \n\n
  • E-Mail-Adresse (obligatorisch)
  • \n\n
  • Bevorzugte Kommunikationssprache (obligatorisch)
  • \n\n
  • Passwort-Hash (obligatorisch)
  • \n\n
  • Ob die E-Mail-Adresse validiert wurde (obligatorisch)
  • \n
\n \n\n

Zusätzlich für Trainees/Endnutzer (obligatorisch)

\n\n

Daten über das verwendete Mobiltelefon:

\n\n\n

Betriebssystem (Android/iOS):

\n
    \n
  • Version des Betriebssystems (z. B. 9)
  • \n\n
  • Hersteller (z. B. Samsung)
  • \n\n
  • Modell (z. B. SM-T518)
  • \n\n
  • App-Version (z. B. 1.2.4)
  • \n\n
  • Zeitpunkt der letzten Vordergrundaktivität der App
  • \n\n
  • Zeitpunkt der letzten Hintergrundaktivität der App
  • \n\n
\n\n

Daten zum verwendeten CorPatch® Gerät (CPS):

\n
    \n
  • Seriennummer / MAC-Adresse
  • \n\n
  • Firmware-Version
  • \n\n
  • Modellbezeichnung (z. B. CPS_01)
  • \n\n
  • Hersteller (derzeit immer SRQ)
  • \n\n
  • Name (derzeit immer CorPatch®)
  • \n\n
  • Akkuzustand
  • \n\n
  • Defekte
  • \n
\n \n\n

Daten zum Onboarding des Benutzers:

\n
    \n
  • Tutorial abgeschlossen (ja/nein)
  • \n\n
  • Nutzungsbedingungen akzeptiert (ja/nein)
  • \n\n
  • Selbsteinschätzung abgeschlossen (ja/nein)
  • \n\n
  • Testtraining abgeschlossen (ja/nein)
  • \n\n
  • Erste Anmeldung erfolgreich (ja/nein)
  • \n\n
  • Wurde ein CPS angeschlossen (ja/nein)
  • \n\n
\n\n

Durch das Training erhobene Daten:

\n
    \n
  • Datum, Uhrzeit und Dauer des Trainings
  • \n\n
  • Ergebnis des Trainings
  • \n\n
  • Art des Trainings oder Trainingseinstellungen
  • \n\n
  • Bei einem Training innerhalb eines Instituts, zusätzliche Informationen über den Kurs, den/die Trainer/in und das Institut
  • \n\n
\n \n\n

Server-Protokolle

\n\n

Die folgenden Daten werden in den Webserver-Protokollen gespeichert:

\n
    \n
  • IP-Adresse des/der zugreifenden Teilnehmers/Teilnehmerin
  • \n\n
  • Browserversion des/der zugreifenden Teilnehmers/Teilnehmerin
  • \n\n
  • Datum/Uhrzeit des Zugriffs
  • \n\n
  • URL des Zugriffs
  • \n
\n

Externe Dienste, die Daten verarbeiten:

\n
    \n
  • Google/Firebase für die Fernprotokollierung, Absturz- und Fehleranalyse
  • \n\n
  • Google/Firebase für den Versand von Benachrichtigungen
  • \n\n
  • Sendgrid für den Versand von E-Mails
  • \n\n
  • Hetzner Online GmbH für das Hosting von Web-Backend und Datenbank
  • \n\n
\n\n

Was passiert, wenn ein Benutzer gelöscht wird

\n
    \n
  • Der/die Benutzer/in löscht sich selbst aus unserem System auf der CorPatch® Services Homepage https://app.corpatch.com
  • \n\n
  • Der/die Benutzer/in wird als gelöscht markiert. Danach kann er/sie sich nicht mehr anmelden, ist für Admins nicht mehr sichtbar, etc., der/die Benutzer/in existiert aber noch in der Datenbank.
  • \n\n
  • Nach 14 Tagen werden die Daten des/der Benutzers/Benutzerin automatisch aus der Datenbank gelöscht.
  • \n\n
  • Zum Zweck der wissenschaftlichen Auswertung und Funktionsverbesserung bleiben die Daten der Trainings und der Nutzung von CorPatch® auch nach der Löschung des Nutzers in der Datenbank bestehen, aber der Verweis (die ID) auf den/die Benutzer/in ist dann leer, und alle Verweise auf persönliche Daten werden entfernt.
  • \n
\n\n
\n\n\n
\n

Wie wir deine persönlichen Daten sammeln

\n\n

Die meisten persönlichen Daten, die wir verarbeiten, werden uns direkt von dir zur Verfügung gestellt. Wir sammeln Daten und verarbeiten Daten, wenn du:

\n
    \n
  • dich online registrierst oder eine Bestellung für eines unserer Produkte oder eine unserer Dienstleistungen aufgibst; z. B. demografische Daten, E-Mail-Adresse, Zahlungsinformationen, Artikel, Bestellmenge, Rabattstufe und -häufigkeit. Einschließlich des Versands von Transaktions-E-Mails, z. B. Bestell-, Versand- und Erstattungsbestätigungen,
  • \n\n
  • dich an der gesendeten Kommunikation (E-Mail, SMS, Direktwerbung oder Telefon) beteiligst; z. B. Öffnungsrate, Klickrate und Zeit, die mit dem Lesen der E-Mails verbracht wird, Absenderdomäne und Art des E-Mail-Clients,
  • \n\n
  • freiwillig eine Kundenumfrage ausfüllst oder Feedback auf einem unserer Messageboards oder per E-Mail gibst.
  • \n
\n \n\n

Wir können persönliche Daten auch indirekt aus den folgenden Quellen in den folgenden Szenarien erhalten:

\n
    \n
  • Von Cookies: wenn du unsere Websites oder Apps besuchst; z. B. IP-Adresse, Land, angesehene Seiten, angesehene Produkte, Interaktionen/Klicks und Suchanfragen.
  • \n\n
  • Von dir oder einer anderen Person, die mit unserem Kunden verbunden ist. Diese Personen können ein/e Manager/in oder ein/e Kollege/Kollegin sein. Wenn der/die Kunde/Kundin, für den/die du arbeitest, Produkte oder Dienstleistungen von SmartResQ/CorPatch® über ein Partnerunternehmen von SmartResQ/CorPatch® kauft, können wir Informationen über dich von dem Partnerunternehmen sammeln.
  • \n\n
  • SmartResQ/CorPatch® Marketingpartnern, öffentlichen Quellen oder sozialen Netzwerken von Dritten.
  • \n\n
  • SmartResQ/CorPatch® kann persönliche Daten über dich, die aus einer Quelle gesammelt wurden, mit Informationen aus einer anderen Quelle kombinieren. Dadurch erhalten wir ein vollständigeres Bild von dir und können dir relevantere Dienste mit einem höheren Maß an Personalisierung anbieten.
  • \n
\n\n
\n\n\n
\n

Wie wir deine Daten verwenden

\n\n

Um unsere Kundenbeziehungen allgemein zu verwalten und unsere Kundenverpflichtungen zu erfüllen, benötigt SmartResQ/CorPatch® Informationen über dich in deiner Rolle als Kunde/Kundin oder wenn du einen Dienst nutzt. Die Zwecke der Verarbeitung dieser persönlichen Daten sind:

\n\n
    \n
  • Deine Bestellung zu bearbeiten, dein Konto zu verwalten,
  • \n
  • dir per E-Mail Sonderangebote für andere Produkte und Dienstleistungen zukommen zu lassen, von denen wir glauben, dass sie dir gefallen könnten,
  • \n\n
  • den Verkaufs- und Vertragsprozess für Kunden/Kundinnen durchzuführen,
  • \n\n
  • um die angeforderten Produkte und Dienstleistungen an die Kunden/Kundinnen zu liefern,
  • \n\n
  • um Lieferungen gemäß den mit dir oder den Kunden geschlossenen Vereinbarungen durchzuführen,
  • \n\n
  • um den Benutzern unserer Produkte und Dienstleistungen Support zu bieten,
  • \n\n
  • die Qualität, Funktionalität und Benutzerfreundlichkeit unserer Produkte, Dienstleistungen und SmartResQ/CorPatch® Website(s) und Apps zu verbessern und weiterzuentwickeln,
  • \n\n
  • Sicherheitsbedrohungen zu erkennen, einzuschränken und zu verhindern sowie Wartung, Fehlerbehebung und Fehlersuche durchzuführen,
  • \n\n
  • den Missbrauch unserer Produkte und Dienstleistungen zu verhindern,
  • \n\n
  • um Bestellungen, Rechnungen, Zahlungen oder andere finanzielle Folgemaßnahmen zu bearbeiten,
  • \n\n
  • Interessenprofile zu erstellen, um relevante Produkte und Dienstleistungen zu bewerben,
  • \n\n
  • Benutzergemeinschaften aufzubauen, um die Interaktion zwischen Benutzern/Benutzerinnen und SmartResQ/CorPatch® zu fördern.
  • \n\n
\n\n

Über Kundenkontakte

\n\n

SmartResQ/CorPatch® verarbeitet persönlichen Daten von Kundenkontakten zu Marketingzwecken. Um potenziellen Kunden zielgerichtete und relevante Inhalte anbieten zu können, erstellt SmartResQ/CorPatch® ein Interessenprofil, das auf deiner Aktivität und deinen Entscheidungen und Handlungen auf den SmartResQ/CorPatch® Seiten sowie auf deiner Reaktion auf Marketinginhalte basiert. Die Rechtsgrundlage für diese Verarbeitung ist in erster Linie deine Zustimmung.

\n\n

Über Arbeitssuchende

\n\n

Wenn du ein/e Arbeitssuchender/Arbeitssuchende bist, verarbeiten wir persönliche Daten, um dein Potenzial als SmartResQ/CorPatch® Mitarbeiter/in zu bewerten. Unsere sichere Online-Karriereplattform stellt sicher, dass wir die neuesten Gesetze und Vorschriften in Bezug auf den Datenschutz einhalten. Die Rechtsgrundlage für diese Verarbeitung ist deine Zustimmung.

\n\n

Über Website-Besucher

\n\n

Um den Zugriff auf unsere Websites zu überwachen, verarbeiten wir persönliche Daten über die Besucher. Die Verarbeitung basiert auf unserem berechtigten Interesse, unsere Geschäftsgeheimnisse, Mitarbeiter, Standorte und dich als Besucher/in zu schützen. Du wirst über deine Rechte in diesem Zusammenhang informiert, wenn du dich in unserem elektronischen Besuchersystem registrierst.

\n\n

Um die Qualität der HLW zu verbessern, insbesondere durch HLW-Trainings, kann SmartResQ/CorPatch® deine Daten an unsere Partnerunternehmen (Training Institute) weitergeben, damit diese dir ihre Produkte und Dienstleistungen anbieten können.

\n\n

Wenn wir deine Bestellung bearbeiten, kann unser System deine Daten an Kreditauskunfteien senden und die daraus resultierenden Informationen nutzen, um betrügerische Käufe zu verhindern.

\n\n
\n\n\n
\n

Wie speichern wir deine persönlichen Daten?

\n\n

SmartResQ/CorPatch® nimmt das Vertrauen, das du und unsere Kunden uns entgegenbringen, sehr ernst. SmartResQ/CorPatch® verpflichtet sich, den unbefugten Zugriff, die Weitergabe oder eine andere abweichende Verarbeitung persönlicher Daten zu verhindern. SmartResQ/CorPatch® stellt die Vertraulichkeit der von uns verarbeiteten persönlichen Daten sicher, wahrt die Integrität der persönlichen Daten und gewährleistet ihre Zugänglichkeit in Übereinstimmung mit den geltenden Datenschutzgesetzen.

\n\n

Im Rahmen unserer Verpflichtungen ergreifen wir angemessene und geeignete organisatorische, technische und physische Verfahren und Maßnahmen, um die von uns erhobenen und verarbeiteten Daten zu schützen. Wir berücksichtigen die Art der persönlichen Daten und das Risiko, dem unsere Kunden durch eine Sicherheitsverletzung ausgesetzt sind. Da die Ursachen für Verstöße gegen persönliche Daten mit hoher Wahrscheinlichkeit intern zu finden sind, glauben wir, dass der Aufbau einer starken Unternehmenskultur, in der Respekt und Wachsamkeit in Bezug auf den Datenschutz unter unseren Mitarbeitern grundlegend sind, um die rechtmäßige Verarbeitung und den Schutz deiner Daten zu gewährleisten. Im Falle einer Datenpanne wird SmartResQ/CorPatch® die vom dänischen Datatilsynet festgelegten Praktiken anwenden.

\n\n

Deine Daten werden gemäß den Bestimmungen der DSGVO sicher gespeichert.

\n\n
\n\n\n
\n

Wie lange bewahren wir deine persönlichen Daten auf?

\n\n

SmartResQ/CorPatch® bewahrt deine persönlichen Daten nur so lange auf, wie es für die genannten Zwecke notwendig ist. Dabei berücksichtigen wir, dass wir auf Anfragen reagieren und Probleme lösen müssen und dass wir die rechtlichen Anforderungen nach geltendem Recht erfüllen.

\n\n

Das bedeutet, dass SmartResQ/CorPatch® deine persönlichen Daten für einen angemessenen Zeitraum nach der letzten Interaktion mit dir und unseren Kunden speichern kann. Wenn die von uns erhobenen persönlichen Daten nicht mehr erforderlich sind, löschen wir sie. Wir können Daten für statistische und/oder wissenschaftliche Zwecke verarbeiten, aber in solchen Fällen werden die Daten pseudonymisiert oder anonymisiert.

\n\n \n \n\n

Zeitrahmen für die Datenspeicherung

\n\n

Wir bewahren deine persönlichen Daten so lange auf, wie es für die Erfüllung der in diesen Datenschutz-Bestimmungen genannten Zwecke erforderlich ist, es sei denn, eine längere Aufbewahrungsfrist ist gesetzlich vorgeschrieben oder zulässig, aus rechtlichen, steuerlichen oder behördlichen Gründen oder aus anderen legitimen und rechtmäßigen Geschäftszwecken.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Zweck Zeitrahmen
Kundendienst und Buchhaltungsvorschriften 5 Jahre oder so lange, wie wir verpflichtet sind, die erforderlichen gesetzlichen Anforderungen zu erfüllen. \n
\nWir löschen deine Anmeldedaten, sobald du dein Benutzerkonto bei uns löschst oder wenn die gesetzliche Aufbewahrungsfrist abgelaufen ist. \n
Karriereplattform 6 Monate für Bewerbungsunterlagen, die nicht zu einer Einstellung des Bewerbers/der Bewerberin führen. \n
\n \n\nErneuerung alle 6 Monate, wenn du für zukünftige Stellenangebote berücksichtigt werden möchtest und du einer längeren Speicherdauer zustimmst. \n
Marketingzwecke 3 Jahre nach deiner letzten Aktivität, z. B. Besuch unserer Websites, Kauf oder Beteiligung an der Kommunikation. \n
\n \n\nWenn du uns deine Erlaubnis für Marketingzwecke (E-Mail, SMS, Telefon usw.) gegeben hast und solange wir deine Erlaubnis haben, dich zu kontaktieren. \n
\n \n\nWir löschen deine E-Mail-Adresse im Newsletter automatisch, wenn du dein Benutzerkonto löschst oder dich von unserem Newsletter abmeldest. \n
Speicherung der Bestellhistorie und Verpflichtungen zur Erfüllung von Bestellungen 5 Jahre oder so lange, wie wir verpflichtet sind, die erforderlichen gesetzlichen Anforderungen zu erfüllen
Kundenerfahrung 3 Jahre nach deiner letzten Aktivität, z. B. Besuch unserer Websites, Kauf oder Beteiligung an der Kommunikation. \n
\n \n\nWenn du deine Zustimmung zu Marketingmaßnahmen (E-Mail, SMS, Telefon usw.) gegeben hast und solange wir deine Zustimmung haben. \n
Betrug und Risikobewertung 5 Jahre oder so lange, wie wir verpflichtet sind, die erforderlichen gesetzlichen Anforderungen zu erfüllen.
\n \n
\n \n \n\n
\n

Marketingmitteilungen

\n\n

Du hast das Recht, den Erhalt von Marketingmitteilungen von SmartResQ/CorPatch® abzulehnen und kannst dies tun, indem du eines der folgenden Dinge tust:

\n
    \n
  • die Anweisungen zur Abmeldung in den jeweiligen Marketingmitteilungen befolgen,
  • \n\n
  • deine Einstellungen im entsprechenden Bearbeitungsbereich deines Kontos ändern, wenn du ein Konto bei SmartResQ/CorPatch® hast,
  • \n\n
  • uns per E-Mail unter info@corpatch.com kontaktieren.
  • \n
\n \n\n

Bitte beachte, dass du auch dann administrative Nachrichten von SmartResQ/CorPatch® erhalten kannst, wenn du dich gegen den Erhalt von Marketingmitteilungen entscheidest, z. B. Auftragsbestätigungen und Mitteilungen, die für die Verwaltung deines Kontos oder der Dienste, die wir unseren Kunden z. B. über mobile Dienste oder Apps anbieten, notwendig sind.

\n\n
\n\n\n
\n

Deine Datenschutzrechte

\n\n

Für SmartResQ/CorPatch® ist es wichtig, dass du über alle deine Datenschutzrechte Bescheid weißt.

\n\n

Einige Datenschutzgesetze, darunter die Allgemeine Datenschutzverordnung (DSGVO) der Europäischen Union, die entsprechenden Gesetze in Deutschland, dem Bundesdatenschutzgesetz (BDSG), in der Schweiz und im Vereinigten Königreich sowie einige Gesetze der US-Bundesstaaten, gewähren dir bestimmte Rechte im Zusammenhang mit persönlichen Daten, die du uns mitgeteilt hast. Wenn du im Europäischen Wirtschaftsraum wohnhaft bist, hast du unter Umständen die folgenden Rechte:

\n
    \n
  1. Dein Recht auf Auskunft – Du hast das Recht, von uns Kopien deiner persönlichen Daten zu verlangen.
  2. \n\n
  3. Dein Recht auf Berichtigung – Du hast das Recht, von uns zu verlangen, dass wir persönliche Daten berichtigen, von denen du glaubst, dass sie unrichtig sind. Du hast auch das Recht, uns aufzufordern, Informationen zu vervollständigen, die du für unvollständig hältst.
  4. \n\n
  5. Dein Recht auf Löschung – Du hast das Recht, von uns zu verlangen, deine persönlichen Daten unter bestimmten Bedingungen zu löschen.
  6. \n\n
  7. Dein Recht auf Einschränkung der Verarbeitung – Du hast das Recht, von uns zu verlangen, dass wir die Verarbeitung deiner persönlichen Daten unter bestimmten Bedingungen einschränken.
  8. \n\n
  9. Dein Recht, der Verarbeitung zu widersprechen – Du hast das Recht, der Verarbeitung deiner persönlichen Daten unter bestimmten Bedingungen zu widersprechen.
  10. \n\n
  11. Dein Recht auf Datenübertragbarkeit – Du hast das Recht zu verlangen, dass wir die von uns erhobenen persönlichen Daten unter bestimmten Bedingungen an eine andere Organisation oder direkt an dich weitergeben.
  12. \n\n
\n\n

Wenn du eines dieser Rechte ausüben möchtest, kontaktiere uns bitte per E-Mail: info@corpatch.com.

\n\n
\n\n\n
\n

Was sind Cookies?

\n\n

Cookies sind kleine Textdateien, die eine Zeichenkette enthalten und eine eindeutige Kennung für einen Benutzer erstellen. Sie werden an die Website und/oder an Dritte zurückgegeben. Die meisten Browser sind von vornherein so eingestellt, dass sie Cookies akzeptieren, da die meisten Websites auf sie zugreifen müssen. Du kannst deine Browsereinstellungen jedoch so ändern, dass dein Browser Cookies generell ablehnt, Cookies von Dritten blockiert oder festlegt, wann ein Cookie gesendet wird.

\n \n \n\n

SmartResQ/CorPatch® setzt sich dafür ein, dass du das Recht hast, deine Interessen anzupassen und den Umfang des digitalen Marketings von uns durch ein System der bevorzugten Verwaltung zu steuern.

\n\n
\n\n\n
\n

Wie wir Cookies verwenden

\n\n

SmartResQ/CorPatch® verwendet Cookies auf verschiedene Weise, um deine Erfahrung auf unseren Websites, Apps und Diensten aus verschiedenen Gründen zu verbessern, z. B:

\n
    \n
  • Funktionalität – Wir verwenden diese Cookies, um dich auf unserer Website wiederzuerkennen und deine zuvor gewählten Einstellungen zu speichern. Dazu gehören z. B. die von dir bevorzugte Sprache und der Ort, an dem du dich befindest. Es wird eine Mischung aus Erstanbieter- und Drittanbieter-Cookies verwendet.
  • \n\n
  • Werbung – Wir verwenden diese Cookies, um Informationen über deinen Besuch auf unseren Websites und Apps, die von dir angesehenen Inhalte, die Links, denen du gefolgt bist, sowie Informationen über deinen Browser, dein Gerät und deine IP-Adresse zu sammeln. Manchmal teilen wir einige begrenzte Aspekte dieser Daten mit Dritten zu Werbezwecken. Wir können die durch Cookies gesammelten Online-Daten auch mit unseren Werbepartnern teilen. Das heißt, wenn du eine andere Website besuchst, wird dir möglicherweise Werbung angezeigt, die auf deinem Surfverhalten auf unserer Website basiert.
  • \n
\n\n
\n\n\n
\n

Die Art der Cookies, die wir verwenden

\n\n

Unsere Website(s) verwenden die folgenden Arten von Cookies:

\n
    \n
  • Google Analytics: Dieses Cookie ermöglicht es uns, Informationen über die Website-Aktivitäten der Benutzer einzusehen, einschließlich, aber nicht beschränkt auf Seitenaufrufe, Quelle und Verweildauer auf einer Website. Die Informationen sind anonymisiert und werden als Zahlen angezeigt, was bedeutet, dass sie nicht zu einzelnen Personen zurückverfolgt werden können. Das hilft, deine Privatsphäre zu schützen. Durch den Einsatz von Google Analytics können wir sehen, welche Inhalte auf unseren Seiten beliebt sind, und wir bemühen uns, dir mehr von dem zu bieten, was du gerne liest und siehst.
  • \n\n
  • Google Analytics Remarketing: Legt Cookies auf deinem Computer ab. Das bedeutet, dass Google dir beim Verlassen unserer Seite möglicherweise Anzeigen zu SmartResQ/CorPatch® zeigt, die dich aufgrund deines vorherigen Verhaltens auf unserer Website interessieren könnten. Diese Informationen sind nicht persönlich identifizierbar.
  • \n\n
  • Google Ads: Durch die Nutzung von Google Ads können wir sehen, welche Seiten dazu führten, dass jemand unser Kontaktformular ausfüllte. Diese Informationen sind nicht persönlich identifizierbar, wohl aber die Daten, die im Kontaktformular angegeben werden.
  • \n\n
  • Google Ads Remarketing: Legt Cookies auf deinem Computer ab. Das bedeutet, dass Google dir beim Verlassen unserer Seite möglicherweise Anzeigen zu SmartResQ/CorPatch® zeigt, die dich aufgrund deines vorherigen Verhaltens auf unserer Website interessieren könnten. Diese Informationen sind nicht persönlich identifizierbar.
  • \n\n
  • Facebook Remarketing: Das Tracking-Pixel von Facebook platziert Cookies auf deinem Computer, die Facebook mitteilen, dass du die Seite besucht hast. Wir gehen dann davon aus, dass du ein Interesse an SmartResQ/CorPatch® und den Inhalten auf dieser Seite hast. Wenn du Facebook besuchst, werden dir dann Informationen oder Werbung mit ähnlichem Inhalt angezeigt. Bitte verwende deine Privatsphäre-Einstellungen auf Facebook, um die Exposition gegenüber dieser Art von Marketing einzuschränken.
  • \n\n
  • YouTube: Wir integrieren Videos von der YouTube-Plattform, die von Google (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA) bereitgestellt wird. Datenschutzrichtlinie: https://www.google.com/policies/privacy/.
  • \n
\n\n
\n\n\n
\n

Wie Cookies verwaltet werden

\n\n

Du kannst deinen Browser so einstellen, dass er Cookies nicht akzeptiert oder löscht. Allerdings kann es sein, dass dadurch einige Funktionen unserer Website nicht funktionieren. Hier erfährst du, wie du Cookies in bestimmten Browsern vermeiden kannst:

\n\n\n

SmartResQ/CorPatch® nutzt einige vertrauenswürdige Dienste Dritter auf unseren Seiten. Diese Dienste können Cookies verwenden. Du kannst Cookies von Drittanbietern in deinem Browser ablehnen, indem du diesem Link folgst.

\n\n

Du kannst die Erfassung und Verarbeitung der durch das Google-Cookie erzeugten Informationen über deine Nutzung unserer Seiten durch Google verhindern, indem du das Google Analytics Opt-out Browser Add-on für deinen aktuellen Webbrowser herunterlädst und installierst. Dieses Add-on ist hier erhältlich.

\n\n
\n\n\n
\n\n

Datenschutzrichtlinien von anderen Websites

\n\n

SmartResQ/CorPatch® Websites enthalten Links zu anderen Websites. Unsere Datenschutzrichtlinie gilt nur für unsere Website. Wenn du also auf einen Link zu einer anderen Website klickst, solltest du deren Datenschutzrichtlinie lesen.

\n\n
\n\n\n
\n

Änderungen an unserer Datenschutzrichtlinie

\n\n

Wenn wir unsere Datenschutzerklärung ändern, werden wir die überarbeitete Erklärung hier mit einem aktualisierten Änderungsdatum veröffentlichen. Wir empfehlen dir, die Erklärung regelmäßig zu lesen. Wenn wir wesentliche Änderungen an unserer Erklärung vornehmen, die unsere Datenschutzpraktiken erheblich verändern, können wir dich auch auf andere Weise benachrichtigen, z. B. per E-Mail oder durch einen Hinweis auf unserer Website und/oder in den sozialen Medien, bevor die Änderungen in Kraft treten.

\n\n
\n\n\n
\n

Wie du SmartResQ ApS kontaktieren kannst

\n\n

Wenn du Fragen zu den Datenschutzrichtlinien von SmartResQ/CorPatch® hast, zu den Daten, die wir über dich gespeichert haben, oder wenn du eines deiner Datenschutzrechte ausüben möchtest, zögere bitte nicht, uns zu kontaktieren.

\n\n

E-Mail: info@corpatch.com

\n\n

Website: https://corpatch.com

\n\n
\n\n\n
\n\n

Wie man die zuständige Behörde kontaktiert

\n\n

Wenn du eine Beschwerde einreichen möchtest oder das Gefühl hast, dass SmartResQ/CorPatch® dein Anliegen nicht zufriedenstellend behandelt hat, kannst du dich an das Information Commissioner's Office (ICO) wenden.

\n\n

Die Adresse des ICO:\n

\nInformation Commissioner's Office \n
\nWycliffe House \n
\nWater Lane \n
\nWilmslow \n
\nCheshire \n
\nSK9 5AF

\n\n \n\n

Helpline-Nummer: +44 303 123 1113

\n\n

ICO-Website: https://www.ico.org.uk

\n\n

© SmartResQ ApS – Alle Rechte vorbehalten \n
\nDänemark, Version 1.3 – Veröffentlicht 2023.04.25

\n\n
\n
\n\n`\n\nexport const termsOfUse_da_DA: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n
\n\n \n\n \n
\n

Vilkår & Privatlivspolitik

\n

SmartResQ ApS / CorPatch®

\n \n \n
\n\n\n
\n\n\n

Vilkår – SmartResQ ApS / CorPatch®

\n\n

Formålet med dette dokument

\n\n

Velkommen til SmartResQ/CorPatch®!

\n\n \n\n

Du er i gang med at læse vores Vilkår, som er et dokument, der indeholder information om dit forhold til SmartResQ ApS, som startede, da du gik ind på vores website, downloadede vores gratis app(s), købte et af vores produkter eller lignende.

\n\n \n\n

SmartResQ/CorPatch® og vores associerede selskaber leverer vores produkter og tjenester til dig på følgende betingelser. Hvis du besøger eller handler på vores website(s) eller app(s), accepterer du disse betingelser. Vi anbefaler på det kraftigste, at du læser dem nøje, inden du begynder at bruge vores produkter eller tjenester.

\n\n \n\n

Dette dokument omhandler følgende:

\n
    \n
  • Sådan kan SmartResQ ApS kontaktes
  • \n\n
  • Produkter, ejendomsret og korrekt brug
  • \n\n
  • Ansvarsfraskrivelse og garantier
  • \n\n
  • Bestilling
  • \n\n
  • Betaling
  • \n\n
  • Levering
  • \n\n
  • Forpligtelser og rettigheder i forbindelse med salg
  • \n\n
  • Returnering af produkter
  • \n\n
  • Databehandling af personoplysninger
  • \n\n
  • Klager
  • \n\n
  • Ændringer af dette dokument
  • \n\n
  • Lovvalg og værneting
  • \n\n
  • Kontaktoplysninger
  • \n
\n \n\n

Hvis du har spørgsmål vedrørende SmartResQs Vilkår, er du velkommen til at kontakte os.

\n\n \n\n

Sådan kan SmartResQ ApS kontaktes

\n\n

Hos SmartResQ har vi til formål at øge overlevelsen ved hjælp af hjerte-lunge-redning af høj kvalitet i tilfælde af hjertestop. Vi ønsker at forberede og vejlede vidner til et hjertestop, så de kan gribe ind allerede i de første afgørende minutter. Derfor har vi udviklet CorPatch® – Vi hjælper dig med at redde liv.

\n\n \n\n

Vores virksomhed ligger på adressen Lundevej 26, 5700 Svendborg

\n

Du kan finde os i det Centrale Virksomhedsregister under CVR-nr. 38674102

\n\n \n\n

Du kan ringe til os på telefonnummer +45 62 200 100

\n\n \n\n

eller

\n\n \n\n

skrive en e-mail til os på info@corpatch.com

\n\n \n\n

Har du spørgsmål, kommentarer eller klager?

\n\n

Vi sætter pris på din mening, og du er meget velkommen til at kontakte os via ovennævnte kontaktoplysninger eller bruge kontaktformularen på vores website(s) eller app(s).

\n\n
\n \n\n
\n

Produkter, ejendomsret og korrekt brug

\n\n

Vores website(s), apps og produkter

\n\n

Følgende afsnit beskriver vigtige egenskaber, rettigheder og forpligtelser i forbindelse med brugen af SmartResQ/CorPatch®-tjenester, -apps og -produkter. \n
\n

Vi bestræber os på i rimelig grad at inkludere nøjagtige og opdaterede oplysninger på website(s) og i apps. SmartResQ/CorPatch® udsteder imidlertid ingen garantier eller erklæringer vedrørende nøjagtigheden af oplysningerne. Vi påtager os intet ansvar for eventuelle fejl eller udeladelser i websitets indhold, produkter og apps. Oplysningerne på dette website eller i apps erstatter ikke lægebehandling. Vi påtager os ansvar for vores produkter og apps i overensstemmelse med forordning EU 745/2017 om medicinsk udstyr (MDR).

\n\n \n\n

Ophavsret

\n\n

Alt indhold på dette website som f.eks. tekst, grafik, logoer, knapikoner, billeder, lydklip, digitale downloads, datasamlinger og software, tilhører SmartResQ/CorPatch® eller dets indholdsleverandører og er beskyttet af internationale ophavsretslove. Det ophavsretlige forfatterskab af al data og indhold på ovenstående medier er ejet af SmartResQ/CorPatch® og er dermed beskyttet af internationale ophavsretslove.

\n\n \n\n

Registrerede varemærker og design

\n\n

SmartResQ/CorPatch®'s varemærker, handelsmærker og produktdesign må ikke anvendes i forbindelse med noget produkt eller nogen tjeneste, som ikke er SmartResQ/CorPatch®, på en måde som kan skabe forvirring hos kunderne, eller på en måde som nedgør eller bringer SmartResQ/CorPatch® i miskredit. Alle andre varemærker, der ikke ejes af SmartResQ/CorPatch® eller dets datterselskaber, og som vises på dette website, tilhører deres respektive ejere, som kan være men ikke nødvendigvis er tilknyttet til, forbundet med eller sponsoreret af SmartResQ/CorPatch® eller dets datterselskaber.

\n\n \n\n

Licens og adgang til websitet

\n\n

SmartResQ/CorPatch® giver dig en begrænset licens til at tilgå og gøre personlig brug af vores website(s) og apps men ikke til at downloade (bortset fra page caching) eller ændre disse eller dele heraf, medmindre der er indhentet udtrykkeligt skriftligt samtykke fra SmartResQ/CorPatch®. Denne licens omfatter ikke videresalg eller kommerciel brug af disse website(s) eller apps eller deres indhold: (a) indsamling og brug af produktfortegnelser, beskrivelser eller priser; (b) afledt brug af dette website eller dets indhold; (c) download eller kopiering af kontooplysninger til fordel for en anden handlende; eller (d) brug af datamining, robotter eller lignende værktøjer til indsamling og udtræk af data.

\n\n \n\n

Hverken dette website eller apps eller dele heraf må reproduceres, ombygges, duplikeres, kopieres, sælges, videresælges, besøges eller på anden måde udnyttes til noget kommercielt formål uden udtrykkeligt skriftligt samtykke fra SmartResQ/CorPatch®. Det er ikke tilladt at frame eller bruge framingteknikker til at inkludere varemærker, logoer eller andre ophavsretligt beskyttede oplysninger (herunder billeder, tekst, sidelayout eller form) tilhørende SmartResQ/CorPatch® og vores associerede selskaber uden udtrykkeligt skriftligt samtykke.

\n\n \n\n

Det er ikke tilladt at bruge metatags eller anden \"skjult tekst\", der anvender SmartResQ/CorPatch®'s navn eller varemærker uden udtrykkeligt skriftligt samtykke fra SmartResQ/CorPatch®. Ved uautoriseret brug annulleres den tilladelse eller licens, der er givet af SmartResQ/CorPatch®.

\n\n \n\n

Du får en begrænset, genkaldelig og ikke-eksklusiv ret til at oprette et hyperlink til SmartResQ/CorPatch®'s hjemmeside, såfremt linket ikke fremstiller SmartResQ/CorPatch®, dets associerede selskaber eller dets produkter eller tjenester på en falsk, vildledende, nedsættende eller anden krænkende måde. Du må ikke bruge noget SmartResQ/CorPatch®-logo eller anden ophavsretligt beskyttet grafik eller varemærke som en del af linket uden udtrykkelig skriftlig tilladelse. \n
\nVed brud på aftalen om licens og adgang til websitet vil der blive taget retslige skridt, og der kan blive lagt sag an ved domstolene.

\n\n

Elektronisk kommunikation

\n\n

Når du besøger SmartResQ/CorPatch®'s hjemmeside og sociale medier eller sender e-mails til os, kommunikerer du med os elektronisk. Du accepterer at modtage kommunikation fra os elektronisk. Vi vil kommunikere med dig via e-mail eller ved at offentliggøre meddelelser på vores websites eller i apps i form af pop-up-notifikationer. Du accepterer, at alle aftaler, meddelelser, offentliggørelser og anden kommunikation, som vi sender til dig elektronisk, opfylder ethvert lovkrav om, at sådan kommunikation skal være skriftlig. Se vores Privatlivspolitik i et særskilt dokument, som kan findes på vores hjemmeside.

\n\n \n\n

Besøgende på vores website og sociale medier kan blive opfordret til at poste anmeldelser, kommentarer og andet indhold som f.eks. forslag, idéer, kommentarer, spørgsmål eller anden information, når blot indholdet ikke er ulovligt, stødende, truende, nedgørende, krænkende for privatlivet, krænker immaterielle rettigheder eller på anden måde er sårende over for tredjeparter eller anstødeligt og ikke består af eller indeholder softwarevirusser, politiske kampagner, reklamer, kædebreve, masseudsendelse af e-mails eller nogen form for \"spam\".

\n\n \n\n

Du må ikke bruge en falsk e-mailadresse, udgive dig for at være/repræsentere en fysisk eller juridisk person eller på anden måde vildlede omkring oprindelsen af et kort eller andet indhold. SmartResQ/CorPatch® forbeholder sig ret (men er ikke forpligtet) til at fjerne eller redigere sådant indhold men gennemgår ikke postet indhold regelmæssigt. Hvis du poster indhold eller fremsender materiale, og medmindre vi anfører andet, giver du SmartResQ/CorPatch® og dets associerede selskaber en ikke-eksklusiv, royaltyfri, tidsubegrænset, uigenkaldelig og fuldt underlicenserbar ret til at bruge, reproducere, ændre, tilpasse, offentliggøre, oversætte, skabe afledte værker af, distribuere og vise sådant indhold globalt i alle medier. Du giver SmartResQ/CorPatch® og dettes associerede selskaber og underlicenstagere ret til at bruge det navn, som du indsender i forbindelse med sådant indhold, hvis de ønsker det.

\n\n \n\n

Du erklærer og garanterer, at du ejer eller på anden måde kontrollerer alle rettighederne til det indhold, som du poster; at indholdet er nøjagtigt; at brugen af indholdet, som du leverer, ikke overtræder denne politik og ikke vil medføre skade på nogen fysisk eller juridisk person; og at du vil holde SmartResQ/CorPatch® eller dets associerede selskaber skadesløs for alle krav, som følger af det indhold, som du leverer. SmartResQ/CorPatch® har ret, men er ikke forpligtet, til at overvåge og redigere eller fjerne enhver aktivitet eller indhold. SmartResQ/CorPatch® påtager sig ikke noget ansvar for indhold, der postes af dig eller en tredjepart.

\n\n
\n\n\n
\n

Ansvarsfraskrivelse og garantier

\n\n

Produktinformation – CorPatch® og CorPatch® Trainer

\n\n

For korrekt brug af et SmartResQ/CorPatch®-produkt eller -tjeneste skal du altid følge de seneste brugervejledninger, instruktioner og beskrivelser. Disse kan findes på vores website og under hver produktbeskrivelse.

\n\n \n\n

Produktet CorPatch® er certificeret som medicinsk udstyr. I en nødsituation med en voksen, der får hjertestop, skal produktet tages ud af sit hylster og placeres og fastgøres korrekt på personens brystkasse. Produktet kan indsamle oplysninger om kompression, dybde, frekvens og recoil og kan overføre disse via Bluetooth® til potentielle enheder. Gratis apps på enheder kan hjælpe vidner med at udføre hjerte-lunge-redning og vise flow-fraction, dybde, recoil og frekvens, hvis de er aktiveret og korrekt installeret, dvs. Bluetooth®, smartphone, app, batteristrøm etc. SmartResQ/CorPatch® er ikke ansvarlig for eksterne faktorer som f.eks. forstyrrende kommunikationssignaler, manglende datadækning, mangel på batteri, forkerte hardware- og softwareindstillinger, der kan påvirke brugeroplevelsen eller lignende.

\n\n \n\n

Ligeledes er SmartResQ/CorPatch® ikke ansvarlig for fysiske skader, der måtte opstå under brugen af produktet, hvis det ikke er påsat eller anvendt i overensstemmelse med instruktionerne, f.eks. udførelse af brystkompressioner på en ikke-ergonomisk måde eller en uhensigtsmæssig håndposition. SmartResQ/CorPatch® har vurderet tekniske risici som en del af den lovbestemte risikostyring for medicinsk udstyr, men der gives ingen garanti for fejl, der går ud over dette. I tilfælde af uventet fejlfunktion af SmartResQ/CorPatch®-systemet, eller hvis det opfører sig mærkeligt, skal brugeren udføre hjerte-lunge-redning manuelt. I så fald er SmartResQ/CorPatch® ikke ansvarlig, da det er uden for SmartResQ/CorPatch®'s kontrol. \n
\nSmartResQ/CorPatch® overvåger batteriniveauer og produktets tilstand, men hvis batteriet løber tør for strøm, fungerer produktet ikke. Det er alene brugerens ansvar at sikre, at enheden er opdateret, ikke beskadiget og har tilstrækkeligt batteri til at fungere korrekt. Dette kan nemt gøres ved at udføre en træning, der validerer korrekt funktionalitet. Vi anbefaler træning i 4 minutter hver 3. måned med din CorPatch®.

\n\n \n\n

Vigtigt! Produktet CorPatch® må kun bruges på en person i en virkelig situation, og kun hvis en person har hjertestop. Det er ikke beregnet til at blive brugt på personer, der har f.eks. slagtilfælde, hjerteanfald eller andre hjerterelaterede sygdomme, der ikke er hjertestop. CorPatch® er ikke beregnet til at blive brugt på en person, der ligger på et blødt underlag som f.eks. en sofa eller seng, da feedback om dybde under sådanne forhold kan være unøjagtig. Ingen SmartResQ/CorPatch®-løsninger er beregnet til brug i et miljø i bevægelse, herunder bl.a. luft-, båd- eller vejambulance. Hvis enheden anvendes under patienttransport eller løftes/fjernes fra kroppen under hjerte-lunge-redning, kan den give unøjagtig feedback. CorPatch® skal fastgøres på patientens brystkasse med patchet. Sørg for, at patienten ligger på et fast, plant underlag, der ikke bevæger sig, og at CorPatch® er fastgjort på brystkassen med patchet.

\n\n \n\n

Produktet CorPatch® Trainer må alene anvendes på dukker eller lignende i Training Sessions og aldrig i virkelige situationer på et rigtigt menneske med hjertestop eller andre hjerterelaterede sygdomme.

\n\n \n\n

Det er muligt regelmæssigt at træne HLR i forhold til brystkompressioner ved hjælp af CorPatch® eller CorPatch® Trainer. Vi anbefaler, at du øver dig på en dukke, men hvis du ikke har adgang til en sådan, kan du i stedet anvende en kontorstol med tilstrækkelig affjedring eller en hård sofa. Overvej elasticiteten og hårdheden af den genstand, du øver dig på. SmartResQ anbefaler ikke brug af bløde genstande, herunder bl.a. puder eller bløde sofaer, til træningsformål, da det ikke giver den rette brugeroplevelse.

\n\n\n

Hvis du ikke kan skaffe en dukke eller lignende til træning, kan du overveje at træne den situation, der opstår, inden du begynder på brystkompressioner. Dette kunne være at følge de anvisninger, som den gratis app giver i at identificere et hjertestop og ringe til alarmcentralen samt tage CorPatch® ud af nøgleringen. I så fald vil du være klar til hurtigt at påsætte CorPatch®, hvis du skulle overvære et hjertestop.

\n\n \n\n

Brug ikke SmartResQ/CorPatch®-systemet til træning eller \"for sjov\" på personer (levende eller døde), kæledyr eller andre levende væsener.

\n\n \n\n

Ansvarsfraskrivelse for produkter, website(s) og apps

\n\n

SmartResQ/CorPatch® udsteder ingen erklæringer eller garantier og er ikke ansvarlig for kompetencerne hos personer, der modtager undervisning og/eller medicinsk træning via eller baseret på systemet eller for udøvelsen af deres færdigheder efter afslutningen af eventuel træning, kurser eller undervisningsplan med anvendelse af systemet. SmartResQ/CorPatch® garanterer ikke, at personer, som modtager undervisning og/eller medicinsk træning fra systemet, vil opnå et bestemt færdighedsniveau eller den nødvendige kompetence til at kvalificere sig til en licens, certifikater eller bedømmelser udstedt af en tilsynsmyndighed eller statslig myndighed.

\n\n \n\n

SmartResQ/CorPatch® og dets associerede selskaber forsøger at være så nøjagtige som muligt. SmartResQ/CorPatch® giver imidlertid ikke nogen erklæringer eller garantier for, at systemet og informationen, produkterne og træningen, der anføres heri: (a) altid eller i det hele taget vil være tilgængelige; eller (b) er fri for fejl, komplette, nøjagtige, sande, opdaterede og/eller ikke-vildledende. Når du bruger systemet, er du bevidst om, at du fraskriver dig ethvert krav, som du måtte have mod SmartResQ/CorPatch® for at have stolet på information eller træning præsenteret i systemet.

\n\n \n\n

Vores produkter er ikke beregnet til at blive brugt af børn. Produkterne er små og farverige og kan forveksles med legetøj, men SmartResQ/CorPatch®-produkter er ikke legetøj! Vi anbefaler, at man ikke at lader produkterne ligge frit fremme og tilgængelige for børn. SmartResQ/CorPatch® påtager sig ikke noget ansvar for børns brug af produkterne. En ansvarlig voksen skal give tilladelse til og overvåge børns eller teenageres brug af CorPatch®, f.eks. forældre, familiemedlemmer eller lærere.

\n\n \n\n

Fraskrivelse af garanti og ansvarsbegrænsning, dette website leveres af SmartResQ/CorPatch® \"som det er\" og \"forefindes\". SmartResQ/CorPatch® udsteder ingen erklæringer eller garantier af nogen art, hverken udtrykkelige eller underforståede, vedrørende driften af dette website eller den information, det indhold og materiale eller de produkter, der ligger på det. Du accepterer udtrykkeligt, at din brug af websitet alene sker for egen risiko. \n
\nSå vidt det er tilladt i henhold til gældende lov, fraskriver SmartResQ/CorPatch® sig alle garantier, både udtrykkelige og underforståede, herunder bl.a. underforståede garantier for salgbarhed og egnethed til et bestemt formål. SmartResQ/CorPatch® garanterer ikke, at dette website, dets servere eller e-mails sendt fra SmartResQ/CorPatch® er fri for virus/spam eller andre skadelige komponenter.

\n\n \n\n

SmartResQ/CorPatch® hæfter ikke for skade af nogen art som følge af brugen af dette website eller dets produkter, herunder bl.a. direkte, indirekte og afledte skader, skadeserstatning og følgeskader. \n
\nLovgivningen i visse stater tillader ikke begrænsninger i underforståede garantier eller udelukkelse eller begrænsning af visse erstatninger. Hvis disse love gælder for dig, er det muligt, at nogle af eller alle ovenstående ansvarsfraskrivelser, udelukkelser eller begrænsninger ikke gælder for dig, og du kan have yderligere rettigheder.

\n\n \n\n

Informationen på dette website skal ikke fortolkes som professionel rådgivning. Du bør altid rådføre dig med professionelle rådgivere, der er bekendt med netop din situation, for at få råd om særlige forhold, inden du træffer en beslutning.

\n\n \n\n

Websitet kan indeholde links, som fører til websites, der drives af personer eller virksomheder, som SmartResQ/CorPatch® ikke har nogen kontrol over. SmartResQ/CorPatch® udsteder ingen erklæringer eller garantier vedrørende nøjagtigheden eller andre aspekter af den information, der ligger på sådanne websites.

\n\n \n\n

Ansvaret for eventuelle holdninger, råd, udsagn eller anden information i artikler eller tekster på dette website ligger alene hos forfatteren og afspejler ikke nødvendigvis SmartResQ/CorPatch®'s holdninger og politikker.

\n\n \n\n

Juridisk ansvarsfraskrivelse

\n\n

Når du køber, licenserer, kigger på, bruger og/eller tilgår vores website(s), produkter og apps, anerkender du og accepterer, at:

\n
    \n
  1. De systemer, der leveres af SmartResQ/CorPatch®, er specifikke produkter, som alene må bruges til de formål, der er anført i produktmanualen. Læs brugsanvisningerne og brugermanualerne nøje og sørg for at gøre dig bekendt med vores medicinske produkter inden brug.
  2. \n\n
  3. De systemer, der leveres af SmartResQ/CorPatch®, er særlige produkter og værktøjer til undervisning og medicinsk træning, som ikke er certificeret som medicinsk udstyr, medmindre andet er udtrykkeligt anført; de er ikke beregnet til klinisk eller diagnostisk brug men alene til medicinsk træning og forbedring af færdigheder.
  4. \n\n
  5. Du til enhver tid kun vil anvende og tilgå systemet i forbindelse med sådan medicinsk træning og forbedring af færdigheder; i overensstemmelse med alle gældende love og bestemmelser; og i overensstemmelse med brugerdokumentation, instruktionsmanualer, vejledninger og/eller krav, som vi udleverer til dig elektronisk eller personligt.
  6. \n\n
  7. Et SmartResQ/CorPatch®-system ikke på noget tidspunkt alene kan diagnosticere, behandle eller kurere et menneskes tilstand eller i en livreddende situation; understøtte professionelle medicinske beslutninger, diagnoser eller behandlinger eller erstatte en diagnose, anbefaling, rådgivning, behandling eller beslutning truffet af en behørigt uddannet og autoriseret læge.
  8. \n\n
  9. Hvis en enhed sættes i forbindelse med patientskade eller patientudfald, betyder det ikke, at enheden forårsagede skaden eller udfaldet.
  10. \n\n
  11. SmartResQ/CorPatch® ikke påtager sig noget ansvar for skade som følge af uhensigtsmæssig brug af vores produkter eller brug ud over den tilsigtede anvendelse af produktet.
  12. \n
\n \n\n

Oplysninger om funktion

\n\n

Informationen heri er alene præsenteret som en guide til anvendelse af SmartResQ/CorPatch®-produkter. SmartResQ/CorPatch® arbejder løbende på at forbedre kvaliteten og pålideligheden af sine produkter. Vores enheder kan imidlertid fungere forkert eller svigte på grund af deres indbyggede elektriske følsomhed og sårbarhed over for fysisk belastning og ugunstige kommunikationssignaler. Det er købers ansvar ved brug af SmartResQ/CorPatch®-produkter at overholde standarder for sikkerhed og afprøvning og at undgå situationer, hvor et funktionssvigt kan medføre personskade eller skade på ejendom.

\n\n \n\n

Standardgaranti

\n\n

SmartResQ/CorPatch® Standard Limited Warranty er betinget af korrekt brug af produkterne, website(s) og apps. \n
\nDenne garanti er begrænset til den første køber af produktet, og kun hvis produktet købes hos en autoriseret SmartResQ/CorPatch®-forhandler. Andre producenter, leverandører eller udgivere end SmartResQ/CorPatch® kan udstede deres egne garantier til dig – kontakt dem for yderligere information.

\n\n \n\n

Garantien dækker ikke:

\n
    \n
  1. defekter eller skade som følge af uheld, forkert brug, unormal brug, unormale forhold, forkert opbevaring, udsættelse for væske, fugt, sand eller snavs, forsømmelse eller usædvanlig fysisk, elektrisk eller elektromekanisk belastning,
  2. \n\n
  3. defekter eller skade som følge af overdreven brug af kraft eller brug af metalgenstande,
  4. \n\n
  5. udstyr, som har fået produktionsnummeret eller forbedringsdatakoden fjernet, udvisket, beskadiget, ændret eller gjort ulæseligt,
  6. \n\n
  7. almindelig slitage eller normal ældning af produktet,
  8. \n\n
  9. ridser, buler og kosmetiske skader, medmindre fejlen er opstået på grund af materiale- eller fabrikationsfejl,
  10. \n\n
  11. defekter eller skader som følge af brug af produkterne i forbindelse med tilbehør, produkter eller ekstraudstyr/periferiudstyr, der ikke er leveret eller godkendt af SmartResQ/CorPatch®,
  12. \n\n
  13. fejl eller skader som følge af ukorrekt afprøvning, drift, vedligeholdelse, installation, service eller justering, som ikke er leveret eller godkendt af SmartResQ/CorPatch®,
  14. \n\n
  15. skader forårsaget af betjening af SmartResQ/CorPatch®-produktet uden for de udsendte retningslinjer,
  16. \n\n
  17. demonstration/installation af det købte produkt,
  18. \n\n
  19. defekter eller skader som følge af eksterne årsager som f.eks. sammenstød med en genstand, brand, oversvømmelse, snavs, storm, lynnedslag, jordskælv, udsættelse for vejrforhold, tyveri, sprunget sikring eller forkert brug af en elektrisk kilde,
  20. \n\n
  21. defekter eller skader som følge af overførsel af virus eller andre softwareproblemer, der er indført i produkterne,
  22. \n\n
  23. hvis batterierne oplades med andre opladere end dem, der passer til CorPatch® Trainer,
  24. \n\n
  25. hvis forseglingerne på batterihuset eller -cellerne er brudt eller viser tegn på manipulation,
  26. \n\n
  27. produkter, der er repareret af, brugt eller købt hos et andet firma end SmartResQ/CorPatch®,
  28. \n\n
  29. hvis SmartResQ/CorPatch® modtager information fra relevante offentlige myndigheder om, at produktet er stjålet, eller hvis du ikke kan deaktivere adgangskodeaktiverede eller andre sikkerhedsmæssige foranstaltninger, der er beregnet til at forhindre uautoriseret adgang til produktet, eller du ikke kan bevise, at du er en autoriseret bruger af produktet,
  30. \n\n
  31. hvis produkterne anvendes uden for de angivne betingelser, der er anført i manualerne, f.eks. temperaturområde, tryk eller fugtighed.
  32. \n
\n \n\n

Batterier og opladere

\n\n

SmartResQ/CorPatch®-produkter indeholder enten ikke-udskiftelige batterier (CorPatch®) eller genopladelige batterier (CorPatch® Trainer). De typer af batterier, der anvendes i vores produkter, er beskrevet under hvert enkelt produkt. SmartResQ/CorPatch® påtager sig intet ansvar, hvis de genopladelige batterier ikke håndteres korrekt i henhold til brugermanualen.

\n\n \n\n

I forbindelse med salg af enheder, der indeholder batterier, er vi forpligtet til at gøre dig opmærksom på følgende: \n
\nSom slutbruger er du juridisk forpligtet til at bortskaffe dem korrekt. Symbolet med den overstregede skraldespand betyder, at batteriet ikke må smides ud med husholdningsaffaldet.

\n\n
\n\n\n
\n

Bestilling

\n\n

Corpatch.coms webshop er åben 24 timer i døgnet, og du kan købe næsten når som helst. Vi kan dog lukke butikken i forbindelse med vedligeholdelse. Køb i store mængder kan ske direkte hos SmartResQ/CorPatch®.

\n\n \n\n

SmartResQ/CorPatch® tilbyder ikke produkter til salg til mindreårige. Produkter, der er beregnet til børn, kan kun købes af voksne. For at købe hos SmartResQ/CorPatch® skal du være mindst 18 år og være i besiddelse af et gyldigt kreditkort eller et andet betalingsmiddel, som vi accepterer.

\n\n \n\n

Præsentationen af produkterne i webshoppen er ikke et juridisk bindende tilbud, men et uforpligtende online-katalog. Når du er klar til at handle, skal du vælge de varer, du ønsker at købe, og lægge dem i “indkøbskurven”. Du kan redigere indholdet af indkøbskurven helt indtil bestillingstidspunktet. Eventuelle ekstra omkostninger som f.eks. forsendelses- eller betalingskortgebyrer beregnes umiddelbart, før du betaler.

\n\n \n\n

Når du er klar til at bestille, skal du klikke på “Kassen” og indtaste relevante oplysninger. Du kan ændre indholdet af indkøbskurven, lige indtil du bekræfter dit køb, ved at klikke på knappen “Betal”. Herefter afgiver du en bindende ordre på de varer, der er indeholdt i indkøbskurven, som ikke længere kan ændres. \n
\nSmartResQ/CorPatch® kan acceptere ordren ved at sende en ordrebekræftelse pr. e-mail eller ved at levere varerne inden for leveringsfristen.

\n\n \n\n

Visse lande kan forhindre brugen og ejerskabet af vores produkter. Du er alene ansvarlig for at finde ud af, om dette produkt er lovligt at importere og/eller bruge i dit land. Vi sender dig de produkter, du bestiller, og kan ikke påtage os noget ansvar for toldproblemer eller eventuelle konsekvenser af dit ejerskab eller brug af denne enhed.

\n\n
\n\n\n
\n

Betaling

\n\n

Vores website(s), app(s) og webshop(s)

\n\n

Vores website(s) og app(s) er gratis at bruge, så længe vores juridiske politikker accepteres og overholdes. Vær opmærksom på, at køb af vores produkter kan være tilgængelige i webshop(s) på vores website(s) og i app(s).

\n\n \n\n

Vores produkter

\n\n

SmartResQ/CorPatch® bruger QuickPay som betalingsgateway. QuickPay er certificeret af Payment Card Industry (PCI) Security Standards Council efter den seneste udgave af PCI Data Security Standard (DSS) Level 1, som omfatter: (a) en årlig rapport – “Report on Compliance” (ROC) udført af en Qualified Security Assessor (QSA); (b) kvartalsvise netværksscanninger udført af Approved Scan Vendor (ASV) og (c) et stort antal regler og retningslinjer for arbejdsgang og behandling af oplysninger.

\n\n \n\n

Vi accepterer betaling med:

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • MasterCard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n \n\n

Betalingerne trækkes fra din konto ved forsendelse af varerne. Alle beløb er i euro, og den lovpligtige moms er allerede inkluderet i alle de nævnte priser. Alle indehavere af kredit-/debitkort er underlagt valideringskontrol og godkendelse fra kortudstederen eller betalingsudbyderen. SmartResQ/CorPatch® er ikke ansvarlig i tilfælde af, at din betalingskortudbyder nægter at godkende betalinger.

\n\n\n

Vi anvender kryptering af kreditkortoplysninger via SSL-protokollen (Secure Socket Layer). Dette sikrer, at andre ikke kan opsnappe kreditkortnummeret eller andre oplysninger under transaktionen med vores udbyder.

\n\n \n\n

Inden købet afsluttes, skal kunden gennemgå og acceptere de forsendelses- og logistikomkostninger, der er tilføjet til købsprisen, da kunden skal betale disse omkostninger. Når du har afgivet en ordre, modtager du en e-mail fra os med en bekræftelse på, at vi har modtaget din ordre. Bemærk venligst, at dette ikke betyder, at din ordre er blevet accepteret. Din ordre udgør et tilbud til SmartResQ/CorPatch® om at købe et produkt (og SmartResQ/CorPatch® forbeholder sig ret til at afvise ordrer på produkter). Der vil ikke være nogen kontrakt i forbindelse med produkterne, før vi har bekræftet over for dig pr. e-mail, at produktet/produkterne er afsendt. Vores accept af dit tilbud anses for at være fuldført, og kontrakten mellem os er indgået, når vi sender dig en bekræftelsesmail om afsendelse.

\n\n \n\n

Forsendelsesomkostningerne er altid angivet i forhold til hver enkelt ordre.

\n\n \n\n

SmartResQ/CorPatch® beholder ejendomsretten til den købte vare, indtil fakturabeløbet er betalt fuldt ud af kunden og automatisk “trukket” lige før forsendelse.

\n\n \n\n

Kunden er kun berettiget til at foretage modregning, hvis dennes modkrav er retligt fastslået eller er ubestridt eller anerkendt af SmartResQ/CorPatch®. Desuden har kunderne kun en tilbageholdelsesret, hvis og i det omfang deres modkrav er baseret på det samme kontraktforhold.

\n\n \n\n

Hvis kunden er i restance hos os med betalingsforpligtelser, forfalder alle eksisterende krav straks.

\n\n \n\n

Tillægsgebyrer

\n\n

Pr. 1. januar 2018 er reglerne for tillægsgebyrer blevet ændret. Det er derfor ikke længere lovligt at opkræve tillægsgebyrer på betalinger fra forbrugerkort, hvis de er udstedt af banker/kortudstedere inden for EU. Dette gælder både for debet- og kreditkort. Forbrugerkort er kort, der er udstedt til en privat forbruger. \n
\nHvis kortet imidlertid enten er et erhvervskort eller et forbrugerkort udstedt uden for EU, vil transaktionsgebyret blive pålagt et tillægsgebyr. Det betyder, at kortindehaveren automatisk betaler transaktionsgebyret. \n
\nGebyret vil ikke være højere end det gebyr, som SmartResQ/CorPatch® opkræves af indløseren. Gebyret vil tydeligt blive vist som en separat post i betalingsvinduet.

\n\n
\n\n\n
\n

Levering

\n\n

Vi bestræber os på at sende ordrer fra den ene hverdag til den anden og bruger et internationalt anerkendt forsendelsesfirma. Du finder den samlede pris for dit køb inklusiv levering ved Tjek ud, før du accepterer din endelige ordre.

\n\n \n\n

Hvis kunden ikke tager imod varerne, kan SmartResQ/CorPatch® udtræde af købskontrakten eller modtage erstatning for misligholdelse efter en periode på to uger for at dække håndterings- og forsendelsesomkostninger.

\n\n \n\n

Hvis kunden har givet forkerte oplysninger om leveringsadressen, er det muligt at afhente pakken i den pakkeshop, der er anført i vores webshop. Ellers er pakken tabt.

\n\n \n\n

Kunden vil aldrig modtage delleverancer, medmindre SmartResQ/CorPatch® udtrykkeligt har givet besked herom.

\n\n \n\n

Risiko for tab

\n\n

Risikoen for ejerskab af produktet overgår til køberen, når produktet stilles til rådighed for køberen i henhold til denne aftale. Hvis leveringstidspunktet er overskredet, og køber ikke modtager et produkt, der er gjort tilgængeligt eller stillet til rådighed for denne i henhold til aftalen, bærer køberen risikoen for tab eller skade som følge af egenskaber ved selve produktet.

\n\n
\n\n\n
\n

Annullering og returnering

\n\n

Når du handler med SmartResQ/CorPatch® online eller offline, har du 14 dage til at fortryde og annullere, hvor du kan informere os om, at du har ombestemt dig, og returnere varen til os i samme stand som den er modtaget. \n
\nVi accepterer kun ubrugte returvarer i original, forseglet og ubeskadiget emballage, og produkterne skal være forsvarligt pakket til forsendelse. Ellers anses de for at være brugt, og der gives ingen delvis refundering. Fortrydelsesretten gælder kun for uforseglede produkter ved modtagelse.

\n\n \n\n

Acceptable grunde til at returnere et produkt

\n
    \n
  • Udøvelse af 14 dages fortrydelsesret
  • \n\n
  • Produktet er ikke som beskrevet (garanti)
  • \n\n
  • Produktet er defekt
  • \n
\n \n\n

Vilkårene for returnering af CorPatch® følger EU's standardregler.

\n\n \n\n \n\n

Hvis du returnerer produktet, skal du beholde den originale emballage og må ikke beskadige, påsætte klistermærker eller skrive på det. Anskaf og brug velegnet returemballage f.eks. en papkasse.

\n\n \n\n

For CorPatch® Trainer følger fortrydelsesbetingelserne for dette produkt de almindelige EU-regler.

\n\n \n\n

For at udøve fortrydelsesretten skal du give os besked inden for 14 dage efter modtagelse af varerne. Anmodninger om annullering skal sendes pr. e-mail til info@corpatch.com med tydelig angivelse af, at du ønsker at gøre brug af din fortrydelsesret og hvorfor.

\n\n \n\n

Vi forventer, at du returnerer varerne så hurtigt som muligt efter, at du har givet meddelelse om brug af fortrydelsesretten, og senest 14 dage efter, at du har informeret os pr. e-mail.

\n\n \n\n

Vi kan afvise tilbagebetalingen, indtil du har returneret varerne eller bevist, at du har returneret varerne. Til denne tilbagebetaling vil vi bruge den samme betalingsmetode som ved den oprindelige transaktion.

\n\n \n\n

Ikke-acceptable grunde til at returnere et produkt

\n
    \n
  • Du ombestemmer dig efter de 14 dages fortrydelsesret.
  • \n\n
  • Hvis produktet er blevet aktiveret.
  • \n\n
  • Hvis produktet er brugt eller beskadiget på anden måde.
  • \n\n
  • Hvis softwaren/den gratis app er downloadet, forbundet til, installeret eller på anden måde kombineret med det/de fysiske produkt(er).
  • \n
\n \n\n

Sådan returnerer du

\n\n

Vi accepterer kun returvarer i uåbnet, original og ubeskadiget emballage, og produkterne skal være forsvarligt pakket til forsendelse. Ellers anses de for at være brugt, og der gives ingen refundering.

\n\n \n\n

Medmindre andet er angivet, skal returvarer sendes til: \n
\nSmartResQ ApS (CorPatch®) \n
\nLundevej 26 \n
\nDK-5700 Svendborg \n
\nDanmark

\n\n \n\n

VIGTIGT! Du er eneansvarlig for emballagekvaliteten og varerne, indtil de er modtaget af os. Du bedes gemme postkvitteringen, herunder oplysninger om forsendelsesomkostninger og evt. track and trace-nummeret. Vi dækker ikke returforsendelsesomkostninger, og vi accepterer ikke pakker, der sendes pr. efterkrav eller lignende.

\n\n
\n\n\n
\n

Refundering

\n\n

SmartResQ/CorPatch® er forpligtet til at reparere, erstatte eller give et prisnedslag eller fuld refundering, hvis varen viser sig at være defekt inden for 2 år efter, at du har købt varen. \n
\nKunden har ikke ret til refundering, hvis der er tale om et mindre problem, f.eks. ridser på varen eller lignende. \n
\nNår SmartResQ/CorPatch® modtager kundens vare, iværksættes en refundering. Værdien af refunderingsbeløbet afhænger af varens tilstand, når den modtages hos SmartResQ/CorPatch®.

\n\n \n\n

Den måde, hvorpå kundens refusion behandles, afhænger af den oprindelige betalingsmetode. Hvis kunden har betalt med kredit- eller betalingskort, sendes refusionen til den kortudstedende bank inden for 5 hverdage efter modtagelsen af den returnerede vare eller anmodningen om annullering. Kontakt venligst den kortudstedende bank, hvis du har spørgsmål om, hvornår beløbet vil blive krediteret din konto

\n\n
\n\n\n
\n

Databehandling af personoplysninger

\n\n

Hos SmartResQ/CorPatch® værdsætter vi dine personoplysninger via vores tretrins-indsats for overholdelse af datafortrolighed: a. opretholdelse af et detaljeret kort over vores dataflow, b. udførelse af en juridisk vurdering baseret på dataflow for at, c. implementere de nødvendige sikkerhedsforanstaltninger for at beskytte dine oplysninger.

\n\n \n\n

For at kunne bruge vores webshop skal du som minimum give følgende oplysninger:

\n
    \n
  • Navn
  • \n\n
  • Adresse
  • \n\n
  • E-mailadresse
  • \n\n
  • Telefonnummer
  • \n
\n \n\n

Indsamlingen af personlige kundeoplysninger finder sted inden for rammerne af den eksisterende lovgivning og EU's Databeskyttelsesforordning (GDPR).

\n\n \n\n

Hvis du vil vide mere om vores behandling af dine personoplysninger, kan du læse vores privatlivspolitik.

\n\n
\n\n\n
\n

Klager

\n\n

Sådan klager du til os

\n\n

Hvis der er noget galt med produktet, kan du enten få et defekt produkt repareret eller udskiftet, få pengene tilbage eller et prisnedslag, afhængigt af den specifikke situation. \n
\nDet er naturligvis et krav, at klagen er berettiget, og at fejlen ikke skyldes forkert brug af produktet eller anden ukorrekt adfærd.

\n\n \n\n

Vi anbefaler, at du indgiver klagen så hurtigt som muligt og inden for en uge efter, at fejlen er blevet opdaget.\n
\nDu er velkommen til at kontakte os med spørgsmål, kommentarer eller klager ved at kontakte os via e-mail: info@corpatch.com.

\n\n

Klage til andre virksomheder indenfor EU

\n\n

Du kan besøge EU's officielle website for at klage til andre virksomheder i EU. Du kan finde oplysningerne her.

\n\n
\n\n\n
\n

Ændringer af dette dokument

\n\n

Vores website(s), app(s) og politikker

\n\n

SmartResQ/CorPatch® forbeholder sig til enhver tid, uanset årsag, ret til uden forudgående varsel til nogen at foretage ændringer i, slette, modificere eller supplere vores website(s), app(s), politikker og dokumenter. \n
\nHvis nogen af disse betingelser skønnes at være ugyldige eller uden retskraft, skal den pågældende betingelse anses for at være uafhængig og skal ikke påvirke gyldigheden og retskraften af de resterende betingelser.

\n\n \n\n

Hvis vi ændrer vores politikker, vil vi offentliggøre de reviderede politikker her med en opdateret revisionsdato. Vi opfordrer dig til at gennemlæse politikkerne regelmæssigt. Hvis vi foretager væsentlige ændringer af vores politikker, der i betydelig grad ændrer vores politikpraksis, kan vi også informere dig på anden vis, f.eks. ved at sende en e-mail eller ved at poste en meddelelse på vores website og/eller sociale medier, inden ændringerne træder i kraft.

\n\n \n\n

Vedrørende et specifikt køb

\n\n

Når du køber et produkt, vil du blive bedt om at acceptere en version af visse dokumenter, som de foreligger på det nøjagtige tidspunkt – denne version vil ikke blive ændret efter dette tidspunkt og vil fastsætte betingelserne for vores forhold til dig vedrørende netop dette køb.

\n\n
\n\n\n
\n

Lovvalg og værneting

\n\n

Lovgivningen i Danmark og byretten i Svendborg

\n\n \n\n

SmartResQ/CorPatch® anvender dansk lov og værneting i tilfælde af retlige tvister, men ikke CISG. \n
\nEnhver tvist, der på nogen måde vedrører dit besøg på SmartResQ/CorPatch® eller produkter, som du køber via SmartResQ/CorPatch®, skal rejses på fortrolig vis i Danmark, dog således at hvis du på nogen måde har krænket eller truet med at krænke immaterielle rettigheder tilhørende SmartResQ/CorPatch®, kan SmartResQ/CorPatch® søge om afhjælpning ved forbud eller andet passende retsmiddel i et hvilket som helst land, og du giver dit samtykke til enekompetence og værneting for sådanne domstole.

\n\n \n\n

Ved brud på aftalen om \"Vilkår\" vil der blive taget retslige skridt, og der kan blive lagt sag an ved domstolene.

\n\n \n\n

Tvister mellem os og en forbruger er underlagt byretten i Svendborg, Christiansvej 41, 5700 Svendborg, Danmark

\n\n
\n\n\n
\n

Kontaktoplysninger

\n\n

Tak fordi du læste SmartResQ/CorPatch®'s \"Vilkår\".\n
\nHvis du har nogen spørgsmål, kommentarer eller klager, er du velkommen til at kontakte os.

\n\n \n\n

Vores virksomhed er beliggende på adressen: Lundevej 26, 5700 Svendborg

\n\n \n\n

Du kan finde os i det Centrale Virksomhedsregister under CVR-nr. 38674102

\n\n \n\n

Du kan kontakte os på tlf. +45 62 200 100

\n\n \n\n

eller

\n\n \n\n

skrive en e-mail til os på: info@corpatch.com

\n\n \n\n

©SmartResQ ApS – Alle rettigheder forbeholdes \n
\nDanmark, Version 2.1 – Udsendt 2023.04.25

\n\n\n
\n \n \n \n\n\n\n \n \n\n
\n

Privatlivspolitik for SmartResQ / CorPatch® \n\n\n

Vi behandler dine oplysninger i overensstemmelse med GDPR

\n\n

SmartResQ/CorPatch® respekterer dit privatliv. Denne privatlivspolitik beskriver dine privatlivsrettigheder og vores forpligtelse til at beskytte dine personoplysninger.

\n\n

Kontakt os, hvis du har spørgsmål vedrørende vores behandling af dine personoplysninger. Den dataansvarlige er:

\n\n

Selskab: SmartResQ ApS (CorPatch®)

\n\n

Adresse: \n
\nLundevej 26 \n
\n5700 Svendborg \n
\nDanmark

\n\n \n\n

CVR-nr.: 38674102

\n\n

Telefonnr.: +45 62 200 100

\n\n

E-mail: info@corpatch.com

\n\n

SmartResQ/CorPatch® er en dansk/europæisk virksomhed med selskaber, forretningsprocesser, ledelsesstrukturer og tekniske systemer på tværs af nationale grænser. SmartResQ/CorPatch® leverer produkter, software og tjenester til offentlige/private virksomheder i Europa.

\n\n

Hovedkontoret ligger i Danmark, og SmartResQ/CorPatch® er underlagt den europæiske databeskyttelseslovgivning, herunder Databeskyttelsesforordningen (GDPR). Alle større beslutninger i SmartResQ/CorPatch® vedrørende beskyttelse af personoplysninger træffes på ledelsesniveau under tilsyn af databeskyttelsesrådgiveren.

\n\n

Denne privatlivspolitik er tilgængelig på vores websites og i vores apps.

\n\n

Brug ikke SmartResQ/CorPatch®-siderne, -apps eller vores tjenester, hvis du ikke kan acceptere den måde, vi behandler personoplysninger på i henhold til denne privatlivspolitik.

\n\n
\n\n\n
\n

Typer af indsamlede personoplysninger

\n\n

Når en behandler bestemmer formålene med og metoderne til behandling af dine personoplysninger, fungerer behandleren som dataansvarlig. Dette omfatter scenarier, hvor SmartResQ/CorPatch® indsamler personoplysninger, når du er jobansøger, kunderepræsentant eller et lead, eller når du er softwarebruger.

\n\n

SmartResQ behandler personoplysninger til en række forskellige formål afhængigt af vores forhold til dig.

\n\n

Vi kan behandle:

\n
    \n
  1. almindelige kontaktoplysninger som f.eks. navn, adresse, telefonnummer (mobil og/eller fastnet) og e-mail,
  2. \n\n
  3. ansættelsesoplysninger som f.eks. arbejdsgiver, titel, stilling, herunder præferencer og interesser i professionel sammenhæng,
  4. \n\n
  5. feedback, kommentarer eller spørgsmål om SmartResQ/CorPatch® eller vores produkter og tjenester,
  6. \n\n
  7. fotos eller video optaget på vores lokationer,
  8. \n\n
  9. indhold, som du har uploadet, f.eks. fotos, videoer og resultater over tid,
  10. \n\n
  11. unikke brugeroplysninger som f.eks. login-ID, brugernavn, adgangskode og sikkerhedsspørgsmål,
  12. \n\n
  13. økonomiske oplysninger, hvor du accepterer, at vi bruger dine oplysninger til f.eks. opbevaring af dine betalingskortoplysninger,
  14. \n\n
  15. trafikoplysninger fra din webbrowser som f.eks. browsertype, enhed, sprog og adressen på det website, hvor du kom fra, samt andre trafikoplysninger, herunder IP-adresse,
  16. \n\n
  17. clickstream-adfærd og -aktivitet på SmartResQ/CorPatch® ID'er og i vores produkter og tjenester,
  18. \n\n
  19. e-mail-adfærd som f.eks. e-mails fra SmartResQ/CorPatch®, som du åbner på et hvilket som helst tidspunkt og på en hvilken som helst måde,
  20. \n\n
  21. andre personoplysninger i din profil, som du frivilligt har lagt ud på tredjeparts sociale netværk, f.eks. LinkedIn, Facebook, Google etc.,
  22. \n\n
  23. oplysninger, der anvendes til videnskabelige formål for at forbedre overlevelsen efter hjertestop og indsamles via vores website(s) og apps,
  24. \n\n
  25. oplysninger om brugere, til hvem der skal leveres produkter, for at overholde kvalitets- og sikkerhedskrav, levere tjenester til brugerne og vedligeholde og forbedre vores tilbud,
  26. \n\n
  27. oplysninger om jobansøgere for at behandle jobansøgninger, kommunikere om fremtidige jobtilbud og vedligeholde og forbedre vores rekrutteringsprocesser,
  28. \n\n
  29. oplysninger om personer, der har tilmeldt sig nyhedsbreve og andet materiale, for at levere materialerne og vedligeholde og forbedre vores tilbud,
  30. \n\n
  31. oplysninger om cookies for at levere skræddersyede reklamer på sociale medier og websites.
  32. \n
\n\n
\n\n\n
\n

Data, der indsamles og behandles i CorPatch® Services-platformen og apps

\n\n

SmartResQ behandler, indsamler og opbevarer følgende personoplysninger, når du bruger CorPatch® Services-platformen eller apps.

\n\n \n \n\n

Alle brugere (Institute Admin, Trainer, Trainee/slutbruger)

\n
    \n
  • Fornavn (hvis indtastet)
  • \n\n
  • Efternavn (hvis indtastet)
  • \n\n
  • Kaldenavne (hvis indtastet)
  • \n\n
  • E-mailadresse (obligatorisk)
  • \n\n
  • Foretrukket kommunikationssprog (obligatorisk)
  • \n\n
  • Adgangskode-hash (obligatorisk)
  • \n\n
  • Om e-mailadressen er valideret (obligatorisk)
  • \n
\n \n\n

Yderligere for trainees/slutbrugere (obligatorisk)

\n\n

Oplysninger om den benyttede mobiltelefon:

\n\n

Styresystem (Android/iOS):

\n
    \n
  • Styresystemversion (f.eks. 9)
  • \n\n
  • Producent (f.eks. Samsung)
  • \n\n
  • Model (f.eks. SM-T518)
  • \n\n
  • App-version (f.eks. 1.2.4)
  • \n\n
  • Tidspunktet for seneste forgrundsaktivitet i appen
  • \n\n
  • Tidspunktet for seneste baggrundsaktivitet i appen
  • \n
\n \n\n

Data om den CorPatch® (CPS), der bruges:

\n
    \n
  • Serienummer / MAC-adresse
  • \n\n
  • Firmwareversion
  • \n\n
  • Modelnavn (f.eks. CPS_01)
  • \n\n
  • Producent (på nuværende tidspunkt altid SRQ)
  • \n\n
  • Navn (på nuværende tidspunkt altid CorPatch®)
  • \n\n
  • Batteritilstand
  • \n\n
  • Fejl
  • \n
\n \n\n

Oplysninger om onboarding af brugere:

\n
    \n
  • Tutorial gennemført (ja/nej)
  • \n\n
  • Brugsbetingelser accepteret (ja/nej)
  • \n\n
  • Selvevaluering gennemført (ja/nej)
  • \n\n
  • Testtræning gennemført (ja/nej)
  • \n\n
  • Første login vellykket (ja/nej)
  • \n\n
  • Var en CPS forbundet (ja/nej)
  • \n
\n \n\n

Oplysninger indsamlet via træning:

\n
    \n
  • Dato, tidspunkt og varighed af træning
  • \n\n
  • Træningsresultat
  • \n\n
  • Træningstype eller træningsindstillinger
  • \n\n
  • I tilfælde af træning i et institute, yderligere oplysninger om kurset, trainer og institute
  • \n
\n \n \n\n

Serverlogfiler

\n\n

Følgende oplysninger gemmes i webserverens logfiler:

\n
    \n
  • IP-adresse for den tilgående part
  • \n\n
  • Browser-version for den tilgående part
  • \n\n
  • Dato/tidspunkt for adgang
  • \n\n
  • URL for adgang
  • \n
\n

Eksterne tjenester der behandler oplysninger:

\n
    \n
  • Google/Firebase for fjernlogning, nedbrud og fejlanalyse
  • \n\n
  • Google/Firebase for afsendelse af notifikationer
  • \n\n
  • Sendgrid for afsendelse af e-mails
  • \n\n
  • Hetzner Online GmbH for hosting af web-backend og database
  • \n
\n \n\n

Hvad sker der, når en bruger slettes?

\n
    \n
  • Brugeren sletter sig selv i vores system på CorPatch® Services-websitet https://app.corpatch.com
  • \n\n
  • Brugeren markeres som slettet. Herefter kan brugeren ikke længere logge ind, er ikke længere synlig for admins etc., men brugeren eksisterer stadig i databasen.
  • \n\n
  • Efter 14 dage slettes brugerens data automatisk fra databasen.
  • \n\n
  • Med henblik på videnskabelig vurdering og forbedring af funktionaliteten vil oplysninger om træninger og brug af CorPatch® stadig ligge i databasen efter sletning af brugeren, men referencen (ID) til brugeren vil være tom, og alle referencer til personoplysninger vil blive fjernet.
  • \n
\n\n
\n\n\n
\n

Sådan indsamler vi dine personoplysninger

\n\n

De fleste af de personoplysninger, som vi behandler, får vi direkte fra dig. Vi indsamler oplysninger og behandler dem, når du:

\n
    \n
  • registrerer dig online eller afgiver en ordre på et af vores produkter eller tjenester, f.eks. demografiske oplysninger, e-mailadresse, betalingsoplysninger, varer, ordrebeløb, rabatniveau og hyppighed. Dette omfatter afsendelse af transaktionsrelaterede e-mails, f.eks. ordrebekræftelse, forsendelsesbekræftelse og refunderingsbekræftelse,
  • \n\n
  • beskæftiger dig med den sendte kommunikation (e-mail, sms, direct mail eller telefon), f.eks. åbningsrate, click-rate og tid brugt på at læse e-mails, afsenderdomæne og type af e-mailklient,
  • \n\n
  • frivilligt deltager i en kundeundersøgelse eller giver feedback på en af vores opslagstavler eller via e-mail.
  • \n
\n

Vi kan også modtage personoplysninger indirekte fra følgende kilder i følgende scenarier:

\n
    \n
  • Fra cookies: når du besøger vores websites eller apps, f.eks. IP-adresse, land, besøgte sider, besøgte produkter, interaktion/clicks og søgninger.
  • \n\n
  • Fra dig eller en anden person med tilknytning til vores kunde. Disse personer kan være en leder eller en kollega. Hvis den kunde, som du arbejder for, køber produkter eller tjenester fra SmartResQ/CorPatch® via en samarbejdspartner til SmartResQ/CorPatch®, kan vi indsamle oplysninger om dig fra samarbejdspartneren.
  • \n\n
  • SmartResQ/CorPatch®'s markedsføringspartnere, offentlige kilder eller tredjeparters sociale netværk.
  • \n\n
  • SmartResQ/CorPatch® vil kunne samkøre personoplysninger om dig indsamlet fra én kilde med oplysninger indhentet fra en anden kilde. Dette giver os et mere komplet billede af dig og gør det muligt for os at give dig en mere relevant og personlig service.
  • \n
\n\n
\n\n\n
\n

Sådan bruger vi dine oplysninger

\n\n

For generelt at administrere vores kundeforhold og opfylde vores kundeforpligtelser har SmartResQ/CorPatch® brug for oplysninger om dig i din rolle som kunde, eller når du bruger en tjeneste. Formålene med at behandle sådanne personoplysninger er følgende:

\n\n
    \n
  • at behandle din ordre, administrere din konto,
  • \n\n
  • at sende dig e-mails med særlige tilbud på andre produkter og tjenester, som vi tror, du vil kunne lide,
  • \n\n
  • at udføre salgs- og kontraktprocessen for kunderne,
  • \n\n
  • at levere de ønskede produkter og tjenester til kunderne,
  • \n\n
  • at foretage levering i henhold til aftaler indgået med dig eller kunderne,
  • \n\n
  • at tilbyde support til brugere af vores produkter og tjenester,
  • \n\n
  • at forbedre og udvikle kvaliteten, funktionaliteten og brugeroplevelsen af vores produkter, tjenester og SmartResQ/CorPatch®-website(s) og -apps,
  • \n\n
  • at opdage, begrænse og forebygge sikkerhedstrusler og udføre vedligeholdelse og fejlfinding og fejlretning,
  • \n\n
  • at forhindre misbrug af vores produkter og tjenester,
  • \n\n
  • at behandle ordrer, foretage fakturering, betalinger eller anden økonomisk opfølgning,
  • \n\n
  • at oprette interesseprofiler for at reklamere for relevante produkter og tjenester,
  • \n\n
  • at etablere brugergrupper for at uddanne og lette interaktionen mellem brugerne og SmartResQ/CorPatch®.
  • \n
\n \n\n

Om leads

\n\n

SmartResQ/CorPatch® behandler personoplysninger om leads til markedsføringsformål. For at levere målrettet og relevant indhold til potentielle kunder opbygger SmartResQ/CorPatch® en interesseprofil baseret på din aktivitet og dine valg og handlinger på SmartResQ/CorPatch®-siderne samt din reaktion på markedsføringsindhold. Retsgrundlaget for denne behandling er primært dit samtykke.

\n\n

Om jobansøgere

\n\n

Hvis du er jobansøger, behandler vi personoplysninger for at vurdere dit potentiale som SmartResQ/CorPatch®-medarbejder. Vores sikre online- karriereplatform sørger for, at vi overholder de seneste love og bestemmelser vedrørende databeskyttelse. Retsgrundlaget for denne behandling er dit samtykke.

\n\n

Om besøgende på websitet

\n\n

For at overvåge adgangen til vores websites behandler vi personoplysninger om besøgende. Behandlingen er baseret på vores legitime interesse i at beskytte vores forretningshemmeligheder, medarbejdere, lokationer og dig som besøgende. Du vil blive informeret om dine rettigheder i denne forbindelse, når du registrerer dig i vores elektroniske system for besøgende.

\n\n

For at forbedre kvaliteten af hjerte-lunge-redning, især gennem træning i hjerte-lunge-redning, kan SmartResQ/CorPatch® dele dine oplysninger med vores samarbejdspartnere (Training Institutes), så de kan tilbyde dig deres produkter og tjenester.

\n\n

Når vi behandler din ordre, kan vores system sende dine oplysninger til, og bruge de returnerede oplysninger fra, kreditoplysningsbureauer for at forhindre falske køb.

\n\n
\n\n\n
\n

Sådan opbevarer vi dine personoplysninger

\n\n

SmartResQ/CorPatch® tager den tillid, som du og vores kunder viser os, meget alvorligt. SmartResQ/CorPatch® forpligter sig til at undgå uautoriseret adgang, videregivelse eller anden afvigende behandling af personoplysninger. SmartResQ/CorPatch® skal sikre fortroligheden af de personoplysninger, vi behandler, fastholde integriteten af personoplysninger og sikre deres tilgængelighed i overensstemmelse med gældende databeskyttelseslove.

\n\n

Som en del af vores forpligtelser udfører og træffer vi rimelige og tilstrækkelige organisatoriske, tekniske og fysiske procedurer og foranstaltninger for at beskytte de oplysninger, som vi indsamler og behandler. Vi tager højde for typen af personoplysninger og den risiko, som vores kunder er udsat for ved et eventuelt sikkerhedsbrud, idet der er stor sandsynlighed for, at hovedårsagen til brud på persondatasikkerhed skal findes internt. Vi mener, at opbygningen af en stærk virksomhedskultur med respekt og årvågenhed omkring databeskyttelse blandt vores medarbejdere er afgørende for at sikre lovlig behandling og beskyttelse af dine oplysninger. I tilfælde af et brud på datasikkerheden vil SmartResQ/CorPatch® følge den praksis, som Datatilsynet har fastlagt.

\n\n

Dine oplysninger opbevares sikkert i henhold til bestemmelserne i GDPR.

\n\n
\n\n\n
\n

Hvor længe opbevarer vi dine personoplysninger?

\n\n

SmartResQ/CorPatch® opbevarer kun dine personoplysninger, så længe det er nødvendigt til de anførte formål, idet der tages højde for vores behov for at besvare forespørgsler og løse problemer samt overholde gældende lovkrav.

\n\n

Det betyder, at SmartResQ/CorPatch® kan opbevare dine personoplysninger i en rimelig periode efter din og vores kundes sidste interaktion med os. Når de personoplysninger, vi har indsamlet, ikke længere er nødvendige, sletter vi dem. Vi kan behandle oplysninger til statistiske og/eller videnskabelige formål, men i sådanne tilfælde vil oplysningerne blive pseudonymiseret eller anonymiseret.

\n\n \n \n\n

Tidsramme for opbevaring af oplysninger

\n\n

Vi vil opbevare dine personoplysninger, så længe det er nødvendigt for at opfylde de formål, der er anført i denne Privatlivspolitik, medmindre en længere opbevaringsperiode er påkrævet eller tilladt ved lov af juridiske, skattemæssige eller regulatoriske årsager eller andre legitime og lovlige forretningsmæssige formål.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Formål Tidsramme
Kundeservice og kontoregulering 5 år eller så længe vi er forpligtet til at opfylde de nødvendige lovkrav.\n
\n \n\nVi sletter dine registreringsoplysninger, så snart du sletter din brugerkonto hos os, eller når den lovbestemte opbevaringsperiode udløber. \n
Karriereplatform 6 måneder for ansøgningsdokumenter, der ikke fører til ansættelse af ansøgeren. \n
\n \n\nFornyelse hver 6. måned, hvis du ønsker at komme i betragtning til fremtidige ledige stillinger, og du giver dit samtykke til en længere opbevaringsperiode. \n
Markedsføringsformål 3 år efter din seneste aktivitet, f.eks. besøg på vores websites, køb eller deltagelse i kommunikation. \n
\n \n\nHvis du har givet tilladelse til markedsføring (e-mail, sms, telefon etc.), og så længe vi har din tilladelse til at kontakte dig. \n
\n \n\nVi sletter automatisk din e-mailadresse til nyhedsbreve, når du sletter din brugerkonto, eller hvis du afmelder vores nyhedsbrev. \n
Opbevaring af ordrehistorik og forpligtelser til at opfylde ordrer 5 år eller så længe vi er forpligtet til at opfylde de nødvendige lovkrav
Kundeoplevelse 3 år efter din seneste aktivitet, f.eks. besøg på vores websites, køb eller deltagelse i kommunikation. \n
\n \n\nHvis du har givet tilladelse til markedsføring (e-mail, sms, telefon etc.), og så længe vi har din tilladelse.
Bedrageri og risikovurdering 5 år eller så længe vi er forpligtet til at opfylde de nødvendige lovkrav.
\n\n
\n\n\n
\n \n

Markedsføringskommunikation

\n\n

Du har ret til at fravælge at modtage markedsføringskommunikation fra SmartResQ/CorPatch® ved enten at:

\n
    \n
  • følge fravalgsanvisningerne i den relevante markedsføringskommunikation,
  • \n\n
  • ændre præferencer i det relevante redigeringsafsnit for kontoen, hvis du har en konto hos SmartResQ/CorPatch®,
  • \n\n
  • kontakte os via e-mail på info@corpatch.com.
  • \n
\n \n\n

Bemærk, at selvom du fravælger at modtage markedsføringskommunikation, kan du stadig modtage administrative meddelelser fra SmartResQ/CorPatch® som f.eks. ordrebekræftelser og meddelelser, der er nødvendige for at administrere din konto eller tjenester, der leveres til vores kunder via f.eks. mobile tjenester eller apps.

\n\n
\n\n\n
\n

Dine databeskyttelsesrettigheder

\n\n

Det er vigtigt for SmartResQ/CorPatch®, at du er fuldt bevidst om alle dine databeskyttelsesrettigheder.

\n\n

Nogle databeskyttelseslove, herunder EU's Databeskyttelsesforordning (GDPR), tilsvarende lovgivning i Tyskland, Bundesdatenschutzgesetz (BDSG), i Schweiz og i Storbritannien samt nogle amerikanske delstatslove giver dig visse rettigheder i forbindelse med personoplysninger, som du har delt med os. Hvis du bor inden for det Europæiske Økonomiske Samarbejdsområde, kan du have følgende rettigheder:

\n
    \n
  1. Indsigtsret – Du har ret til at anmode os om kopier af dine personoplysninger. \n\n
  2. Ret til berigtigelse – du har ret til at anmode om, at vi berigtiger personoplysninger, som du mener er forkerte. Du har også ret til at anmode os om at fuldstændiggøre ufuldstændige oplysninger. \n\n
  3. Ret til sletning – Du har ret til at anmode os om at slette dine personoplysninger under visse omstændigheder. \n\n
  4. Ret til begrænsning af behandling – Du har ret til at anmode os om at begrænse behandlingen af dine personoplysninger under visse omstændigheder. \n\n
  5. Ret til at gøre indsigelse mod behandling – Du har ret til at gøre indsigelse mod behandlingen af dine personoplysninger under visse omstændigheder. \n\n
  6. Ret til dataportabilitet – Du har ret til at anmode om, at vi overfører de personoplysninger, vi har indsamlet, til en anden organisation eller direkte til dig under visse omstændigheder. \n
\n \n\n

Hvis du ønsker at udøve en af disse rettigheder, skal du kontakte os på vores e-mail info@corpatch.com.

\n\n
\n\n\n
\n

Hvad er cookies?

\n\n

Cookies er små tekstfiler, der indeholder en tekststreng og opretter en unik identifikator for en bruger. De returneres til websitet og/eller tredjeparter. De fleste browsere er som standard sat op til at acceptere cookies, da de fleste websites kræver adgang til dem. Du kan imidlertid ændre dine browserindstillinger, så din browser generelt kan afvise cookies, blokere tredjepartscookies eller angive, hvornår en cookie sendes.

\n \n \n\n

SmartResQ/CorPatch® er fast besluttet på at sikre din ret til at justere dine interesser og administrere omfanget af digital markedsføring fra os via et system med præferenceadministration.

\n\n
\n\n\n
\n

Sådan bruger vi cookies

\n\n

SmartResQ/CorPatch® bruger cookies på en række forskellige måder til at forbedre din oplevelse på vores websites, apps og tjenester af forskellige grunde, f.eks.:

\n
    \n
  • Funktionalitet – vi bruger disse cookies til at genkende dig på vores website og huske dine tidligere valgte præferencer. Disse omfatter dit foretrukne sprog og det sted, hvor du befinder dig. Der anvendes en blanding af førsteparts- og tredjepartscookies.
  • \n\n
  • Reklame – vi bruger disse cookies til at indsamle oplysninger om dit besøg på vores websites, app(s), det indhold du har set, de links du har fulgt, og oplysninger om din browser, enhed og IP-adresse. Nogle gange deler vi begrænsede elementer af disse oplysninger med tredjeparter til reklameformål. Vi kan også dele onlineoplysninger indsamlet via cookies med vores reklamepartnere. Det betyder, at når du besøger et andet website, kan du få vist reklamer, der er baseret på dine browsingmønstre på vores website.
  • \n
\n
\n\n\n
\n

Typer af anvendte cookies

\n\n

Vores website(s) anvender følgende typer af cookies:

\n
    \n
  • Google Analytics: Denne cookie gør det muligt for os at se oplysninger om website-aktiviteter for brugere, herunder bl.a. sidevisninger, kilde og den tid, der bliver brugt på websitet. Oplysningerne anonymiseres og vises som tal, hvilket betyder, at de ikke kan spores tilbage til personer. Dette er med til at opretholde fortroligheden af dine oplysninger. Når vi bruger Google Analytics, kan vi se hvilket indhold, der er populært på vores sider, og vi bestræber os på at give dig mere af det, du godt kan lide at læse og se.
  • \n\n
  • Google Analytics remarketing: Placerer cookies på din computer, hvilket betyder, at når du forlader websitet, kan Google vise dig reklamer om SmartResQ/CorPatch®, som du måske er interesseret i ud fra din tidligere adfærd på vores website. Disse oplysninger er ikke personhenførbare.
  • \n\n
  • Google Ads: Når vi bruger Google Ads, kan vi se hvilke sider, der var nyttige, idet de førte til indsendelser via vores kontaktformular. Disse oplysninger er ikke personhenførbare, men det er oplysningerne i kontaktformularen.
  • \n\n
  • Google Ads remarketing: Placerer cookies på din computer, hvilket betyder, at når du forlader websitet, kan Google vise dig reklamer om SmartResQ/CorPatch®, som du måske er interesseret i ud fra din tidligere adfærd på vores website. Disse oplysninger er ikke personhenførbare.
  • \n\n
  • Facebook remarketing: Facebooks sporingspixel placerer cookies på din computer, som fortæller Facebook, at du har være inde på websitet. Vi går så ud fra, at du har interesse for SmartResQ/CorPatch® og indholdet på dette site. Når du går ind på Facebook, får du vist information eller reklamer med lignende indhold. Du bedes anvende vores privatlivsindstillinger på Facebook for at begrænse visningen af denne type af markedsføring.
  • \n\n
  • YouTube: Vi bruger videoer fra YouTube-platformen, der leveres af Google (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA). Privatlivspolitik: https://www.google.com/policies/privacy/.
  • \n
\n \n
\n\n\n
\n

Sådan administrerer vi cookies

\n\n

Du kan indstille din browser til ikke at acceptere eller slette cookies. Dette kan imidlertid betyde, at nogle af vores website-funktioner ikke fungerer. Se, hvordan man undgår cookies i specifikke browsere:

\n\n \n\n

SmartResQ/CorPatch® bruger visse betroede tredjepartstjenester på vores sider. Disse tjenester bruger muligvis cookies. Du kan vælge at afvise tredjepartscookies i din browser ved at følge dette link.

\n\n

Du kan forhindre, at oplysninger genereret af Google-cookien om din brug af vores websites bliver indsamlet og behandlet af Google ved at downloade og installere Google Analytics opt-out browser-add-on til din aktuelle webbrowser. Denne add-on er tilgængelig her.

\n\n
\n\n\n
\n

Privatlivspolitikker på andre websites

\n\n

SmartResQ/CorPatch® websites indeholder links til andre websites. Vores privatlivspolitik gælder kun for vores website, så hvis du klikker på et link til et andet website, skal du læse deres privatlivspolitik.

\n\n
\n\n\n
\n

Ændringer i vores privatlivspolitik

\n\n

Hvis vi ændrer vores privatlivspolitik, vil vi offentliggøre den reviderede politik her med en opdateret revisionsdato. Vi opfordrer dig til at gennemlæse politikken regelmæssigt. Hvis vi foretager væsentlige ændringer af vores politik, der i betydelig grad ændrer vores privatlivspraksis, kan vi også informere dig på anden vis, f.eks. ved at sende en e-mail eller ved at poste en meddelelse på vores website og/eller sociale medier, inden ændringerne træder i kraft.

\n\n
\n\n\n
\n

Sådan kan SmartResQ ApS kontaktes

\n\n

Hvis du har spørgsmål om SmartResQ/CorPatch®'s privatlivspolitik, de oplysninger vi opbevarer om dig, eller hvis du ønsker at udøve en af dine databeskyttelsesrettigheder, er du meget velkommen til at kontakte os.

\n\n

E-mail: info@corpatch.com

\n\n

Website: https://corpatch.com

\n\n
\n\n\n
\n\n

Sådan kontaktes den relevante myndighed

\n\n

Hvis du ønsker at indgive en klage, eller hvis du føler, at SmartResQ/CorPatch® ikke har håndteret din bekymring på tilfredsstillende vis, kan du kontakte Information Commissioner's Office (ICO).

\n\n

ICO's adresse: \n

\nInformation Commissioner's Office \n
\nWycliffe House \n
\nWater Lane \n
\nWilmslow \n
\nCheshire \n
\nSK9 5AF

\n\n \n\n

Helpline-nummer: +44 303 123 1113

\n\n

ICO website: https://www.ico.org.uk

\n\n

© SmartResQ ApS – Alle rettigheder forbeholdes \n
\nDanmark, Version 1.3 – Udsendt 2023.04.25

\n\n
\n\n
\n\n`\n\nexport const termsOfUse_fi_FI: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n\n
\n\n \n\n \n
\n

Käyttöehdot & Tietosuojakäytäntö

\n

SmartResQ ApS / CorPatch®

\n \n
\n \n\n
\n\n

Käyttöehdot – SmartResQ ApS / CorPatch®

\n\n

Tämän asiakirjan tarkoitus

\n\n

Tervetuloa SmartResQ/CorPatch®:iin!

\n\n \n\n

Luet juuri käyttöehtojamme, asiakirjaa, joka sisältää tietoja suhteestasi SmartResQ ApS:ään. Suhde alkoi, kun tulit verkkosivustollemme, latasit maksuttoman sovelluksemme, ostit jonkin tuotteistamme tai muuta vastaavaa.

\n\n \n\n

SmartResQ/CorPatch® ja yhteistyökumppanimme tarjoavat sinulle tuotteitamme ja palvelujamme seuraavien ehtojen mukaisesti. Jos vierailet verkkosivustollamme tai sovelluksessamme tai teet ostoksia niissä, hyväksyt nämä ehdot. Suosittelemme, että luet ehdot huolellisesti ennen kuin käytät tuotteitamme tai palvelujamme.

\n\n \n\n

Tässä asiakirjassa käsitellään:

\n
    \n
  • Kuinka voit ottaa yhteyttä SmartResQ-yritykseen
  • \n\n
  • Tuotteet, ominaisuudet ja asianmukainen käyttö
  • \n\n
  • Vastuuvapauslausekkeet ja takuut
  • \n\n
  • Tilaaminen
  • \n\n
  • Maksaminen
  • \n\n
  • Toimitus
  • \n\n
  • Myyntiin liittyvät velvollisuudet ja oikeudet
  • \n\n
  • Palautukset
  • \n\n
  • Henkilötietojen käsittely
  • \n\n
  • Reklamaatiot
  • \n\n
  • Tämän asiakirjan muutokset
  • \n\n
  • Laki ja lainkäyttöalue
  • \n\n
  • Yhteystiedot
  • \n
\n \n\n

Jos sinulla on kysyttävää SmartResQ:n käyttöehdoista, ota yhteyttä meihin.

\n\n \n\n

Kuinka voit ottaa yhteyttä SmartResQ-yritykseen

\n\n

SmartResQ:n tavoitteena on parantaa eloonjäämistä laadukkaan PPE:n avulla sydänpysähdystapauksissa. Haluamme valmistaa ja opastaa sivullisia toimimaan ensimmäisten ratkaisevien minuuttien aikana sen jälkeen, kun he ovat havainneet sydänpysähdyksen. Siksi olemme kehittäneet CorPatch®:n – autamme sinua pelastamaan ihmishengen.

\n\n \n\n

Yrityksemme sijaitsee osoitteessa Lundevej 26, DK- 5700 Svendborg, Tanska

\n\n \n\n

Löydät meidät keskusyritysrekisteristä ALV-numerolla DK 38674102

\n\n \n\n

Voit soittaa meille numeroon +45 62 200 100

\n\n \n\n

tai

\n\n \n\n

lähettää sähköpostia osoitteeseen info@corpatch.com

\n\n \n\n

Kysymyksiä, kommentteja tai reklamaatioita?

\n\n

Arvostamme mielipidettäsi, joten ota meihin yhteyttä edellä ilmoitettuja yhteystietoja käyttäen tai käytä verkkosivustomme tai sovelluksemme yhteydenottolomaketta.

\n\n
\n\n\n
\n

Tuotteet, ominaisuudet ja asianmukainen käyttö

\n\n

Verkkosivustomme, sovelluksemme ja tuotteemme

\n\n

Seuraavissa kappaleissa kuvataan SmartResQ/CorPatch®-palveluiden, -sovellusten ja -tuotteiden käyttöön liittyviä keskeisiä ominaisuuksia, oikeuksia ja velvollisuuksia. \n
\nKäytämme kohtuullisia keinoja sisällyttääksemme verkkosivusto(i)lle ja sovelluksiin tarkkaa ja ajantasaista tietoa. SmartResQ/CorPatch® ei kuitenkaan anna mitään takuita tai vakuuksia tietojen oikeellisuudesta. Emme ota mitään vastuuta mistään verkkosivuston, tuotteiden tai sovellusten sisältämistä virheistä tai puutteista. Tällä verkkosivustolla tai sovelluksissa annetut tiedot eivät korvaa lääkärinhoitoa. Otamme vastuun tuotteistamme ja sovelluksistamme lääkinnällisistä laitteista annetun direktiivin EU 745/2017 (MDR) mukaisesti.

\n\n \n\n

Tekijänoikeudet

\n\n

Kaikki tämän sivuston sisältö, kuten teksti, grafiikka, logot, painikekuvakkeet, kuvat, äänileikkeet, digitaaliset lataukset, tietokokoelmat ja ohjelmistot, on SmartResQ/CorPatch®:n tai sen sisällöntoimittajien omaisuutta ja suojattu kansainvälisillä tekijänoikeuslaeilla. Koko tämän sivuston sisältökooste on SmartResQ/CorPatch®:n yksinomaista omaisuutta, tämän koosteen tekijänoikeudet ovat SmartResQ/CorPatch®:llä, ja sitä suojaavat kansainväliset tekijänoikeuslait.

\n\n \n\n

Rekisteröidyt tavaramerkit ja mallit

\n\n

SmartResQ/CorPatch®-tavaramerkkejä, ulkoasua ja tuotesuunnittelua ei saa käyttää minkään sellaisen tuotteen tai palvelun yhteydessä, joka ei ole SmartResQ/CorPatch®, millään tavalla, joka todennäköisesti aiheuttaa sekaannusta asiakkaiden keskuudessa, tai millään tavalla, joka halventaa tai mustamaalaa SmartResQ/CorPatch®-tuotetta. Kaikki muut tällä sivustolla esiintyvät tavaramerkit, jotka eivät ole SmartResQ/CorPatch®:n tai sen tytäryhtiöiden omistamia, ovat omistajiensa omaisuutta. Omistajat voivat olla tai voivat olla olematta sidoksissa SmartResQ/CorPatch®:iin tai sen tytäryhtiöihin tai sponsoroida niitä.

\n\n \n\n

Lisenssi ja käyttöoikeus

\n\n

SmartResQ/CorPatch® myöntää sinulle rajoitetun lisenssin käyttää ja hyödyntää henkilökohtaisesti sivustoamme (sivustojamme) ja sovelluksiamme. Et saa ladata (muuta kuin sivujen välimuistiin tallentaminen) tai muokata niitä tai mitään niiden osaa ilman SmartResQ/CorPatch®:n nimenomaista kirjallista lupaa. Tämä lisenssi ei sisällä näiden sivustojen tai sovellusten tai niiden sisällön jälleenmyyntiä tai kaupallista käyttöä: (a) tuoteluetteloiden, kuvausten tai hintojen keräämistä ja käyttöä: (b) tämän sivuston tai sen sisällön minkäänlaista johdannaiskäyttöä: (c) tilitietojen lataamista tai kopiointia toisen kauppiaan hyödyksi: tai (d) tiedonlouhinnan, robottien tai vastaavien tiedonkeruu- ja louhintatyökalujen käyttöä.

\n\n \n\n

Tätä sivustoa tai sovellusta tai mitään sivuston osaa ei saa jäljentää, muokata, monistaa, kopioida, myydä, jälleenmyydä, vierailla tai muutoin hyödyntää mihinkään kaupalliseen tarkoitukseen ilman SmartResQ/CorPatch®:n nimenomaista kirjallista lupaa. Et saa kehystää tai käyttää kehystekniikoita SmartResQ/CorPatch®:n ja yhteistyökumppaneidemme tavaramerkkien, logojen tai muiden omistusoikeuden alaisten tietojen (mukaan lukien kuvat, teksti, sivun asettelu tai muoto) sisällyttämiseen ilman nimenomaista kirjallista lupaa.

\n\n \n\n

Et saa käyttää metatunnisteita tai muuta ”piilotettua tekstiä”, jossa käytetään SmartResQ/CorPatch®-nimeä tai -tavaramerkkejä ilman SmartResQ/CorPatch®:n nimenomaista kirjallista lupaa. Luvattoman käytön seurauksena SmartResQ/CorPatch®:n myöntämä lupa tai lisenssi päättyy.

\n\n \n\n

Sinulle myönnetään rajoitettu, peruutettavissa oleva ja ei-yksinomainen oikeus luoda hyperlinkki SmartResQ/CorPatch®:n kotisivulle niin kauan kuin linkki ei kuvaa SmartResQ/CorPatch®:a, sen osakkuusyhtiöitä tai niiden tuotteita tai palveluja väärällä, harhaanjohtavalla, halventavalla tai muulla tavalla loukkaavalla tavalla. Et saa käyttää mitään SmartResQ/CorPatch®-logoa tai muuta omistusoikeuden alaista grafiikkaa tai tavaramerkkiä osana linkkiä ilman nimenomaista kirjallista lupaa. \n
\nJos lisenssisopimusta ja sivuston käyttöoikeutta koskevaa sopimusta rikotaan, ryhdytään oikeustoimiin, ja kanne voidaan nostaa tuomioistuimessa.

\n\n

Sähköinen viestintä

\n\n

Kun käyt SmartResQ/CorPatch®:n kotisivulla ja sosiaalisen median kanavissa tai lähetät meille sähköpostia, viestit kanssamme sähköisesti. Annat suostumuksesi vastaanottaa meiltä sähköistä viestintää. Viestimme sinulle sähköpostitse tai julkaisemalla ilmoituksia verkkosivustoillamme tai sovelluksissamme ponnahdusikkunoiden tai ilmoitusten muodossa. Hyväksyt, että kaikki sopimukset, ilmoitukset, tiedotteet ja muu viestintä, jonka tarjoamme sinulle sähköisesti, täyttää kaikki lakisääteiset vaatimukset, joiden mukaan tällainen viestintä on tehtävä kirjallisesti. Tutustu tietosuojaselosteeseemme erillisessä asiakirjassa kotisivullamme.

\n\n \n

Verkkosivustomme ja sosiaalisen median kanaviemme kävijöitä saatetaan pyytää julkaisemaan arvosteluja, kommentteja ja muuta sisältöä,esim. lähettämään ehdotuksia, ideoita, kommentteja, kysymyksiä tai muuta tietoa, kunhan sisältö ei ole laitonta, säädytöntä, uhkaavaa, herjaavaa, yksityisyyttä loukkaavaa, immateriaalioikeuksia loukkaavaa tai muutoin kolmansia osapuolia vahingoittavaa tai paheksuttavaa, eikä se koostu ohjelmistoviruksista, poliittisesta kampanjoinnista, kaupallisesta myynninedistämisestä, ketjukirjeistä, massapostituksista tai muunlaisesta roskapostista tai sisällä niitä.

\n\n \n\n

Et saa käyttää väärää sähköpostiosoitetta, esiintyä toisena henkilönä tai oikeushenkilönä tai muutoin johtaa harhaan kortin tai muun sisällön alkuperän suhteen. SmartResQ/CorPatch® pidättää oikeuden (mutta ei velvollisuutta) poistaa tai muokata tällaista sisältöä, mutta ei tarkista julkaistua sisältöä säännöllisesti. Jos julkaiset sisältöä tai lähetät materiaalia, ja jollemme toisin ilmoita, annat SmartResQ/CorPatch®:lle ja sen yhteistyökumppaneille ei-yksinomaisen, rojaltittoman, pysyvän, peruuttamattoman ja täysin alilisensoitavissa olevan oikeuden käyttää, kopioida, muokata, mukauttaa, julkaista, kääntää, luoda johdannaisia teoksia, levittää ja esittää kyseistä sisältöä kaikkialla maailmassa missä tahansa mediassa. Annat SmartResQ/CorPatch®:lle ja sen yhteistyökumppaneille ja alilisenssinsaajille oikeuden käyttää lähettämääsi nimeä tällaisen sisällön yhteydessä, mikäli he niin haluavat.

\n\n

Vakuutat ja takaat, että omistat tai hallitset muutoin kaikkia oikeuksia julkaisemaasi sisältöön, että sisältö on täsmällistä, että toimittamasi sisällön käyttö ei riko tätä käytäntöä eikä aiheuta vahinkoa kenellekään henkilölle tai entiteetille ja että korvaat SmartResQ/CorPatch®:lle tai sen yhteistyökumppaneille kaikki vaatimukset, jotka johtuvat toimittamastasi sisällöstä. SmartResQ/CorPatch®:lla on oikeus mutta ei velvollisuutta valvoa ja muokata tai poistaa mitä tahansa toimintaa tai sisältöä. SmartResQ/CorPatch® ei ota vastuuta eikä ole vastuussa mistään sinun tai kolmannen osapuolen julkaisemasta sisällöstä.

\n
\n\n\n
\n \n\n

Vastuuvapauslausekkeet ja takuut

\n\n

Tuotetiedot – CorPatch® ja CorPatch® Trainer

\n\n

SmartResQ/CorPatch®-tuotteen tai -palvelun oikean käytön varmistamiseksi on aina noudatettava viimeisimpiä käyttöoppaita, ohjeita ja kuvauksia. Ne löytyvät verkkosivuiltamme ja kunkin tuotekuvauksen alta.

\n\n \n\n

CorPatch®-tuote on sertifioitu lääkinnälliseksi laitteeksi. Hätätilanteessa, jossa aikuinen henkilö on saanut sydämenpysähdyksen, tuote on otettava kotelostaan, asetettava ja kiinnitettävä oikein uhrin rintaan. Tuote pystyy keräämään tietoja painalluksista, syvyydestä, tiheydestä ja rintakehän palautumisesta, ja se voi lähettää nämä tiedot Bluetooth®-yhteyden kautta mahdollisiin laitteisiin. Laitteiden sisältämät ilmaiset sovellukset voivat opastaa sivullista PPE:n suorittamisessa ja näyttää paineluajan, syvyyden, rintakehän palautumisen ja tiheyden, jos ne on aktivoitu ja asennettu oikein, eli Bluetooth®, älypuhelin, sovellus, akun teho jne. SmartResQ/CorPatch® ei ole vastuussa ulkoisista tekijöistä, kuten häiritsevistä tietoliikennesignaaleista, datapeiton puutteesta, akkuvirran riittämättömyydestä, virheellisistä laitteisto- tai ohjelmistoasetuksista, jotka voivat vaikuttaa käyttökokemukseen tai vastaaviin.

\n\n \n\n

SmartResQ/CorPatch® ei myöskään ole vastuussa tuotteen käytön aikana aiheutuneista fyysisistä vahingoista, jos tuotetta käytetään ohjeiden vastaisesti, esim. suorittamalla rintakehän painelu epäergonomisella tavalla tai käyttämällä epäsopivaa käsien asentoa. SmartResQ/CorPatch® on arvioinut teknisiä riskejä osana lääkinnällisten laitteiden lakisääteistä riskinhallintaa, mutta mitään takuuta ei anneta tämän ylittävistä virheistä. Jos SmartResQ/CorPatch®-järjestelmässä ilmenee odottamattomia toimintahäiriöitä tai epätodennäköistä toimintaa, käyttäjän on suoritettava PPE manuaalisesti. Tässä tapauksessa SmartResQ/CorPatch® ei ole vastuussa, koska se ei ole SmartResQ/CorPatch®:n hallinnassa.\n
\nSmartResQ/CorPatch® valvoo akun varaustasoa ja kuntoa, mutta jos akun virta loppuu, tuote ei toimi. Käyttäjä on yksin vastuussa siitä, että laite on ajan tasalla, että se ei ole vahingoittunut ja että siinä on riittävästi akkuvirtaa toimiakseen oikein, mikä voidaan tehdä helposti suorittamalla harjoittelu, jossa vahvistetaan oikea toiminta. Suosittelemme 4 minuutin harjoittelua 3 kuukauden välein CorPatch®-laitteella.

\n\n \n\n

Tärkeää! CorPatch®-laitetta saa käyttää henkilöön ainoastaan todellisessa tilanteessa ja vain, jos henkilö on saanut sydänpysähdyksen. Sitä ei ole tarkoitettu käytettäväksi henkilöille, jotka kärsivät esimerkiksi aivohalvauksesta, sydänkohtauksesta tai muista terveyteen liittyvistä sairauksista, jotka eivät ole sydänpysähdys. CorPatch® ei ole tarkoitettu käytettäväksi, jos henkilö makaa pehmeällä pinnalla, esim. sohvalla tai sängyllä, koska syvyyspalaute voi olla epätarkka tällaisissa olosuhteissa. Mitään SmartResQ/CorPatch®-ratkaisuja ei ole tarkoitettu käytettäväksi liikkuvassa ympäristössä, mukaan lukien mutta ei rajoittuen lento-, meri- tai maantieambulansseihin. Jos laitetta käytetään potilaan kuljetuksen aikana tai jos se nostetaan/irrotetaan kehosta PPE:n aikana, se voi antaa epätarkkaa palautetta. CorPatch® on kiinnitettävä potilaan rintaan liimatarralla. Varmista, että potilas makaa kiinteällä, tasaisella ja liikkumattomalla alustalla ja että CorPatch® on kiinnitetty rintakehään liimatarralla.

\n\n \n\n

CorPatch® Trainer -tuotetta saa käyttää ainoastaan harjoitusnukkeihin tai vastaaviin esineisiin Training Sessionoissa eikä koskaan todellisessa tilanteessa oikeaan henkilöön, joka on saanut sydänpysähdyksen tai jolla on muu sairaus.

\n\n \n\n

Käyttämällä CorPatch®️- tai CorPatch®️ Trainer -laitetta säännöllisesti, on mahdollista harjoitella PPE-suoritusta rintakehän painallusten osalta. Suosittelemme, että harjoittelet harjoitusnukella, mutta jos sinulla ei ole mahdollisuutta käyttää sellaista, korvaavana välineenä voidaan käyttää palautumiseltaan riittävää toimistotuolia tai kovaa sohvaa. Ota huomioon harjoituskohteen joustavuus ja kovuus. SmartResQ ei suosittele pehmeiden esineiden, kuten tyynyjen tai pehmeiden sohvien, käyttämistä harjoittelussa, koska käyttäjäkokemus ei ole oikea.

\n\n

Jos et löydä harjoitusnukkea tai korvaavaa esinettä, harkitse harjoittelevasi tilannetta, joka tapahtuu ennen rintakehän painelujen aloittamista. Tämä voi tarkoittaa maksuttoman sovelluksen antamien sydänpysähdyksen tunnistamista ja hätäpuhelun soittamista koskevien tietojen noudattamista ja CorPatch®-laitteen purkamista avaimenperästä. Tällöin olet valmis käyttämään CorPatch®-laitetta nopeasti havaitessasi sydänpysähdyksen.

\n\n \n\n

Älä käytä SmartResQ/CorPatch®️-järjestelmää harjoitteluun tai ”huvin vuoksi” ihmisiin (eläviin tai kuolleisiin), lemmikkeihin tai muihin eläviin olentoihin.

\n\n \n\n

Tuotteita, verkkosivusto(j)a ja sovelluksia koskeva vastuuvapauslauseke

\n\n

SmartResQ/CorPatch® ei anna mitään vakuutuksia tai takuita eikä ole vastuussa kenenkään sellaisen henkilön pätevyydestä, joka saa järjestelmän kautta tai sen perusteella annettua koulutustietoa ja/tai lääketieteellistä koulutusta, tai siitä, että kyseinen henkilö käyttää taitojaan järjestelmää käyttävän koulutuksen, kurssin tai oppijakson suorittamisen jälkeen. SmartResQ/CorPatch® ei takaa, että järjestelmästä koulutustietoa ja/tai lääketieteellistä koulutusta saavat henkilöt saavuttavat tietyn taitotason tai tarvittavan pätevyyden, jotta he voivat saada minkä tahansa sääntelyelimen tai valtion viranomaisen myöntämän lisenssin, todistuksen tai luokituksen.

\n\n \n\n

SmartResQ/CorPatch® ja sen yhteistyökumppanit pyrkivät olemaan mahdollisimman tarkkoja. SmartResQ/CorPatch® ei kuitenkaan vakuuta eikä takaa, että järjestelmä ja tässä annetut tiedot, tuotteet ja koulutus: (a) ovat aina saatavilla tai ylipäätään saatavilla; tai (b) ovat virheettömiä, täydellisiä, tarkkoja, todenmukaisia, ajantasaisia ja/tai harhaanjohtamattomia. Kun käytät järjestelmää, tiedät ja olet tietoinen siitä, että luovut kaikista SmartResQ/CorPatch®:iin kohdistuvista vaateista, jotka perustuvat järjestelmän kautta esitettyjen tietojen tai koulutuksen luotettavuuteen.

\n\n \n\n

Tuotteitamme ei ole tarkoitettu lasten käyttöön. Tuotteet ovat pieniä ja värikkäitä, ja niitä voi erehtyä luulemaan leluiksi, mutta SmartResQ/CorPatch®-tuotteet eivät ole leluja! Suosittelemme, ettei tuotteita jätetä esille lasten ulottuville. SmartResQ/CorPatch® ei ota vastuuta siitä, että lapset käyttävät tuotteita. Vastuullisten aikuisten, esim. vanhempien, perheenjäsenten tai opettajien on annettava lapsille tai nuorille lupa käyttää CorPatch®-laitetta ja valvottava sen käyttöä.

\n\n \n\n

Vastuuvapauslauseke ja vastuunrajoitus, SmartResQ/CorPatch® tarjoaa tämän sivuston ”sellaisena kuin se on” ja ”sellaisena kuin se on saatavilla”. SmartResQ/CorPatch® ei anna minkäänlaisia, suoria tai epäsuoria vakuutuksia tai takuita tämän sivuston toiminnasta tai sen sisältämistä tiedoista, sisällöstä, materiaaleista tai tuotteista. Hyväksyt nimenomaisesti, että tämän sivuston käyttö tapahtuu omalla vastuullasi. \n
\nSovellettavan lain sallimissa rajoissa SmartResQ/CorPatch® kieltäytyy kaikista suorista tai epäsuorista takuista, mukaan lukien, mutta ei rajoittuen, epäsuorat takuut myyntikelpoisuudesta ja soveltuvuudesta tiettyyn tarkoitukseen. SmartResQ/CorPatch® ei takaa, että tämä sivusto, sen palvelimet tai SmartResQ/CorPatch®:n lähettämä sähköposti ei sisällä viruksia/roskapostia tai muita haitallisia komponentteja.

\n\n \n\n

SmartResQ/CorPatch® ei ole vastuussa mistään tämän sivuston tai sen tuotteiden käytöstä aiheutuvista vahingoista, mukaan lukien, mutta ei rajoittuen, suorat, epäsuorat, satunnaiset, rangaistusluonteiset ja välilliset vahingot. \n
\nTietyt osavaltioiden lait eivät salli epäsuorien takuiden rajoittamista tai tiettyjen vahinkojen poissulkemista tai rajoittamista. Jos näitä lakeja sovelletaan sinuun, jotkut tai kaikki edellä mainitut vastuuvapauslausekkeet, poissulkemiset tai rajoitukset eivät välttämättä koske sinua, ja sinulla saattaa olla lisäoikeuksia.

\n\n \n\n

Tällä verkkosivustolla esitettyjä tietoja ei pidä tulkita ammatilliseksi neuvonnaksi. Sinun on aina kysyttävä neuvoa tietyissä asioissa omaan tilanteeseesi perehtyneiltä ammattimaisilta neuvonantajilta ennen kuin teet mitään päätöksiä.

\n\n \n\n

Verkkosivusto voi sisältää linkkejä, jotka johtavat sellaisten henkilöiden tai organisaatioiden ylläpitämille verkkosivustoille, joihin SmartResQ/CorPatch® ei voi vaikuttaa. SmartResQ/CorPatch® ei anna mitään vakuutuksia eikä takuita tällaisten verkkosivustojen sisältämien tietojen tarkkuudesta tai muista näkökohdista.

\n\n \n\n

Vastuu tämän verkkosivuston artikkeleihin tai teksteihin sisältyvistä mielipiteistä, neuvoista, lausunnoista tai muista tiedoista on yksinomaan niiden kirjoittajalla, eivätkä ne välttämättä vastaa SmartResQ/CorPatch®:n mielipiteitä ja käytäntöjä.

\n\n \n\n

Vastuuvapauslauseke

\n\n

Ostamalla, lisensoimalla, katselemalla ja/tai käyttämällä verkkosivustoamme, tuotteitamme ja sovelluksiamme hyväksyt seuraavan:

\n
    \n
  1. SmartResQ/CorPatch®:n tarjoamat järjestelmät ovat tiettyjä tuotteita, joita saa käyttää ainoastaan tuotteen käyttöohjeessa mainittuun käyttötarkoitukseen. Lue ohjeet ja käyttöoppaat huolellisesti ja varmista, että tunnet lääkinnälliset tuotteemme ennen käyttöönottoa.
  2. \n\n
  3. SmartResQ/CorPatch®:n tarjoamat järjestelmät ovat erityisiä koulutus- ja lääketieteellisiä harjoittelutuotteita ja -välineitä ei ole sertifioitu lääkinnällisiksi laitteiksi, ellei sitä ole nimenomaisesti mainittu. Niitä ei ole tarkoitettu kliiniseen tai diagnostiseen käyttöön, ja ne on tarkoitettu käytettäväksi yksinomaan lääketieteelliseen koulutukseen ja suorituskyvyn parantamiseen.
  4. \n\n
  5. Käytät järjestelmää aina ainoastaan tällaiseen lääketieteelliseen koulutukseen ja suorituskyvyn parantamiseen liittyviin tarkoituksiin, kaikkien sovellettavien lakien ja asetusten mukaisesti sekä kaikkien sinulle sähköisesti tai henkilökohtaisesti toimittamiemme käyttäjäasiakirjojen, käyttöohjeiden, oppaiden ja/tai vaatimusten mukaisesti.
  6. \n\n
  7. SmartResQ/CorPatch®-järjestelmä ei voi missään vaiheessa yksinään diagnosoida, hoitaa tai parantaa ihmisen tilaa tai hengenpelastustilanteessa tukea ammattimaisia lääketieteellisiä päätöksiä, diagnooseja tai hoitoja tai korvata asianmukaisesti koulutetun ja lisensoidun lääkärin tekemää diagnoosia, suositusta, neuvoa, hoitoa tai päätöstä.
  8. \n\n
  9. Se, että laite on yhteydessä potilasvahinkoon tai -tulokseen, ei tarkoita, että laite olisi aiheuttanut vahingon tai tuloksen.
  10. \n\n
  11. SmartResQ/CorPatch® ei ota vastuuta vahingoista, jotka johtuvat tuotteidemme kohtuuttomasta käytöstä tai tuotteen käyttötarkoituksen ylittävästä käytöstä.
  12. \n
\n \n\n

Suorituskykytiedot

\n\n

Tässä esitetyt tiedot on tarkoitettu ainoastaan ohjeeksi SmartResQ/CorPatch®-tuotteiden käyttöä varten. SmartResQ/CorPatch® pyrkii jatkuvasti parantamaan tuotteidensa laatua ja luotettavuutta. Laitteissamme voi kuitenkin esiintyä toimintahäiriöitä tai vikoja, koska ne ovat luonnostaan sähköherkkiä ja alttiita fyysiselle rasitukselle ja haitallisille viestintäsignaaleille. SmartResQ/CorPatch®-tuotteita käyttäessään ostaja on vastuussa turvallisuus- ja testausstandardien noudattamisesta ja sellaisten tilanteiden välttämisestä, joissa toimintahäiriö tai vika voi johtaa henkilö- tai omaisuusvahinkoihin.

\n\n \n\n

Vakiotakuu

\n\n

SmartResQ/CorPatch®:n rajoitettu vakiotakuu edellyttää tuotteiden, verkkosivustojen ja sovellusten asianmukaista käyttöä. \n
\nTämä takuu koskee vain tuotteen ensimmäistä ostajaa ja vain, jos tuote on ostettu valtuutetulta SmartResQ/CorPatch®-jälleenmyyjältä. Muut valmistajat, toimittajat tai julkaisijat kuin SmartResQ/CorPatch®, voivat antaa omat takuunsa. Ota yhteyttä heihin saadaksesi lisätietoja.

\n\n \n\n

Takuu ei kata:

\n
    \n
  1. vikoja tai vaurioita, jotka johtuvat onnettomuudesta, väärinkäytöstä, epätavallisesta käytöstä, epätavallisista olosuhteista, epäasianmukaisesta varastoinnista, altistumisesta nesteelle, kosteudelle, hiekalle tai lialle, laiminlyönnistä tai epätavallisesta fyysisestä, sähköisestä tai sähkömekaanisesta rasituksesta,
  2. \n\n
  3. liiallisesta voimankäytöstä tai metalliesineiden käytöstä johtuvia vikoja tai vaurioita,
  4. \n\n
  5. laitteita, joiden valmistusnumero tai parannustietokoodi on poistettu, turmeltunut, vahingoittunut, muutettu tai tehty lukukelvottomaksi,
  6. \n\n
  7. tuotteen tavanomaista kulumista tai normaalia vanhenemista,
  8. \n\n
  9. naarmuja, kolhuja ja kosmeettisia vaurioita, ellei vika johdu materiaali- tai valmistusvirheestä,
  10. \n\n
  11. vikoja tai vahinkoja, jotka johtuvat tuotteiden käytöstä yhdessä tai yhteydessä sellaisten lisävarusteiden, tuotteiden tai lisä- tai oheislaitteiden kanssa, joita SmartResQ/CorPatch® ei ole toimittanut tai hyväksynyt,
  12. \n\n
  13. vikoja tai vahinkoja, jotka johtuvat epäasianmukaisesta testauksesta, käytöstä, ylläpidosta, asennuksesta, huollosta tai säädöstä, jota SmartResQ/CorPatch® ei ole toimittanut tai hyväksynyt,
  14. \n\n
  15. SmartResQ/CorPatch®-tuotteen käytöstä julkaistujen ohjeiden ulkopuolella aiheutuneet vahingot,
  16. \n\n
  17. ostetun tuotteen esittelyä/asennusta,
  18. \n\n
  19. vikoja tai vaurioita, jotka johtuvat ulkoisista syistä, kuten törmäyksestä esineeseen, tulipalosta, tulvasta, liasta, myrskystä, salamasta, maanjäristyksestä, altistumisesta sääolosuhteille, varkaudesta, sulakkeen rikkoutumisesta tai minkä tahansa sähkölähteen epäasianmukaisesta käytöstä,
  20. \n\n
  21. tartunnasta tai viruksista tai muista tuotteisiin sisältyvistä ohjelmisto-ongelmista johtuvat viat tai vahingot,
  22. \n\n
  23. jos akkuja ladataan muilla kuin CorPatch® Trainerin kanssa yhteensopivilla latureilla,
  24. \n\n
  25. akkukotelon tai kennojen sinetit ovat rikki tai niissä on merkkejä peukaloinnista,
  26. \n\n
  27. tuotteita, jotka on korjannut tai käyttänyt tai jotka on ostettu muulta yritykseltä kuin SmartResQ/CorPatch®,
  28. \n\n
  29. jos SmartResQ/CorPatch® saa asianomaisilta viranomaisilta tiedon, että tuote on varastettu tai jos et pysty poistamaan salasanaa tai muita turvatoimia, jotka on suunniteltu estämään luvattoman pääsyn tuotteeseen, tai jos et pysty todistamaan, että olet tuotteen valtuutettu käyttäjä,
  30. \n\n
  31. jos tuotteita käytetään käyttöohjeissa mainittujen olosuhteiden, esim. lämpötila-alueen, paineen ja kosteuden, ulkopuolella.
  32. \n
\n \n\n

Akut ja laturit

\n\n

SmartResQ/CorPatch®-tuotteet sisältävät joko ei-vaihdettavia akkuja (CorPatch®) tai ladattavia akkuja (CorPatch® Trainer). Tuotteissamme käytetyt akkutyypit on ilmoitettu kunkin yksittäisen tuotteen kohdalla. SmartResQ/CorPatch® ei ota vastuuta siitä, jos ladattavia akkuja ei käsitellä oikein käyttöohjeen mukaisesti.

\n\n \n\n

Akkuja sisältävien laitteiden myynnin yhteydessä meidän velvollisuutemme on kiinnittää huomiosi seuraaviin seikkoihin: \n
\nLoppukäyttäjänä sinulla on lakisääteinen velvollisuus hävittää ne asianmukaisesti. Yliviivatun roskakorin symboli tarkoittaa, ettei akkua saa hävittää kotitalousjätteen mukana.

\n\n
\n\n\n
\n

Tilaaminen

\n\n

Corpatch.com-verkkokauppa on avoinna 24 tuntia vuorokaudessa, ja voit tehdä ostoksia lähes milloin tahansa. Saatamme kuitenkin sulkea verkkokaupan ylläpidon ajaksi. Suuria määriä voi ostaa suoraan SmartResQ/CorPatch®:n kautta.

\n\n \n\n

SmartResQ/CorPatch® ei tarjoa tuotteita myytäväksi alaikäisille. Vain aikuiset voivat ostaa lapsille tarkoitettuja tuotteita. Ostaaksesi SmartResQ/CorPatch®:ltä sinun on oltava vähintään 18-vuotias ja sinulla on oltava voimassa oleva luottokortti tai muu hyväksymämme maksutapa.

\n\n \n\n

Verkkokaupan tuotteiden esittely ei ole oikeudellisesti sitova tarjous, vaan ei-sitova verkkoluettelo. Kun olet valmis tekemään ostoksia, valitse haluamasi tuotteet ja laita ne “Ostoskoriin”. Voit muokata ostoskorin sisältöä tilaushetkeen saakka. Kaikki lisämaksut, kuten toimituskulut tai pankkikorttimaksut, lasketaan välittömästi ennen maksua.

\n\n \n\n

Kun olet valmis tilaamaan, napsauta ”Kassalle\" ja anna tarvittavat tiedot. Voit muuttaa ostoskorin sisältöä siihen asti, kunnes vahvistat ostoksesi klikkaamalla ”Maksa”-painiketta Tämän jälkeen teet ostoskoriin sisältyvistä tavaroista sitovan tilauksen, jota ei voi enää muuttaa. \n
\nSmartResQ/CorPatch® voi hyväksyä tilauksen lähettämällä tilausvahvistuksen sähköpostitse tai toimittamalla tavarat toimitusajan kuluessa.

\n\n \n\n

Tietyt maat saattavat estää tuotteidemme käytön ja omistamisen. Olet yksin vastuussa siitä, että selvität, onko tämän tuotteen maahantuonti ja/tai käyttö maassasi laillista. Lähetämme sinulle tilaamasi tuotteet, emmekä voi ottaa vastuuta tullikysymyksistä tai tämän laitteen omistamiseen tai käyttöön liittyvistä seurauksista.

\n\n
\n\n\n
\n

Maksaminen

\n\n

Verkkosivustomme, sovelluksemme ja verkkokauppamme

\n\n

Verkkosivujemme ja sovellustemme käyttö on ilmaista, kunhan oikeudelliset periaatteet hyväksytään ja niitä noudatetaan. Huomaa, että tuotteidemme ostot saattavat olla saatavilla verkkokaupassa (verkkokaupoissa) verkkosivustollamme (verkkosivustoillamme) ja sovelluksessa (sovelluksissa).

\n\n \n\n

Tuotteemme

\n\n

SmartResQ/CorPatch® käyttää QuickPayta maksuyhdyskäytävänä. Maksukorttiteollisuuden (PCI) turvallisuusstandardilautakunta on sertifioinut QuickPayn PCI Data Security Standard (DSS) Level 1 -standardin viimeisimmän julkaisun mukaisesti, johon sisältyy: a) pätevän turvallisuusarvioijan (Qualified Security Assessor, QSA) laatima vuosittainen raportti - \"Report on Compliance\" (ROC); (b) hyväksytyn verkkotarkistuksen toimittajan (Approved Scan Vendor, ASV) neljännesvuosittain suorittamat verkkotarkistukset; ja c) suuri määrä työnkulkua ja tietojen käsittelyä koskevia sääntöjä ja ohjeita.

\n\n \n\n

Hyväksymme seuraavat maksutavat:

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • MasterCard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n \n\n

Maksut vähennetään tililtäsi tavaroiden lähetyksen yhteydessä. Kaikki summat ovat euromääräisiä, ja lakisääteinen arvonlisävero sisältyy jo kaikkiin mainittuihin hintoihin. Kaikkien luotto- tai maksukortin haltijoiden kortin myöntäjä tai maksupalveluntarjoaja suorittaa kortin kelpoisuustarkastuksen ja valtuutuksen. SmartResQ/CorPatch® ei ole vastuussa, jos maksukortintarjoajasi kieltäytyy hyväksymästä maksuja.

\n\n \n\n

Käytämme luottokorttitietojen salausta SSL-protokollan (Secure Socket Layer) avulla. Näin varmistetaan, etteivät muut voi siepata luottokortin numeroa tai muita tietoja palveluntarjoajamme kanssa suoritettavan maksutapahtuman aikana.

\n\n \n\n

Ennen sopimuksen tekemistä asiakkaan on tarkistettava ja hyväksyttävä ostohintaan lisätyt toimitus- ja logistiikkakulut, sillä ne veloitetaan asiakkaalta. Tehtyäsi tilauksen saat meiltä sähköpostiviestin, jossa ilmoitamme vastaanottaneemme tilauksesi. Huomaa, ettei tämä tarkoita, että tilauksesi on hyväksytty. Tilauksesi muodostaa tarjouksen SmartResQ/CorPatch®:lle tuotteen ostamisesta (ja SmartResQ/CorPatch® pidättää oikeuden kieltäytyä tuotteiden tilauksista). Tuotteita koskevaa sopimusta ei synny ennen kuin olemme vahvistaneet sinulle sähköpostitse, että tuotteet on lähetetty. Tarjouksesi hyväksyminen katsotaan täydelliseksi ja välillämme syntyy sopimus, kun lähetämme sinulle lähetysvahvistuksen sähköpostitse.

\n\n \n\n

Toimituskulut ilmoitetaan aina kuhunkin yksittäiseen tilaukseen liittyen.

\n\n \n\n

SmartResQ/CorPatch® säilyttää ostetun tuotteen omistusoikeuden siihen saakka, kunnes asiakas on maksanut laskun summan kokonaisuudessaan ja se on automaattisesti laadittu juuri ennen toimitusta.

\n\n \n\n

Asiakkailla on oikeus hyvitykseen vain, jos heidän vastasaatavansa on laillisesti vahvistettu tai SmartResQ/CorPatch® ei ole kiistänyt niitä tai on tunnustanut ne. Lisäksi asiakkaalla on pidättämisoikeus vain, jos ja siltä osin kuin hänen vastasaatavansa perustuu samaan sopimussuhteeseen.

\n\n \n\n

Jos asiakkaalla on meille maksuvelvoitteita, kaikki olemassa olevat saatavat erääntyvät välittömästi.

\n\n \n\n

Lisämaksut

\n\n

Lisämaksuja koskevia sääntöjä on muutettu 1.1.2018 alkaen. Näin ollen ei ole enää laillista periä lisämaksuja kuluttajakorteilla suoritettavista maksuista, jos kortit on myöntänyt EU:n alueella toimiva pankki / kortin myöntäjä. Tämä koskee sekä pankki- että luottokortteja. Kuluttajakortit ovat yksityiselle kuluttajalle myönnettyjä kortteja. \n
\nJos kortti on kuitenkin joko yrityskortti tai kuluttajakortti, joka on myönnetty EU:n ulkopuolella, tapahtumamaksusta peritään lisämaksu. Tämä tarkoittaa sitä, että kortinhaltija maksaa tapahtumamaksun automaattisesti. \n
\nMaksu ei ylitä SmartResQ/CorPatch®:n hankkijan veloittamaa maksua. Maksu näkyy selvästi erillisenä eränä maksuikkunassa.

\n\n
\n\n\n
\n

Toimitus

\n\n

Pyrimme toimittamaan tilaukset työpäivästä työpäivään ja käytämme kansainvälisesti luotettavaa kuljetusyritystä. Näet ostoksesi kokonaishinnan toimituksineen kassalla ennen lopullisen tilauksen hyväksymistä.

\n\n \n\n

Jos asiakas ei ota tavaroita vastaan, SmartResQ/CorPatch® voi peruuttaa sopimuksen tai saada korvauksen laiminlyönnistä kahden viikon kuluessa käsittely- ja toimituskulujen kattamiseksi.

\n\n \n\n

Jos asiakas on antanut virheelliset tiedot toimitusosoitteesta, paketti on mahdollista noutaa verkkokaupassamme mainitusta pakettiliikkeestä. Muutoin paketti menetetään.

\n\n \n\n

Asiakas ei koskaan saa osatoimituksia, ellei SmartResQ/CorPatch® ole nimenomaisesti ilmoittanut siitä.

\n\n \n\n

Menettämisriski

\n\n

Tuotteen omistusoikeus siirtyy ostajalle, kun tuote on saatettu ostajan käyttöön tämän sopimuksen mukaisesti. Jos toimitusaika on kulunut umpeen, eikä ostaja saa tuotetta, joka on saatettu hänen käyttöönsä sopimuksen mukaisesti, ostaja kantaa riskin tuotteen ominaisuuksista johtuvasta menetyksestä tai vahingosta.

\n\n
\n\n\n
\n

Peruutus ja palautukset

\n\n

Kun teet ostoksia SmartResQ/CorPatch®-verkkokaupassa tai offline-tilassa, on sinulla 14 päivää aikaa katua ja peruuttaa ostoksesi, jolloin voit ilmoittaa meille, että olet muuttanut mieltäsi ja palauttaa tuotteen meille samassa kunnossa kuin se on vastaanotettu. \n
\nHyväksymme vain käyttämättömien tuotteiden palautukset alkuperäisessä, sinetöidyssä ja vahingoittumattomassa pakkauksessa. Ne on pakattava asianmukaisesti lähetystä varten, muuten tuotteet katsotaan käytetyiksi, eikä osittaisia palautuksia hyväksytä. Peruuttamisoikeus koskee vain vastaanotettaessa sinetöimättömiä tuotteita.

\n

Hyväksyttävät syyt tuotteen palauttamiseksi

\n
    \n
  • 14 päivän peruutusoikeuden käyttäminen
  • \n\n
  • Tuote ei vastaa kuvausta (takuu)
  • \n\n
  • Tuote on viallinen
  • \n
\n \n\n

CorPatch®-palautusehdot ovat EU:n vakiosääntöjen mukaiset.

\n

Jos palautat tuotteen, säilytä alkuperäispakkaus. Älä vahingoita sitä tai liimaa tai kirjoita siihen. Hanki ja käytä erityistä palautuspakkausta, esim. pahvilaatikkoa.

\n\n \n\n

CorPatch® Trainer -tuotteen peruutusehdot ovat EU:n vakiosääntöjen mukaiset.

\n\n \n\n

Jos haluat käyttää peruutusoikeutta, sinun on ilmoitettava siitä meille 14 päivän kuluessa tuotteiden vastaanottamisesta. Peruutuspyynnöt on lähetettävä sähköpostitse osoitteeseen info@corpatch.com, ja niissä on ilmoitettava selkeästi, että haluat käyttää peruutusoikeuttasi sekä syy.

\n\n \n\n

Odotamme, että palautat tuotteet mahdollisimman pian sen jälkeen, kun olet tehnyt peruutusilmoituksen, ja viimeistään 14 päivän kuluessa siitä, kun olet ilmoittanut siitä meille sähköpostitse.

\n\n \n\n

Voimme hylätä takaisinmaksun, kunnes olet palauttanut tuotteet tai todistanut, että olet palauttanut ne. Takaisinmaksussa käytämme samaa maksutapaa kuin alkuperäisessä maksutapahtumassa.

\n\n \n\n

Syyt, joita ei hyväksytä tuotteen palauttamiseksi

\n
    \n
  • Mielenmuutos 14 päivän peruutusoikeuden jälkeen.
  • \n\n
  • Jos tuote on aktivoitu.
  • \n\n
  • Jos tuotetta käytetään tai se vahingoittuu muulla tavoin.
  • \n\n
  • Jos ohjelmisto/maksuton sovellus ladataan, yhdistetään, asennetaan tai muulla tavoin liitetään fyysiseen tuotteeseen (fyysisiin tuotteisiin).
  • \n
\n \n\n

Palauttaminen

\n\n

Hyväksymme vain avaamattomien tuotteiden palautukset alkuperäisessä ja vahingoittumattomassa pakkauksessa. Niiden on oltava asianmukaisesti pakattuja lähetystä varten, muutoin tuotteet katsotaan käytetyiksi, eikä palautuksia hyväksytä.

\n\n

Ellei muuta ole mainittu, palautukset on lähetettävä osoitteeseen: \n
\nSmartResQ ApS (CorPatch®) \n
\nLundevej 26 \n
\nDK-5700 Svendborg\n
\nTanska

\n \n\n

TÄRKEÄÄ! Olet yksin vastuussa pakkauksen laadusta ja tuotteista, kunnes olemme vastaanottaneet ne. Säilytä postikuitti, joka sisältää tiedot toimituskuluista ja tarvittaessa lähetysnumeron. Emme korvaa palautuksen toimituskuluja emmekä ota vastaan postiennakolla tai vastaavalla tavalla lähetettyjä paketteja.

\n\n
\n\n\n
\n

Hyvitykset

\n\n

SmartResQ/CorPatch® on velvollinen korjaamaan, vaihtamaan tai antamaan hinnanalennuksen tai täyden hyvityksen, jos tuote osoittautuu vialliseksi 2 vuoden kuluessa tuotteen ostamisesta. \n
\nAsiakkaalla ei ole oikeutta hyvitykseen, jos ongelma on vähäinen, kuten naarmut tuotteessa tai vastaava. \n
\nHyvitys käynnistetään kun SmartResQ/CorPatch® vastaanottaa asiakkaan tuotteen. Hyvityksen määrä riippuu tuotteiden tilasta SmartResQ/CorPatch®:n vastaanottohetkellä.

\n\n \n\n

Asiakkaan hyvityksen käsittelytapa riippuu alkuperäisestä maksutavasta. Jos asiakas on maksanut luotto- tai pankkikortilla, hyvitykset lähetetään kortin myöntäneeseen pankkiin 5 arkipäivän kuluessa palautetun tuotteen tai peruutuspyynnön vastaanottamisesta. Ota yhteyttä kortin myöntäneeseen pankkiin, jos sinulla on kysyttävää siitä, milloin hyvitys kirjataan tilillesi.

\n\n
\n\n\n
\n

Henkilötietojen käsittely

\n\n

SmartResQ/CorPatch® arvostaa henkilötietojasi kolmivaiheisen tietosuojan vaatimustenmukaisuuden avulla: a. pidämme yksityiskohtaista karttaa tietovirroistamme, b. suoritamme tietovirtaan perustuvan oikeudellisen arvioinnin, jotta voimme c. toteuttaa tarvittavat turvatoimet tietojesi suojaamiseksi.

\n \n\n

Käyttääksesi verkkokauppaamme sinun on annettava vähintään seuraavat tiedot:

\n
    \n
  • Nimi
  • \n\n
  • Osoite
  • \n\n
  • Sähköpostiosoite
  • \n\n
  • Puhelinnumero
  • \n
\n \n\n

Asiakkaiden henkilötietojen kerääminen tapahtuu voimassa olevan lainsäädännön ja EU:n yleisen tietosuoja-asetuksen (GDPR) puitteissa.

\n \n\n

Jos haluat lisätietoja henkilötietojesi käsittelystä, lue tietosuojakäytäntömme.

\n\n
\n\n\n
\n

Reklamaatiot

\n\n

Reklamaation tekeminen

\n\n

Jos tuotteessa on jotain vikaa, voit joko korjauttaa tai vaihtaa viallisen tuotteen, saada hyvityksen tai hinnanalennuksen tilanteesta riippuen. \n
\nEdellytyksenä on tietenkin, että reklamaatio on perusteltu ja ettei vika johdu tuotteen virheellisestä käytöstä tai muusta virheellisestä toiminnasta.

\n\n\n

Suosittelemme, että reklamoit mahdollisimman pian ja viikon kuluessa vian havaitsemisesta.\n
\nJos sinulla on kysyttävää, kommentteja tai reklamaatioita, ota meihin yhteyttä sähköpostitse osoitteeseen: info@corpatch.com.

\n\n

Reklamaatio muille EU:n elimille

\n\n

Jos haluat reklamoida muille EU:n elimille, käy Euroopan unionin virallisella verkkosivustolla. Löydät tietoa täältä.

\n\n
\n\n\n
\n

Tämän asiakirjan muutokset

\n\n

Verkkosivustojen, sovellusten ja käytäntöjen muutokset

\n\n

SmartResQ/CorPatch® pidättää oikeuden tehdä muutoksia, poistaa, muokata tai täydentää verkkosivusto(j)a, sovelluksia, käytäntöjä ja asiakirjoja milloin tahansa ja mistä tahansa syystä ilman ennakkoilmoitusta. \n
\nJos jokin näistä ehdoista katsotaan pätemättömäksi, mitättömäksi tai jostain syystä täytäntöönpanokelvottomaksi, kyseinen ehto katsotaan erotettavaksi, eikä se vaikuta muiden ehtojen pätevyyteen ja täytäntöönpanokelpoisuuteen.

\n\n \n\n

Jos muutamme käytäntöjämme, julkaisemme tarkistetut käytännöt verkossa päivitetyn tarkistuspäivämäärän kera. Kehotamme sinua tarkistamaan käytännöt säännöllisesti. Jos teemme käytäntöihimme olennaisia muutoksia, jotka muuttavat merkittävästi käytäntöjämme, saatamme ilmoittaa sinulle myös muilla tavoin, esimerkiksi lähettämällä sähköpostia tai julkaisemalla ilmoituksen verkkosivustollamme ja/tai sosiaalisessa mediassa ennen muutosten voimaantuloa.

\n\n \n\n

Tiettyyn ostokseen liittyvä

\n\n

Kun ostat tuotteen, sinua pyydetään hyväksymään tiettyjen asiakirjojen versio sellaisena kuin ne ovat juuri kyseisenä ajankohtana – tätä versiota ei muuteta enää kyseisen ajankohdan jälkeen, ja se määrää ehdot, jotka koskevat suhdettamme sinuun juuri kyseisen ostoksen osalta.

\n\n
\n\n\n
\n

Laki ja lainkäyttöalue

\n\n

Tanskan lait ja Svendborgin käräjäoikeus

\n\n

SmartResQ/CorPatch® soveltaa Tanskan lakia ja oikeuspaikkaa kaikkiin oikeudellisiin riitoihin, mutta ei YK:n kansainvälistä tavaran kauppaa koskevaa yleissopimusta. \n
\nKaikki riidat, jotka liittyvät millään tavalla vierailuusi SmartResQ/CorPatch®:ssa tai SmartResQ/CorPatch®:n kautta ostamiisi tuotteisiin, on käsiteltävä luottamuksellisesti Tanskassa, lukuun ottamatta sitä, että jos olet jollain tavalla loukannut tai uhannut loukata SmartResQ/CorPatch®:n teollis- ja tekijänoikeuksia, SmartResQ/CorPatch® voi hakea kieltotuomiota tai muuta asianmukaista oikeussuojaa mistä tahansa maasta, ja suostut yksinomaiseen tuomiovaltaan ja oikeuspaikkaan tällaisissa tuomioistuimissa.

\n

Jos käyttöehtosopimusta rikotaan, ryhdytään oikeustoimiin ja kanne voidaan nostaa tuomioistuimessa.

\n\n \n\n

Meidän ja kuluttajan väliset riidat käsitellään Svendborgin käräjäoikeudessa, Christiansvej 41, DK-5700 Svendborg, Tanska.

\n\n
\n\n\n
\n

Yhteystiedot

\n\n

Kiitos, että luit SmartResQ/CorPatch®:n käyttöehdot. \n
\nJos sinulla on kysyttävää, kommentteja tai reklamaatioita, ota yhteyttä meihin.

\n\n \n\n

Yrityksemme sijaitsee osoitteessa: Lundevej 26, DK-5700 Svendborg, Tanska

\n\n \n\n

Löydät meidät keskusyritysrekisteristä ALV-numerolla DK 38674102

\n\n \n\n

Voit soittaa meille numeroon +45 62 200 100

\n\n \n\n

tai

\n\n \n\n

lähettää sähköpostia osoitteeseen: info@corpatch.com

\n\n \n\n

© SmartResQ ApS – Kaikki oikeudet pidätetään \n
\nTanska, versio 2.1 – Julkaistu 25.4.2023

\n\n
\n \n \n \n\n\n\n\n \n \n\n
\n

SmartResQ/CorPatch® -tietosuojakäytäntö

\n\n\n

Käsittelemme tietojasi EU:n yleisen tietosuoja-asetuksen mukaisesti

\n\n

SmartResQ/CorPatch® kunnioittaa yksityisyyttäsi. Tässä tietosuojalausunnossa kuvataan yksityisyydensuojasi ja sitoumuksemme henkilötietojesi suojaamiseen.

\n\n

Jos sinulla on kysyttävää henkilötietojesi käsittelystä, ota yhteyttä meihin. Rekisterinpitäjä on:

\n\n

Yritys: SmartResQ ApS (CorPatch®)

\n\n

Osoite: \n
\nLundevej 26 \n
\nDK-5700 Svendborg \n
\nTanska

\n\n

CVR-numero: 38674102

\n\n

Puhelin: +45 62 200 100

\n\n

Sähköposti: info@corpatch.com

\n\n

SmartResQ/CorPatch® on tanskalainen/eurooppalainen yritys, jolla on oikeussubjekteja, liiketoimintaprosesseja, hallintorakenteita ja teknisiä järjestelmiä yli kansallisten rajojen. SmartResQ/CorPatch® tarjoaa tuotteita, ohjelmistoja ja palveluja julkisille/yksityisille yrityksille Euroopassa.

\n\n

Pääkonttori sijaitsee Tanskassa ja SmartResQ/CorPatch® on eurooppalaisen tietosuojalainsäädännön alainen, mukaan lukien yleinen tietosuoja-asetus (GDPR). SmartResQ/CorPatch® tekee tärkeimmät henkilötietojen suojaa koskevat päätökset johtotasolla tietosuojavastaavan valvonnassa.

\n\n

Tämä tietosuojalausunto on saatavilla verkkosivustoillamme ja sovelluksissamme.

\n\n

Älä käytä SmartResQ/CorPatch®-sivustoja, sovelluksia tai palvelujamme, jos et hyväksy tapaa, jolla käsittelemme henkilötietoja tämän tietosuojaselosteen mukaisesti.

\n\n
\n\n\n
\n

Keräämiemme henkilötietojen tyyppi

\n\n

Kun käsittelijä määrittää henkilötietojesi käsittelytarkoitukset ja -keinot, käsittelijä toimii rekisterinpitäjänä. Tämä sisältää skenaariot, joissa SmartResQ/CorPatch® kerää henkilötietoja kun olet työnhakija, asiakkaan edustaja tai liidi, tai kun olet ohjelmiston käyttäjä.

\n\n

SmartResQ käsittelee henkilötietoja eri tarkoituksiin riippuen suhteestamme sinuun.

\n\n

Voimme käsitellä seuraavia tietoja:

\n
    \n
  1. perusyhteystiedot, kuten nimi, osoite, puhelinnumero (matkapuhelin ja/tai lankapuhelin) ja sähköpostiosoite,
  2. \n\n
  3. työllisyystiedot, kuten työnantaja, titteli, asema, mukaan lukien ammatilliset mieltymykset ja mielenkiinnon kohteet,
  4. \n\n
  5. palaute, kommentit ja kysymykset, joiden aiheena ovat SmartResQ/CorPatch® tai tuotteemme ja palvelumme,
  6. \n\n
  7. valokuvat tai videot, jotka on tallennettu toimipaikoissamme,
  8. \n\n
  9. lataamasi sisältö, kuten valokuvat, videot ja suoritukset ajan myötä,
  10. \n\n
  11. yksilölliset käyttäjätiedot, kuten sisäänkirjautumistunnus, käyttäjätunnus, salasana ja turvakysymys,
  12. \n\n
  13. taloudelliset tiedot, jos hyväksyt sen, että käytämme tietojasi esimerkiksi maksukorttitietojesi tallentamiseen,
  14. \n\n
  15. verkkoselaimesi tarjoamat liikennetiedot, kuten selaintyyppi, laite, kieli ja sen verkkosivuston osoite, josta tulit sekä muut liikennetiedot, mukaan lukien IP-osoite,
  16. \n\n
  17. napsautusvirtakäyttäytyminen ja toiminta SmartResQ/CorPatch®:n tunnuksilla sekä tuotteissamme ja palveluissamme,
  18. \n\n
  19. sähköpostikäyttäytyminen, kuten SmartResQ/CorPatch®:n sähköpostiviestit, jotka avaat milloin ja miten,
  20. \n\n
  21. muut henkilötiedot, jotka sisältyvät profiiliisi ja jotka olet asettanut vapaasti kolmansien osapuolten sosiaalisiin verkostoihin, kuten LinkedIn, Facebook, Google jne.,
  22. \n\n
  23. tiedot, joita käytetään tieteellisiin tarkoituksiin sydänpysähdyksen jälkeisen eloonjäännin parantamiseksi ja jotka on kerätty verkkosivujemme ja sovellustemme kautta,
  24. \n\n
  25. tietoa käyttäjistä, jotta voimme toimittaa tuotteita laatu- ja turvallisuusvaatimusten mukaisesti, tarjota palveluja käyttäjille sekä ylläpitää ja parantaa tarjontaamme,
  26. \n\n
  27. tietoa työnhakijoista, jotta voimme käsitellä työhakemuksia, tiedottaa tulevista työtarjouksista sekä ylläpitää ja parantaa rekrytointiprosessejamme,
  28. \n\n
  29. tietoa henkilöistä, jotka ovat hyväksyneet uutiskirjeiden ja muiden materiaalien vastaanottamisen, jotta voimme toimittaa materiaalit sekä ylläpitää ja parantaa tarjontaamme,
  30. \n\n
  31. evästetiedot räätälöidyn mainonnan tarjoamiseksi sosiaalisessa mediassa ja verkkosivustoilla.
  32. \n
\n
\n\n\n
\n

CorPatch® Services -alustalla ja -sovelluksissa kerätyt ja käsitellyt tiedot

\n\n

SmartResQ käsittelee, kerää ja tallentaa seuraavia henkilötietoja, kun käytät CorPatch® Services -alustaa ja -sovelluksia.

\n\n \n \n\n

Kaikki käyttäjät (koulutuslaitoksen järjestelmänvalvoja, trainer, trainee / loppukäyttäjä)

\n
    \n
  • Etunimi (jos ilmoitettu)
  • \n\n
  • Sukunimi (jos ilmoitettu)
  • \n\n
  • Lempinimet (jos ilmoitettu)
  • \n\n
  • Sähköpostiosoite (pakollinen)
  • \n\n
  • Ensisijainen viestintäkieli (pakollinen)
  • \n\n
  • Salasanan salaus (pakollinen)
  • \n\n
  • Onko sähköpostiosoite vahvistettu (pakollinen)
  • \n
\n \n\n

Lisäksi traineet/loppukäyttäjät (pakollinen)

\n\n

Käytetyn matkapuhelimen tiedot:

\n\n

Käyttöjärjestelmä (Android/iOS):

\n
    \n
  • Käyttöjärjestelmäversio (esim. 9)
  • \n\n
  • Valmistaja (esim. Samsung)
  • \n\n
  • Malli (esim. SM-T518)
  • \n\n
  • Sovellusversio (esim. 1.2.4)
  • \n\n
  • Sovelluksen viimeisen etualapalvelun aika
  • \n\n
  • Sovelluksen viimeisen taustapalvelun aika
  • \n
\n \n\n

Käytetyn CorPatch®:n (CPS) tiedot:

\n
    \n
  • Sarjanumero / MAC-osoite
  • \n\n
  • Laiteohjelmistoversio
  • \n\n
  • Mallinimi (esim. CPS_01)
  • \n\n
  • Valmistaja (tällä hetkellä aina SRQ)
  • \n\n
  • Nimi (tällä hetkellä aina CorPatch®)
  • \n\n
  • Akun kunto
  • \n\n
  • Viat
  • \n
\n \n\n

Käyttäjän perehdytystiedot:

\n
    \n
  • Tutorial suoritettu (kyllä/ei)
  • \n\n
  • Käyttöehdot hyväksytty (kyllä/ei)
  • \n\n
  • Itsearviointi suoritettu (kyllä/ei)
  • \n\n
  • Testiharjoitus suoritettu (kyllä/ei)
  • \n\n
  • Ensimmäinen sisäänkirjautuminen onnistui (kyllä/ei)
  • \n\n
  • Oliko CPS yhdistetty (kyllä/ei)
  • \n
\n \n\n

Koulutuksen kautta kerätyt tiedot:

\n
    \n
  • Koulutuksen päivämäärä, aika ja kesto
  • \n\n
  • Koulutuksen tulos
  • \n\n
  • Koulutustyyppi ja koulutusasetukset
  • \n\n
  • Jos kyseessä on koulutus koulutuslaitoksessa, lisätietoja kurssista, kouluttajasta ja koulutuslaitoksesta
  • \n
\n \n \n\n

Palvelinlokit

\n\n

Seuraavat tiedot tallennetaan verkkopalvelinlokeihin:

\n
    \n
  • Yhteyttä käyttävän osapuolen IP-osoite
  • \n\n
  • Yhteyttä käyttävän osapuolen selainversio
  • \n\n
  • Yhteyden käytön aika/päivämäärä
  • \n\n
  • Yhteys-URL
  • \n
\n\n

Ulkoiset tietoja käsittelevät palvelut:

\n
    \n
  • Google/Firebase etälokeja, kaatumisten ja virheiden analysointia varten
  • \n\n
  • Google/Firebase ilmoitusten lähettämistä varten
  • \n\n
  • Sendgrid sähköpostiviestien lähettämistä varten
  • \n\n
  • Hetzner Online GmbH verkkopalvelin- ja tietokantaisännöintiä varten
  • \n
\n \n\n

Mitä tapahtuu, kun käyttäjä poistetaan

\n
    \n
  • Käyttäjä poistaa itsensä järjestelmästämme CorPatch® Services -verkkosivulla https://app.corpatch.com.
  • \n\n
  • Käyttäjä merkitään poistetuksi. Tämän jälkeen hän ei voi enää kirjautua sisään, hän ei näy enää järjestelmänvalvojille jne. Käyttäjä on kuitenkin edelleen tietokannassa.
  • \n\n
  • 14 päivän jälkeen käyttäjän tiedot poistetaan automaattisesti tietokannasta.
  • \n\n
  • Tieteellistä arviointia ja toiminnallisuuden parantamista varten CorPatch®:n koulutuksia ja käyttöä koskevat tiedot säilyvät tietokannassa myös käyttäjän poistamisen jälkeen, mutta viittaus (ID) käyttäjään on tyhjä ja kaikki viittaukset henkilötietoihin poistetaan.
  • \n
\n\n
\n\n\n
\n

Kuinka keräämme henkilötietojasi

\n\n

Sinä toimitat meille suurimman osan käsittelemistämme henkilötiedoista itse. Keräämme tietoja ja käsittelemme niitä, kun sinä:

\n
    \n
  • rekisteröidyt verkossa tai tilaat tuotteitamme tai palvelujamme; esim. demografiset tiedot, sähköpostiosoite, maksutiedot, tuotteet, tilausmäärä, alennus ja tiheys. Mukaan lukien transaktiosähköpostiviestien, kuten tilausvahvistuksen, toimitusvahvistuksen ja palautusvahvistuksen, lähettäminen,
  • \n\n
  • osallistuminen lähetettyyn viestintään (sähköposti, tekstiviesti, suoramainonta tai puhelin); esim. avaamisaste, klikkausaste ja sähköpostien lukemiseen käytetty aika, lähettäjän verkkotunnus ja sähköpostiohjelman tyyppi,
  • \n\n
  • täytät vapaaehtoisesti asiakaskyselyn tai annat palautetta millä tahansa ilmoitustaulullamme tai sähköpostitse.
  • \n
\n\n

Saatamme myös saada henkilötietoja epäsuorasti seuraavilta lähteiltä seuraavissa tapauksissa:

\n
    \n
  • Evästeistä: kun käyt verkkosivustoillamme tai sovelluksissamme, esim. IP-osoite, maa, katsotut sivut, katsotut tuotteet, vuorovaikutus/klikkaukset ja haut.
  • \n\n
  • Sinulta tai muulta asiakkaaseemme liittyvältä henkilöltä. Tällainen henkilö voi olla johtaja tai kollega. Jos asiakas, jolle työskentelet, ostaa tuotteita tai palveluja SmartResQ/CorPatch®:lta SartResQ/CorPatch®:n kumppaniyrityksen kautta, saatamme kerätä sinua koskevia tietoja kumppaniyritykseltä.
  • \n\n
  • SmartResQ/CorPatch®:n markkinointikumppanit, julkiset lähteet tai kolmansien osapuolten sosiaaliset verkostot.
  • \n\n
  • SmartResQ/CorPatch® voi yhdistää yhdestä lähteestä kerättyjä henkilötietojasi toisesta lähteestä saatuihin tietoihin. Näin saamme kokonaisemman kuvan sinusta, jolloin voimme myös palvella sinua asianmukaisemmin ja räätälöidymmin.
  • \n
\n\n
\n\n\n
\n

Kuinka käytämme tietojasi

\n\n

SmartResQ/CorPatch® tarvitsee tietoja sinusta, kun olet asiakkaana tai kun käytät palvelua, jotta voimme yleisesti hallinnoida asiakassuhteitamme ja täyttää asiakassitoumuksemme. Tällaisten henkilötietojen käsittelyn tarkoituksena on:

\n\n
    \n
  • tilauksesi käsittely, tilisi hallinnointi,
  • \n\n
  • muita tuotteita ja palveluita, joista saattaisit pitää, koskevien erikoistarjousten lähettäminen sinulle sähköpostitse,
  • \n\n
  • myynti- ja sopimusprosessin suorittaminen asiakkaille,
  • \n\n
  • pyydettyjen tuotteiden ja palvelujen toimittaminen asiakkaille,
  • \n\n
  • toimitusten suorittaminen sinun tai asiakkaiden kanssa tehtyjen sopimusten mukaisesti,
  • \n\n
  • tuen tarjoaminen tuotteidemme ja palvelujemme käyttäjille,
  • \n\n
  • tuotteidemme ja palvelujemme sekä SartResQ/CorPatch®-verkkosivustojen ja -sovellusten laadun, toiminnallisuuden ja käyttäjäkokemuksen parantaminen ja kehittäminen,
  • \n\n
  • tietoturvauhkien havaitseminen, rajoittaminen ja ehkäiseminen sekä ylläpito, vianmääritys ja virheenkorjaus,
  • \n\n
  • tuotteidemme ja palvelujemme väärinkäytön estäminen,
  • \n\n
  • tilausten käsittely, laskutus, maksut tai muu taloudellinen seuranta,
  • \n\n
  • kiinnostusprofiilien luominen merkityksellisten tuotteiden ja palveluiden myynninedistämiseksi,
  • \n\n
  • käyttäjäyhteisöjen perustaminen käyttäjien ja SmartResQ/CorPatch®:n välisen koulutuksen ja vuorovaikutuksen helpottamiseen.
  • \n
\n

Tietoa liideistä

\n\n

SmartResQ/CorPatch® käsittelee liidien henkilötietoja markkinointitarkoituksiin. Tarjotakseen kohdennettua ja relevanttia sisältöä mahdollisille asiakkaille SmartResQ/CorPatch® luo kiinnostusprofiilin, joka perustuu aktiivisuuteesi, valintoihisi ja toimiisi SmartResQ/CorPatch®-sivuilla sekä reagointiisi markkinointisisältöön. Käsittelyn oikeudellinen perusta on ensisijaisesti sinun antamasi suostumus.

\n\n

Tietoa työnhakijoista

\n\n

Jos olet työnhakija, käsittelemme henkilötietoja arvioidaksemme potentiaaliasi SmartResQ/CorPatch®:n työntekijänä. Turvallinen, verkossa toimiva ura-alustamme takaa, että noudatamme uusimpia tietosuojaa koskevia lakeja ja asetuksia. Käsittelyn oikeudellinen perusta on antamasi suostumus.

\n\n

Tietoa verkkosivustolla kävijöistä

\n\n

Jotta voimme seurata sivustojemme käyttöä, käsittelemme kävijöiden henkilötietoja. Käsittely perustuu oikeutettuun etuumme suojella liikesalaisuuksiamme, työntekijöitämme, toimipaikkojamme ja sinua kävijänä. Sinulle ilmoitetaan oikeuksistasi tässä yhteydessä, kun rekisteröidyt sähköiseen kävijäjärjestelmäämme.

\n\n

PPE:n laadun parantamiseksi, erityisesti PPE-koulutuksen avulla, SmartResQ/CorPatch® saattaa jakaa tietojasi kumppaniyrityksillemme (koulutuslaitoksille), jotta ne voivat tarjota sinulle tuotteitaan ja palvelujaan.

\n\n

Kun käsittelemme tilauksesi, järjestelmämme voi lähettää tietojasi luottotietotoimistoille ja käyttää niistä saatuja tietoja petollisten ostosten estämiseksi.

\n\n
\n\n\n
\n

Kuinka säilytämme henkilötietojasi

\n\n

SmartResQ/CorPatch® ottaa sinun ja asiakkaidemme osoittaman luottamuksen erittäin vakavasti. SmartResQ/CorPatch® sitoutuu välttämään henkilötietojen luvatonta käyttöä, luovuttamista tai muuta poikkeavaa käsittelyä. SmartResQ/CorPatch® varmistaa käsittelemiemme henkilötietojen luottamuksellisuuden, säilyttää henkilötietojen eheyden ja varmistaa niiden saatavuuden sovellettavien tietosuojalakien mukaisesti.

\n\n

Osana sitoumuksiamme käytämme kohtuullisia ja riittäviä organisatorisia, teknisiä ja fyysisiä menettelyjä ja toimenpiteitä keräämiemme ja käsittelemiemme tietojen suojaamiseksi. Otamme huomioon henkilötietotyypin ja riskin, jolle asiakkaamme altistuvat mahdollisen tietoturvaloukkauksen vuoksi, koska on erittäin todennäköistä, että henkilötietojen tietoturvaloukkausten perimmäiset syyt löytyvät sisäisesti. Uskomme, että sellaisen vahvan yrityskulttuurin rakentaminen, jossa tietosuojaa kunnioitetaan ja valvotaan työntekijöidemme keskuudessa, on olennaisen tärkeää tietojesi lainmukaisen käsittelyn ja suojaamisen varmistamiseksi. Tietoturvaloukkauksen sattuessa SmartResQ/CorPatch® noudattaa Tanskan tietosuojaviraston määrittämiä käytäntöjä.

\n\n

Tietojasi säilytetään turvallisesti EU:n yleisen tietosuoja-asetuksen määräysten mukaisesti.

\n\n
\n\n\n
\n

Kuinka kauan säilytämme henkilötietojasi?

\n\n

SmartResQ/CorPatch® säilyttää henkilötietojasi vain niin kauan kuin se on tarpeen ilmoitettuja tarkoituksia varten, ottaen samalla huomioon tarpeemme vastata kyselyihin ja ratkaista ongelmia sekä noudattaa sovellettavan lain mukaisia oikeudellisia vaatimuksia.

\n\n

Tämä tarkoittaa, että SmartResQ/CorPatch® voi säilyttää henkilötietojasi kohtuullisen ajan sen jälkeen, kun sinä ja asiakkaamme olette viimeksi olleet kanssamme tekemisissä. Kun keräämämme henkilötiedot eivät ole enää tarpeellisia, poistamme ne. Voimme käsitellä tietoja tilastollisia ja/tai tieteellisiä tarkoituksia varten, mutta tällaisissa tapauksissa tiedot pseudonymisoidaan tai anonymisoidaan.

\n\n \n \n\n

Tietojen säilyttämisen aikarajat

\n\n

Säilytämme henkilötietojasi niin kauan kuin on tarpeen tässä tietosuojakäytännössä esitettyjen tarkoitusten täyttämiseksi, ellei laki, oikeudelliset, verotukselliset tai sääntelyyn liittyvät syyt tai muut lailliset ja oikeutetut liiketoimintatarkoitukset edellytä tai salli pidempää säilytysaikaa.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Tarkoitus Aikaraja
Asiakaspalvelun ja kirjanpidon sääntely 5 vuotta tai niin kauan kuin meillä on velvollisuus täyttää tarvittava oikeudellinen vaatimus. \n
\n \n\nPoistamme rekisteröintitietosi heti, kun poistat käyttäjätilisi meiltä tai kun lakisääteinen säilytysaika umpeutuu. \n
Ura-alusta 6 kuukautta hakemusasiakirjoille, jotka eivät johda työnhakijan palkkaamiseen. \n
\n \n\nUusiminen 6 kuukauden välein, jos haluat, että tulet harkituksi täytettäessä uusia avoimia työpaikkoja, ja suostut pidempään säilytysaikaan. \n
Markkinointitarkoitus 3 vuotta viimeisimmästä toiminnastasi, esim. vierailusta verkkosivustoillamme, ostoksesta tai viestintään osallistumisesta. \n
\n \n\nJos olet antanut markkinointiluvan (sähköposti, tekstiviesti, puhelin jne.), ja jos meillä on lupasi ottaa yhteyttä sinuun. \n
\n \n\nPoistamme sähköpostiosoitteesi uutiskirjeestä automaattisesti, kun poistat käyttäjätilisi tai jos peruutat uutiskirjeemme tilauksen. \n
Tilaushistorian säilyttäminen ja tilausten täyttämisvelvoitteet 5 vuotta tai niin kauan kuin meillä on velvollisuus täyttää tarvittavat oikeudelliset vaatimukset \n
Asiakaskokemus 3 vuotta viimeisimmästä toiminnastasi, esim. vierailusta verkkosivustoillamme, ostoksesta tai viestintään osallistumisesta. \n
\n \n\nJos olet antanut markkinointiluvan (sähköposti, tekstiviesti, puhelin jne.), ja jos meillä on lupasi. \n
Petokset ja riskinarviointi 5 vuotta tai niin kauan kuin meillä on velvollisuus täyttää tarvittava oikeudellinen vaatimus.
\n\n
\n\n\n
\n

Markkinointiviestintä

\n\n

Sinulla on oikeus kieltäytyä vastaanottamasta markkinointiviestintää SmartResQ/CorPatch®:ltä. Voit tehdä sen kahdella eri tavalla:

\n
    \n
  • noudata asianomaisen markkinointiviestinnän peruutusohjeita,
  • \n\n
  • muuta asetuksia tilin muokkausosiossa, jos sinulla on SmartResQ/CorPatch®-tili,
  • \n\n
  • ota meihin yhteyttä sähköpostitse osoitteeseen info@corpatch.com
  • \n
\n \n\n

Huomaa, että vaikka kieltäytyisit vastaanottamasta markkinointiviestintää, saatat silti saada SmartResQ/CorPatch®:ltä hallinnollisia viestejä, kuten tilausvahvistuksia ja ilmoituksia, jotka ovat tarpeen tilisi hallinnoimiseksi tai asiakkaillemme esimerkiksi mobiilipalveluiden tai -sovellusten kautta tarjottavien palveluiden hallinnoimiseksi.

\n\n
\n\n\n
\n

Tietosuojaoikeutesi

\n\n

SmartResQ/CorPatch®:lle on tärkeää, että olet tietoinen kaikista tietosuojaoikeuksistasi.

\n\n

Jotkut tietosuojalait, mukaan lukien EU:n yleinen tietosuoja-asetus (GDPR), vastaava lainsäädäntö Saksassa Bundesdatenschutzgesetz (BDSG), Sveitsissä ja Yhdistyneessä kuningaskunnassa sekä jotkut Yhdysvaltojen osavaltioiden lait, antavat sinulle tiettyjä oikeuksia, jotka liittyvät meille jakamiisi henkilötietoihin. Jos asut Euroopan talousalueella, sinulla voi olla seuraavat oikeudet:

\n
    \n
  1. Tarkastusoikeus – Sinulla on oikeus pyytää meiltä kopioita henkilötiedoistasi.
  2. \n\n
  3. Oikaisuoikeus – Sinulla on oikeus pyytää meitä oikaisemaan henkilötiedot, jotka ovat mielestäsi virheellisiä. Sinulla on myös oikeus pyytää meitä täydentämään tietoja, jotka ovat mielestäsi puutteellisia.
  4. \n\n
  5. Poisto-oikeus – Sinulla on oikeus pyytää meitä poistamaan henkilötietosi tietyin edellytyksin.
  6. \n\n
  7. Käsittelynrajoitusoikeus – Sinulla on oikeus pyytää meitä rajoittamaan henkilötietojesi käsittelyä tietyin edellytyksin.
  8. \n\n
  9. Käsittelynvastustusoikeus – Sinulla on oikeus vastustaa henkilötietojesi käsittelyä tietyin edellytyksin.
  10. \n\n
  11. Oikeus tietojen siirrettävyyteen – Sinulla on oikeus pyytää, että siirrämme keräämämme henkilötiedot toiselle organisaatiolle tai tietyin edellytyksin suoraan sinulle.
  12. \n
\n \n\n

Jos haluat käyttää jotakin näistä oikeuksista, ota meihin yhteyttä sähköpostiosoitteeseen info@corpatch.com.

\n\n
\n\n\n
\n

Mitä evästeet ovat?

\n\n

Evästeet ovat pieniä tekstitiedostoja, jotka sisältävät merkkijonon ja luovat käyttäjälle yksilöllisen tunnuksen. Ne palautetaan verkkosivustolle ja/tai kolmansille osapuolille. Useimmat selaimet on alun perin asetettu hyväksymään evästeet, koska useimpien verkkosivustojen on käytettävä niitä. Voit kuitenkin muuttaa selainasetuksia niin, että selaimesi voi yleensä hylätä evästeet, estää kolmannen osapuolen evästeet tai määrittää, milloin eväste lähetetään.

\n \n \n\n

SmartResQ/CorPatch® on sitoutunut varmistamaan, että sinulla on oikeus mukauttaa etujasi ja hallita meiltä tulevan digitaalisen markkinoinnin laajuutta valinnanhallintajärjestelmän avulla.

\n\n
\n\n\n
\n

Miten käytämme evästeitä

\n\n

SmartResQ/CorPatch® käyttää evästeitä monin eri tavoin parantaakseen käyttökokemustasi verkkosivustoillamme, sovelluksissamme ja palveluissamme erilaisista syistä, kuten:

\n
    \n
  • Toiminnallisuus – käytämme näitä evästeitä tunnistamaan sinut verkkosivustollamme ja muistamaan aiemmin valitsemasi asetukset. Näitä ovat valitsemasi kieli ja sijainti, jossa olet. Käytössä on yhdistelmä ensimmäisen ja toisen osapuolen evästeitä.
  • \n\n
  • Mainonta – käytämme näitä evästeitä kerätäksemme tietoja vierailustasi verkkosivustoillamme tai sovelluksissamme, katsomastasi sisällöstä, seuraamistasi linkeistä sekä tietoja selaimestasi, laitteestasi ja IP-osoitteestasi. Joskus jaamme joitakin rajoitettuja osia näistä tiedoista kolmansien osapuolten kanssa mainostarkoituksiin. Voimme jakaa myös evästeiden avulla kerättyjä verkkotietoja mainoskumppaneidemme kanssa. Tämä tarkoittaa, että vieraillessasi toisella verkkosivustolla sinulle saatetaan näyttää mainoksia, jotka perustuvat selaustottumuksiisi verkkosivustollamme.
  • \n
\n\n\n
\n\n\n
\n

Käyttämiemme evästeiden tyyppi

\n\n

Verkkosivusto(i)llamme käytetään seuraavan tyyppisiä evästeitä:

\n
    \n
  • Google Analytics: Tämän evästeen avulla voimme tarkastella tietoja käyttäjien suorittamista toiminnoista verkkosivustolla, mukaan lukien mutta ei rajoittuen sivujen katseluun, lähteeseen ja verkkosivustolla vietettyyn aikaan. Tiedot anonymisoidaan ja näytetään lukuina, joten niitä ei voida jäljittää yksittäisiin henkilöihin. Tämä auttaa suojaamaan yksityisyyttäsi. Google Analyticsin avulla näemme, mikä sisältö on suosittua sivuillamme, ja pyrimme tarjoamaan sinulle enemmän sitä, mitä haluat lukea ja nähdä. \n\n
  • Google Analytics -uudelleenmarkkinointi: Asettaa evästeitä tietokoneellesi, mikä tarkoittaa, että kun poistut sivustoltamme, Google voi näyttää sinulle SmartResQ/CorPatch®-mainoksia, joista saatat olla kiinnostunut sen perusteella, miten olet aiemmin käyttäytynyt sivustollamme. Näitä tietoja ei voida tunnistaa henkilökohtaisesti. \n\n
  • Google Ads: Google Adsin avulla näemme, mitkä sivut olivat avuksi yhteydenottolomakkeemme kautta tapahtuvassa lähettämisessä. Näitä tietoja ei voida tunnistaa henkilökohtaisesti, mutta yhteydenottolomakkeen tiedot voidaan. \n\n
  • Google Ads -uudelleenmarkkinointi: Asettaa evästeitä tietokoneellesi, mikä tarkoittaa, että kun poistut sivustoltamme, Google voi näyttää sinulle SmartResQ/CorPatch®-mainoksia, joista saatat olla kiinnostunut sen perusteella, miten olet aiemmin käyttäytynyt sivustollamme. Näitä tietoja ei voida tunnistaa henkilökohtaisesti. \n\n
  • Facebook-uudelleenmarkkinointi: Facebookin seurantapikseli asettaa tietokoneellesi evästeitä, jotka kertovat Facebookille sinun käyneen sivustolla. Oletamme, että olet kiinnostunut SmartResQ/CorPatch®:sta ja tämän sivuston sisällöstä. Kun käyt Facebookissa, sinulle esitetään tietoa tai mainoksia, joissa on samankaltainen sisältö. Käytä Facebookin yksityisyysasetuksiasi rajoittaaksesi tämän tyyppisen markkinoinnin esittämistä. \n\n
  • YouTube: Integroimme videoita Googlen YouTube-alustalta (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, Yhdysvallat). Tietosuojakäytäntö: https://www.google.com/policies/privacy/.
  • \n
\n \n
\n\n\n
\n

Miten voin hallita evästeitä

\n\n

Voit asettaa selaimen hylkäämään evästeitä tai poistamaan evästeitä. Jotkut verkkosivustomme ominaisuudet eivät kuitenkaan ehkä toimi siitä johtuen. Katso, kuinka vältät evästeet tietyissä selaimissa:

\n\n \n\n

SmartResQ/CorPatch® käyttää joitakin luotettavia kolmannen osapuolen palveluita sivuillamme. Palvelut saattavat hyödyntää evästeitä. Voit hylätä kolmannen osapuolen evästeet selaimessasi napsauttamalla tätä linkkiä.

\n\n

Voit estää Googlea keräämästä ja käsittelemästä Googlen evästeen tuottamia tietoja verkkosivustomme käytöstä lataamalla ja asentamalla Google Analytics Opt-out -selainlisäosan nykyiseen selaimeesi. Tämä lisäosa on saatavilla täältä.

\n\n
\n\n\n
\n

Muiden verkkosivustojen tietosuojakäytännöt

\n\n

SmartResQ/CorPatch®-verkkosivustot sisältävät linkkejä muille verkkosivustoille. Tietosuojakäytäntömme koskee ainoastaan verkkosivustoamme, joten jos napsautat linkkiä toiselle verkkosivustolle, sinun on luettava sen tietosuojakäytäntö.

\n\n
\n\n\n
\n

Tietosuojakäytäntömme muutokset

\n\n

Jos muutamme tietosuojalausuntoamme, julkaisemme tarkistetun lausunnon täällä päivitetyn tarkistuspäivän kera. Suosittelemme tarkistamaan lausunnon säännöllisesti. Jos teemme lausuntoomme olennaisia muutoksia, jotka muuttavat merkittävästi tietosuojakäytäntöjämme, saatamme ilmoittaa sinulle myös muilla tavoin, esimerkiksi lähettämällä sähköpostia tai julkaisemalla ilmoituksen verkkosivustollamme ja/tai sosiaalisessa mediassa ennen muutosten voimaantuloa.

\n\n
\n\n\n
\n

Kuinka voin ottaa yhteyttä SmartResQ ApSiin

\n\n

Jos sinulla on kysyttävää SmartResQ/CorPatch®:n tietosuojakäytännöstä, hallussamme olevista tiedoistasi tai jos haluat käyttää jotakin tietosuojaoikeuksiasi, ota meihin yhteyttä.

\n\n

Sähköposti: info@corpatch.com

\n\n

Verkkosivusto: https://corpatch.com

\n\n
\n\n\n
\n\n

Kuinka voin ottaa yhteyttä asianomaiseen viranomaiseen

\n\n

Jos haluat tehdä valituksen tai jos SmartResQ/CorPatch® ei mielestäsi ole käsitellyt ongelmaasi tyydyttävällä tavalla, voit ottaa yhteyttä tietosuojavaltuutetun toimistoon.

\n\n

Tietosuojavaltuutetun toimiston osoite: \n

\nInformation Commissioner’s Office \n
\nWycliffe House \n
\nWater Lane \n
\nWilmslow \n
\nCheshire \n
\nSK9 5AF

\n\n \n\n

Asiakaspalvelun puhelinnumero: +44 303 123 1113

\n\n

ICO verkkosivusto: https://www.ico.org.uk

\n\n

© SmartResQ ApS – Kaikki oikeudet pidätetään \n
\nTanska, Versio 1.3 – Julkaistu 25.4.2023

\n\n
\n\n
\n\n`\n\nexport const termsOfUse_fr_FR: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n
\n\n \n\n\n
\n\n

Conditions générales & Politique de confidentialité

\n

SmartResQ ApS / CorPatch®

\n \n
\n \n\n
\n

Conditions générales – SmartResQ ApS / CorPatch®

\n\n

Objet de ce document

\n\n

Bienvenue sur SmartResQ/CorPatch® !

\n\n \n\n

Vous lisez actuellement nos conditions générales ; un document contenant des informations sur votre relation avec SmartResQ ApS, qui a commencé lorsque vous avez accédé à notre site Web, téléchargé notre ou nos applications gratuites, ou acheté l’un de nos produits ou similaire.

\n\n \n\n

SmartResQ/CorPatch® et ses associés vous fournissent leurs produits et services sous réserve des conditions suivantes. Si vous visitez ou passez commande sur nos sites Web ou applications, vous acceptez ces conditions. Nous vous conseillons vivement de les lire attentivement avant de procéder à toute utilisation de nos produits ou services.

\n\n \n\n

Ce document couvre :

\n
    \n
  • Comment contacter SmartResQ
  • \n\n
  • Produits, propriétés et bon usage
  • \n\n
  • Avis de non-responsabilité et garanties
  • \n\n
  • Commande
  • \n\n
  • Paiement
  • \n\n
  • Livraison
  • \n\n
  • Responsabilités et droits relatifs à la vente
  • \n\n
  • Retours
  • \n\n
  • Traitement des données personnelles
  • \n\n
  • Réclamations
  • \n\n
  • Modifications apportées à ce document
  • \n\n
  • Droit et juridiction
  • \n\n
  • Coordonnées de contact
  • \n
\n \n\n

Si vous avez des questions concernant les « Conditions générales » de SmartResQ, veuillez nous contacter.

\n\n \n\n

Comment contacter SmartResQ

\n\n

SmartResQ s’efforce d’augmenter les chances de survie grâce à une RCR de qualité en cas d’arrêt cardiaque. Nous voulons préparer et guider les passants à agir dès les premières minutes cruciales après avoir été témoins d’un arrêt cardiaque. C’est pourquoi nous avons développé CorPatch® - nous vous aidons à sauver une vie.

\n\n \n\n

Notre société est située à Lundevej 26, 5700 Svendborg, Danemark

\n\n \n\n

Vous pouvez nous trouver au registre central des entreprises sous le numéro de TVA DK 38674102

\n\n \n\n

Vous pouvez nous appeler au numéro de téléphone +45 62 200 100

\n\n \n\n

ou

\n\n \n\n

envoyez-nous un e-mail à info@corpatch.com

\n\n \n\n

Des questions, commentaires ou réclamations ?

\n\n

Nous apprécions votre opinion, veuillez donc nous contacter via les coordonnées mentionnées ci-dessus ou utiliser le formulaire de contact sur nos sites Web ou applications.

\n\n
\n\n\n
\n

Produits, propriétés et bon usage

\n\n

Nos sites Web, applications et produits

\n\n

Les paragraphes suivants décrivent les propriétés, droits et responsabilités essentiels liés à l’utilisation des services, applications et produits SmartResQ/CorPatch®. \n
\nNous déployons des efforts raisonnables pour inclure des informations exactes et à jour sur le(s) site(s) Web et dans les applications. Cependant, SmartResQ/CorPatch® ne fournit aucune garantie ou représentation quant à l’exactitude des informations. Nous déclinons toute responsabilité vis-à-vis de toute erreur ou omission dans le contenu, les produits et les applications du site Web. Les informations fournies sur ce site Web ou dans les applications ne remplacent pas les soins médicaux. Nous assumons la responsabilité de nos produits et applications conformément au Règlement relatif aux dispositifs médicaux UE 2017/745 (RDM).

\n\n \n\n

Droits d’auteur

\n\n

Tout le contenu figurant sur ce site, tel que les textes, les graphiques, les logos, les symboles de bouton, les images, les clips audio, les téléchargements numériques, les compilations de données et les logiciels, est la propriété de SmartResQ/CorPatch® ou de ses fournisseurs de contenu, et est protégé par les lois internationales sur les droits d’auteur. La compilation de tout le contenu de ce site est la propriété exclusive de SmartResQ/CorPatch®, avec la paternité des droits d’auteur pour cette collection par SmartResQ/CorPatch® et protégée par les lois internationales sur les droits d’auteur.

\n\n \n\n

Marques et modèles déposés

\n\n

Les marques déposées SmartResQ/CorPatch®, l’habillage commercial et la conception des produits ne sauraient être utilisés en relation avec tout produit ou service ne provenant pas de SmartResQ/CorPatch®, d’une manière susceptible de semer la confusion parmi les clients, ou de dénigrer ou discréditer SmartResQ/CorPatch®. Toutes les autres marques déposées non détenues par SmartResQ/CorPatch® ou ses filiales qui apparaissent sur ce site sont la propriété de leurs propriétaires respectifs, qui peuvent ou non être affiliés, connectés ou parrainés par SmartResQ/CorPatch® ou ses filiales.

\n\n \n\n

Licence et accès au site

\n\n

SmartResQ/CorPatch® vous accorde une licence limitée pour accéder et faire un usage personnel de son ou ses site(s) et application(s) et non pour télécharger (autrement que pour la mise en cache de page) ou modifier tout ou partie de celui-ci, sauf avec le consentement écrit exprès de SmartResQ/ CorPatch®. Cette licence n’inclut pas la revente ou l’utilisation commerciale de ces site(s) ou applications, ou de leur contenu : (a) toute collecte et utilisation de listes de produits, de descriptions ou de prix ; (b) toute utilisation dérivée de ce site ou de son contenu ; (c) tout téléchargement ou copie d’informations de compte au profit d’un autre marchand ; ou (d) toute utilisation d’exploration de données, de robots ou d’outils similaires de collecte et d’extraction de données.

\n\n \n\n

Ce site (ou cette application ou toute partie de ce site) ne peut être reproduit, repensé, dupliqué, copié, vendu, revendu, visité ou autrement exploité à des fins commerciales sans le consentement exprès écrit de SmartResQ/CorPatch®. Vous ne pouvez pas encadrer ou utiliser des techniques de cadrage pour joindre une marque, un logo ou d’autres informations exclusives (y compris des images, du texte, une mise en page ou un formulaire) de SmartResQ/CorPatch® et de nos associés sans consentement explicite écrit.

\n\n \n\n

Vous ne pouvez pas utiliser de balises méta ou tout autre « texte caché » utilisant le nom ou les marques SmartResQ/CorPatch® sans le consentement explicite écrit de SmartResQ/CorPatch®. Toute utilisation non autorisée met fin à l’autorisation ou à la licence accordée par SmartResQ/CorPatch®.

\n\n \n\n

Vous bénéficiez d’un droit limité, révocable et non exclusif de créer un lien hypertexte vers la page d’accueil de SmartResQ/CorPatch® tant que le lien ne représente pas SmartResQ/CorPatch®, ses associés ou leurs produits ou services sous une forme fausse, trompeuse, désobligeante ou autrement offensante. Vous ne pouvez pas utiliser le logo SmartResQ/CorPatch® ou tout autre graphique ou marque déposée dans le cadre du lien sans autorisation explicite écrite. \n
\nSi l’accord sur la licence et l’accès au site est violé, des poursuites judiciaires seront engagées et une action en justice pourra être intentée devant un tribunal.

\n\n

Communication électronique

\n\n

Lorsque vous visitez la page d’accueil et les réseaux sociaux de SmartResQ/CorPatch® ou que vous nous envoyez des e-mails, vous communiquez avec nous par voie électronique. Vous consentez à recevoir des communications de notre part de manière électronique. Nous communiquerons avec vous par e-mail ou en publiant des avis sur nos sites Web ou dans les applications sous la forme de fenêtres contextuelles ou de notifications. Vous convenez que tous les accords, avis, divulgations et autres communications que nous vous fournissons par voie électronique satisfont à toute exigence légale selon laquelle ces communications doivent être écrites. Veuillez vous référer à notre politique de confidentialité dans un document séparé qui peut être trouvé sur notre page d’accueil.

\n\n \n\n

Les visiteurs de notre site Web et de nos canaux de médias sociaux peuvent être invités à publier des critiques, des commentaires et d’autres contenus, par exemple soumettre des suggestions, des idées, des commentaires, des questions ou d’autres informations, tant que le contenu n’est pas illégal, obscène, menaçant, diffamatoire, envahissant la vie privée, portant atteinte aux droits de propriété intellectuelle ou autrement préjudiciable à des tiers ou répréhensible, et ne consiste pas en ni ne contient des virus logiciels, des campagnes politiques, des sollicitations commerciales, des chaînes de lettres, des envois de masse ou toute forme de « spam ».

\n\n \n\n

Vous ne pouvez pas utiliser une fausse adresse e-mail, usurper l’identité d’une personne ou d’une entité, ou autrement induire en erreur quant à l’origine d’une carte ou de tout autre contenu. SmartResQ/CorPatch® se réserve le droit (mais pas l’obligation) de supprimer ou de modifier ce contenu, mais ne révise pas régulièrement le contenu publié. Si vous publiez du contenu ou soumettez des documents et sauf indication contraire de notre part, vous accordez à SmartResQ/CorPatch® et à ses associés un droit non exclusif, libre de droits, perpétuel, irrévocable et entièrement sous-licenciable d’utiliser, reproduire, modifier, adapter, publier, traduire, créer des œuvres dérivées à partir de, distribuer et afficher ce contenu dans le monde entier sur n’importe quel support. Vous accordez à SmartResQ/CorPatch® et à ses associés et sous-licenciés le droit d’utiliser le nom que vous soumettez en relation avec ce contenu s’ils le souhaitent.

\n\n \n\n

Vous déclarez et garantissez que vous possédez ou contrôlez autrement tous les droits sur le contenu que vous publiez ; que le contenu est exact ; que l’utilisation du contenu que vous fournissez ne viole pas cette politique et ne causera de préjudice à aucune personne ou entité ; et que vous indemniserez SmartResQ/CorPatch® ou ses associés pour toutes les réclamations résultant du contenu que vous fournissez. SmartResQ/CorPatch® a le droit mais non l’obligation de surveiller et de modifier ou de supprimer toute activité ou contenu. SmartResQ/CorPatch® décline toute responsabilité et n’assume aucune responsabilité pour tout contenu publié par vous-même ou un tiers.

\n\n
\n\n\n
\n

Avis de non-responsabilité et garanties

\n\n

Informations sur le produit – CorPatch® et CorPatch® Trainer

\n\n

Pour une utilisation correcte de tout produit ou service SmartResQ/CorPatch®, vous devez toujours suivre les derniers guides d’utilisation, instructions et descriptions. Ceux-ci peuvent être trouvés sur notre site Web et sous chaque description de produit.

\n\n \n\n

Le produit CorPatch® est un dispositif médical certifié. En cas d’urgence concernant une personne adulte en arrêt cardiaque, le produit doit être sorti de son boîtier, puis placé et attaché correctement sur la poitrine de la personne en arrêt cardiaque. Le produit peut collecter des données sur la compression, la profondeur, la fréquence et le relâchement, et peut les transmettre via Bluetooth® à des appareils potentiels. Des applications gratuites sur les appareils peuvent aider le passant à utiliser la RCR et afficher la fraction de flux, la profondeur, le relâchement et la fréquence si elles sont activées et correctement installées, c’est-à-dire via Bluetooth®, smartphone, application, alimentation de la batterie, etc. SmartResQ/CorPatch® n’est pas responsable des facteurs externes, par exemple, des signaux de communication perturbateurs, un manque de couverture des données, un manque de batterie, des paramètres matériels ou logiciels incorrects, qui peuvent affecter l’expérience de l’utilisateur ou similaire.

\n\n \n\n

De même, SmartResQ/CorPatch® n’est pas responsable des dommages physiques causés lors de l’utilisation du produit s’il n’est pas appliqué ou utilisé conformément aux instructions, par exemple, le fait d’effectuer des compressions thoraciques de manière non ergonomique ou d’avoir une position des mains inappropriée. SmartResQ/CorPatch® a évalué les risques techniques dans le cadre de la gestion des risques prescrite par la loi pour les dispositifs médicaux, mais aucune garantie n’est fournie pour les erreurs allant au-delà. En cas de dysfonctionnements inattendus ou de comportement non plausible d’un système SmartResQ/CorPatch®, l’utilisateur est invité à effectuer la RCR manuellement. Dans ce cas, SmartResQ/CorPatch® n’est pas responsable car cela est hors du contrôle de SmartResQ/CorPatch®. \n
\nSmartResQ/CorPatch® surveille les niveaux et l’état de santé de la batterie, mais si la batterie est déchargée, le produit ne fonctionnera pas. C’est à l’utilisateur seul qu’il incombe de s’assurer que l’appareil est à jour, non endommagé et dispose d’une batterie suffisante pour fonctionner correctement, ce qui peut être fait facilement en exécutant une session d’entraînement qui valide la fonctionnalité correcte. Nous vous recommandons de vous entraîner pendant 4 minutes tous les 3 mois avec votre CorPatch®.

\n\n \n\n

Important ! Le produit CorPatch® doit être utilisé exclusivement sur une personne en situation réelle et uniquement en cas d’arrêt cardiaque. Il n’est pas destiné à être utilisé sur des personnes souffrant, par exemple, d’un accident vasculaire cérébral, d’une crise cardiaque ou d’autres maladies liées qui ne sont pas un arrêt cardiaque. Le CorPatch® n’est pas destiné à être utilisé si la personne est allongée sur une surface molle, par exemple un canapé ou un lit, car les commentaires de profondeur dans de telles conditions peuvent s’avérer inexacts. Aucune solution SmartResQ/CorPatch® n’est destinée à être utilisée dans un environnement mobile, y compris, mais sans s’y limiter, une ambulance aérienne, maritime ou routière. S’il est utilisé pendant le transport du patient ou s’il est soulevé/retiré du corps pendant la RCR, l’appareil pourrait fournir des informations inexactes. Le CorPatch® doit être attaché à la poitrine du patient avec le patch. Assurez-vous que le patient est allongé sur une surface ferme, horizontale et immobile et que le CorPatch® est attaché à la poitrine avec le patch.

\n\n \n\n

Le produit CorPatch® Trainer doit être utilisé exclusivement sur des mannequins ou objets similaires lors de Training Sessions et jamais en situation réelle sur une personne réelle souffrant d’un arrêt cardiaque ou de toute autre maladie.

\n\n \n\n

Il est possible d’exercer régulièrement vos performances de RCR par rapport aux compressions thoraciques en utilisant CorPatch® ou CorPatch® Trainer. Nous vous recommandons de vous entraîner sur un mannequin, mais si vous n’en disposez pas, une chaise de bureau suffisamment réactive ou un canapé dur peuvent être utilisés en remplacement. Considérez l’élasticité et la dureté de l’objet avec lequel vous vous entraînez. SmartResQ ne recommande pas d’utiliser des objets mous, y compris, mais sans s’y limiter, des oreillers ou des canapés moelleux lors de l’entraînement, car l’expérience utilisateur ne sera pas correcte.

\n\n\n

Si vous ne trouvez pas de mannequin ou d’objet de remplacement pour l’entraînement, envisagez de vous entraîner aux gestes requis avant de commencer les compressions thoraciques. Il peut s’agir de déballer le CorPatch® du porte-clés et de suivre les informations fournies par l’application gratuite sur l’identification d’un arrêt cardiaque et l’appel des services d’urgence. Dans ce cas, vous pourrez appliquer le CorPatch® rapidement au cas où vous seriez témoin d’un arrêt cardiaque.

\n\n \n\n

N’utilisez aucun système SmartResQ/CorPatch® pour vous entraîner ou « vous amuser » sur une personne (vivante ou morte), un animal de compagnie ou tout autre être vivant.

\n\n \n\n

Avis de non-responsabilité concernant les produits, le(s) site(s) Web et les applications

\n\n

SmartResQ/CorPatch® ne fait aucune représentation ou garantie et ne sera pas responsable de la compétence de toute personne qui recevrait des informations éducatives et/ou une formation médicale fournies par ou basées sur le système ou de l’exercice de ses compétences par une telle personne après l’achèvement de toute formation, cours ou cursus utilisant le système. SmartResQ/CorPatch® ne garantit pas que toute personne recevant des informations pédagogiques et/ou une formation médicale du système atteindra un niveau de compétence particulier ou les compétences nécessaires pour se qualifier pour une licence, des certificats ou des qualifications délivrés par un organisme de réglementation ou une autorité gouvernementale.

\n\n \n\n

SmartResQ/CorPatch® et ses associés s’efforcent d’être aussi précis que possible. Cependant, SmartResQ/CorPatch® ne fait aucune représentation et ne donne aucune garantie que le système et les informations, produits et formations fournis ici : (a) seront toujours ou simplement disponibles ; ou (b) sont exempts d’erreurs, complets, exacts, véridiques, à jour et/ou non trompeurs. Lorsque vous utilisez le système, vous avez conscience que vous renoncez à toute réclamation que vous pourriez avoir contre SmartResQ/CorPatch® pour vous être fié(e) à toute information ou entraînement fourni par le système.

\n\n \n\n

Nos produits ne sont pas destinés à être utilisés par des enfants. Les produits sont petits et colorés, et peuvent être confondus avec des jouets, mais les produits SmartResQ/CorPatch® ne sont pas des jouets ! Nous vous recommandons de ne pas laisser les produits dans un endroit accessible aux enfants. SmartResQ/CorPatch® décline toute responsabilité concernant l’utilisation des produits par les enfants. Toute utilisation de CorPatch® par des enfants ou des adolescents doit être autorisée et surveillée par des adultes responsables, par exemple les parents, un membre de la famille ou des enseignants.

\n\n \n\n

Exclusion de garantie et limitation de responsabilité, ce site est fourni par SmartResQ/CorPatch® sur une base « telle quelle » et « telle que disponible ». SmartResQ/CorPatch® ne fait aucune représentation ou garantie d’aucune sorte, explicite ou implicite, quant au fonctionnement de ce site ou aux informations, contenus, matériaux ou produits inclus sur ce site. Vous convenez expressément que votre utilisation de ce site s’effectue à vos risques et périls. \n
\nDans toute la mesure permise par la loi applicable, SmartResQ/CorPatch® décline toute garantie, explicite ou implicite, y compris, mais sans s’y limiter, les garanties implicites de qualité marchande et d’adéquation à un usage particulier. SmartResQ/CorPatch® ne garantit pas que ce site, ses serveurs ou les e-mails envoyés par SmartResQ/CorPatch® sont exempts de virus/spam ou d’autres composants nuisibles.

\n\n \n\n

SmartResQ/CorPatch® ne sera pas responsable des dommages de toute nature résultant de l’utilisation de ce site ou de ses produits, y compris, mais sans s’y limiter, les dommages directs, indirects, accessoires, punitifs et consécutifs. \n
\nLes lois de certains États n’autorisent pas les limitations des garanties implicites ou l’exclusion ou la limitation de certains dommages. Si ces lois s’appliquent à vous, certaines ou toutes les clauses de non-responsabilité, exclusions ou limitations ci-dessus peuvent ne pas s’appliquer dans votre cas, et vous pourriez bénéficier de droits supplémentaires.

\n\n \n\n

Les informations présentées sur ce site Web ne doivent pas être interprétées comme des conseils professionnels. Vous devriez toujours consulter des conseillers professionnels familiers avec votre situation factuelle pour obtenir des conseils sur des questions spécifiques avant de prendre une décision.

\n\n \n\n

Le site Web peut contenir des liens menant à des sites Web gérés par des individus ou des organisations sur lesquels SmartResQ/CorPatch® n’a aucun contrôle. SmartResQ/CorPatch® ne fait aucune déclaration et ne fournit aucune garantie concernant l’exactitude ou tout autre aspect des informations contenues sur ces sites Web.

\n\n \n\n

La responsabilité des opinions, conseils, déclarations ou autres informations contenues dans les articles ou textes de ce site Web incombe uniquement à l’auteur et ne reflète pas nécessairement les opinions et les politiques de SmartResQ/CorPatch® en tant que telle.

\n\n \n\n

Avertissement légal

\n\n

En achetant, octroyant une licence, visualisant, utilisant et/ou accédant à nos sites Web, produits et applications, vous reconnaissez et acceptez que :

\n
    \n
  1. Les systèmes fournis par SmartResQ/CorPatch® sont des produits spécifiques à utiliser uniquement pour l’usage prévu indiqué dans le manuel du produit. Veuillez lire attentivement les instructions d’utilisation et les manuels et assurez-vous de bien connaître nos produits médicaux avant de les utiliser.
  2. \n\n
  3. Les systèmes fournis par SmartResQ/CorPatch® sont des produits et outils pédagogiques et médicaux spécifiques qui ne sont pas certifiés en tant que dispositifs médicaux, sauf indication explicite ; ils ne sont pas destinés à un usage clinique ou diagnostique et sont destinés à être utilisés uniquement à des fins de formation médicale et d’amélioration des performances.
  4. \n\n
  5. À tout moment, vous ne devez utiliser et accéder au système que dans le cadre de ces objectifs de formation médicale et d’amélioration des performances ; en conformité avec toutes les lois et réglementations applicables ; et conformément à toute documentation utilisateur, manuels d’instructions, guides et/ou exigences que nous sommes susceptibles de vous fournir par voie électronique ou en personne.
  6. \n\n
  7. À aucun moment un système SmartResQ/CorPatch® ne peut à lui seul diagnostiquer, traiter ou guérir la maladie d’un être humain ou dans une situation vitale ; aider aux décisions, diagnostics ou traitements médicaux professionnels ou remplacer tout diagnostic, recommandation, conseil, traitement ou décision par un médecin dûment formé et agréé.
  8. \n\n
  9. L’association d’un dispositif avec un préjudice ou un résultat pour le patient ne signifie pas que le dispositif a causé le préjudice ou le résultat.
  10. \n\n
  11. SmartResQ/CorPatch® décline toute responsabilité vis-à-vis des dommages résultant d’une utilisation déraisonnable de ses produits ou d’une utilisation au-delà de l’utilisation prévue du produit.
  12. \n
\n \n\n

Informations sur les performances

\n\n

Les informations contenues dans ce document sont présentées uniquement à titre de guide pour l’application des produits SmartResQ/CorPatch®. SmartResQ/CorPatch® travaille continuellement à l’amélioration de la qualité et de la fiabilité de ses produits. Néanmoins, nos appareils peuvent mal fonctionner ou tomber en panne en raison de leur sensibilité électrique inhérente et de leur vulnérabilité au stress physique et aux signaux de communication indésirables. Il incombe à l’acheteur, lors de l’utilisation des produits SmartResQ/CorPatch®, de respecter les normes de sécurité et de test, et d’éviter les situations dans lesquelles un dysfonctionnement ou une panne pourrait entraîner des blessures corporelles ou des dommages matériels.

\n\n \n\n

Garantie standard

\n\n

La garantie limitée standard SmartResQ/CorPatch® est conditionnelle à l’utilisation appropriée des produits, des sites Web et des applications.\n
\nCette garantie est limitée au premier acheteur du produit uniquement et uniquement si le produit a été acheté auprès d’un revendeur SmartResQ/CorPatch® agréé. Les fabricants, fournisseurs ou éditeurs, autres que SmartResQ/CorPatch®, peuvent vous fournir leurs propres garanties – veuillez les contacter pour plus d’informations.

\n\n \n\n

La garantie ne couvre pas :

\n
    \n
  1. Les défauts ou dommages résultant d’un accident, d’une mauvaise utilisation, d’une utilisation anormale, de conditions anormales, d’un stockage inapproprié, d’une exposition à un liquide, à l’humidité, au sable ou à la saleté, d’une négligence ou d’une contrainte physique, électrique ou électromécanique inhabituelle
  2. \n\n
  3. Les défauts ou dommages résultant d’une force excessive ou de l’utilisation d’objets métalliques
  4. \n\n
  5. Les équipements dont le numéro de production ou le code de données d’amélioration a été supprimé, dégradé, endommagé, modifié ou rendu illisible
  6. \n\n
  7. L’usure normale ou le vieillissement normal du produit
  8. \n\n
  9. Les rayures, bosses et dommages esthétiques, à moins que la panne ne soit due à un défaut de matériaux ou de fabrication
  10. \n\n
  11. Les défauts ou dommages résultant de l’utilisation de produits en conjonction ou en connexion avec des accessoires, des produits ou des équipements auxiliaires/périphériques qui ne sont pas fournis ou approuvés par SmartResQ/CorPatch®
  12. \n\n
  13. Les défauts ou dommages résultant d’un test, d’un fonctionnement, d’une maintenance, d’une installation, d’un entretien ou d’un réglage inappropriés,qui ne sont pas fournis ou approuvés par SmartResQ/CorPatch®
  14. \n\n
  15. Les dommages causés par l’utilisation du produit SmartResQ/CorPatch® en dehors des directives publiées
  16. \n\n
  17. La démonstration / installation du produit acheté
  18. \n\n
  19. Les défauts ou dommages résultant de causes externes telles que collision avec un objet, incendie, inondation, saleté, rafale de vent, foudre, tremblement de terre, exposition aux conditions météorologiques, vol, fusible grillé ou mauvaise utilisation d’une quelconque source électrique
  20. \n\n
  21. Les défauts ou dommages résultant de la transmission ou de virus, ou d’autres problèmes logiciels introduits dans les produits
  22. \n\n
  23. Si les batteries sont chargées par des chargeurs autres que ceux compatibles avec CorPatch® Trainer
  24. \n\n
  25. L’un des sceaux du boîtier de la batterie ou des cellules est brisé ou présente des signes d’effraction
  26. \n\n
  27. Les produits réparés par, utilisés ou achetés auprès d’une autre société que SmartResQ/CorPatch®
  28. \n\n
  29. Si SmartResQ/CorPatch® reçoit des informations des autorités publiques compétentes indiquant que le produit a été volé, ou si vous ne parvenez pas à désactiver les mesures de sécurité activées par mot de passe ou autres conçues pour empêcher l’accès non autorisé au produit, ou si vous ne pouvez pas prouver que vous êtes l’utilisateur autorisé du produit
  30. \n\n
  31. Si les produits sont utilisés en dehors des conditions spécifiées dans les manuels, par exemple, la plage de température, la pression et l’humidité.
  32. \n
\n \n\n

Batteries et chargeurs

\n\n

Les produits SmartResQ/CorPatch® contiennent soit des piles non remplaçables (CorPatch®) soit des piles rechargeables (CorPatch® Trainer). Les types de batteries utilisées dans nos produits sont décrits sous chaque produit individuel. SmartResQ/CorPatch® décline toute responsabilité si les batteries rechargeables ne sont pas manipulées correctement et conformément au manuel d’utilisation.

\n\n \n\n

Dans le cadre de la vente d’appareils contenant des batteries, nous sommes dans l’obligation de porter à votre attention ce qui suit : \n
\nEn tant qu’utilisateur final, vous êtes légalement tenu de les éliminer correctement. Le symbole de la poubelle barrée signifie que la batterie ne doit pas être jetée avec les ordures ménagères.

\n\n
\n\n\n
\n

Commande

\n\n

La boutique en ligne Corpatch.com est ouverte 24h/24 et vous pouvez passer commande presque à tout moment. Cependant, nous pouvons fermer la boutique pour maintenance. L’achat en grand volume est possible directement avec SmartResQ/CorPatch®.

\n\n \n\n

SmartResQ/CorPatch® ne propose pas de produits à la vente aux mineurs. Les produits destinés aux enfants ne peuvent être achetés que par des adultes. Pour acheter chez SmartResQ/CorPatch®, vous devez avoir au moins 18 ans et posséder une carte de crédit valide ou un autre moyen de paiement que nous acceptons.

\n\n \n\n

La présentation des produits dans la boutique en ligne n’est pas une offre juridiquement contraignante, mais un catalogue en ligne non contraignant. Lorsque vous désirez passez votre commande, sélectionnez les articles que vous souhaitez acheter et placez-les dans le « panier ». Vous pouvez modifier le contenu du panier jusqu’au moment de la commande. Tous les paiements supplémentaires tels que l’expédition ou les frais de carte de débit seront calculés immédiatement avant le paiement.

\n\n \n\n

Lorsque vous désirez passer votre commande, cliquez sur « Commander » et saisissez les informations pertinentes. Vous pouvez modifier le contenu du panier jusqu’à ce que vous confirmiez votre achat en cliquant sur le bouton « Payer ». Passé ce stade, vous passez une commande ferme pour les marchandises contenues dans le panier, et votre commande ne peut plus être modifiée. \n
\nSmartResQ/CorPatch® peut accepter la commande en envoyant une confirmation de commande par e-mail ou en livrant la marchandise dans le délai de livraison.

\n\n \n\n

Certains pays peuvent empêcher l’utilisation et la détention de nos produits. Il est de votre seule responsabilité de savoir s’il est légal d’importer et/ou d’utiliser ce produit dans votre pays. Nous vous enverrons les produits que vous commandez et déclinons toute responsabilité vis-à-vis des problèmes de douane ou des conséquences éventuelles de votre détention ou utilisation de cet appareil.

\n\n
\n\n\n
\n

Paiement

\n\n

Notre ou nos site(s) Web, application(s) et boutique(s) en ligne

\n\n

Nos sites Web et nos applications sont libres d’utilisation tant que nos politiques légales sont acceptées et respectées. Sachez que les achats de nos produits peuvent être disponibles dans la ou les boutique(s) en ligne sur notre ou nos site(s) Web et dans la ou les application(s).

\n\n \n\n

Nos produits

\n\n

SmartResQ/CorPatch® utilise QuickPay comme passerelle de paiement. QuickPay est certifié par le Conseil des normes de sécurité de l’industrie des cartes de paiement (PCI) conformément à la dernière version de la norme de sécurité des données PCI (DSS) niveau 1, qui comprend ; (a) un rapport annuel - « Rapport sur la conformité » (ROC) réalisé par un évaluateur de sécurité qualifié (QSA) ; (b) des analyses trimestrielles du réseau effectuées par le fournisseur d’analyse approuvé (ASV) ; et (c) un grand nombre de règles et de lignes directrices pour le flux de travail et le traitement des données.

\n\n \n\n

Nous acceptons les paiements par :

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • Mastercard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n \n\n

Les paiements seront déduits de votre compte lors de l’expédition des marchandises. Tous les montants sont en euros et la taxe sur la valeur ajoutée légale est déjà incluse dans tous les prix mentionnés. Tous les titulaires de cartes de crédit/débit sont soumis à des contrôles de validation et à autorisation par l’émetteur de la carte ou du prestataire de paiement. SmartResQ/CorPatch® décline toute responsabilité dans le cas où votre fournisseur de carte de paiement refuserait d’autoriser les paiements.

\n \n

Nous utilisons le cryptage des informations de carte de crédit via le protocole Secure Socket Layer (SSL). Cela garantit que personne ne peut intercepter le numéro de carte de crédit ou d’autres informations lors de la transaction avec notre fournisseur.

\n\n \n\n

Avant de conclure le contrat, le client doit examiner et accepter les frais d’expédition et de logistique ajoutés au prix d’achat, car ces frais sont facturés au client. Après avoir passé commande, vous recevrez un e-mail de notre part accusant réception de votre commande. Veuillez noter que cela ne signifie pas que votre commande a été acceptée. Votre commande constitue une offre à SmartResQ/CorPatch® d’acheter un produit (et SmartResQ/CorPatch® se réserve le droit de refuser des commandes de produits). Aucun contrat n’existera en relation avec les produits jusqu’à ce que nous vous ayons confirmé par e-mail que le ou les produits ont été expédiés. Notre acceptation de votre offre sera réputée complète et le contrat entre nous sera formé lorsque nous vous enverrons un courrier de confirmation d’expédition.

\n\n \n\n

Les frais d’expédition sont toujours indiqués par rapport à chaque commande individuelle.

\n\n \n\n

SmartResQ/CorPatch® conserve la propriété de l’article acheté jusqu’à ce que le montant de la facture ait été entièrement payé par le client et automatiquement « prélevé » juste avant l’expédition.

\n\n \n\n

Les clients n’ont droit à une compensation que si leurs demandes reconventionnelles ont été légalement établies ou sont incontestées ou reconnues par SmartResQ/CorPatch®. En outre, les clients ne disposent d’un droit de rétention que si et dans la mesure où leur demande reconventionnelle est basée sur la même relation contractuelle.

\n\n \n\n

Si le client tarde à honorer ses obligations de paiement envers nous, toutes les créances existantes deviennent exigibles immédiatement.

\n\n \n\n

Frais de majoration

\n\n

Depuis le 1er janvier 2018, les règles concernant la surcharge ont été modifiées. Par conséquent, il n’est plus légal de majorer les frais sur les paiements effectués par carte bancaire si celle-ci est émise par des banques/émetteurs de cartes au sein de l’UE. Cela s’applique aux cartes de débit et de crédit. Les cartes individuelles sont des cartes délivrées à un consommateur privé. \n
\nToutefois, s’il s’agit d’une carte d’entreprise ou d’une carte individuelle émise en dehors de l’UE, les frais de transaction seront majorés. Cela signifie que le titulaire de la carte paie automatiquement les frais de transaction. \n
\nLes frais ne seront pas supérieurs à ce que SmartResQ/CorPatch® est facturé par l’acquéreur. Les frais seront clairement affichés comme un poste distinct dans la fenêtre de paiement.

\n\n
\n\n\n
\n

Livraison

\n\n

Nous nous efforçons d’expédier les commandes d’un jour ouvrable à l’autre et utilisons une agence d’expédition de confiance internationale. Vous trouverez le prix total de votre achat, livraison comprise, sur la page de paiement et avant d’accepter votre commande finale.

\n\n \n\n

Si le client n’accepte pas la marchandise, SmartResQ/CorPatch® peut résilier le contrat ou recevoir une indemnité pour inexécution après un délai de deux semaines pour couvrir les frais de traitement et d’expédition.

\n\n \n\n

Si le client a fourni des informations incorrectes sur l’adresse de livraison, il est possible de récupérer le colis dans le magasin indiqué dans notre boutique en ligne, sinon le colis sera perdu.

\n\n \n\n

Le client ne recevra jamais de livraisons partielles sauf indication explicite de SmartResQ/CorPatch®.

\n\n \n\n

Risque de perte

\n\n

La propriété des risques du produit est transférée à l’acheteur lorsque le produit est mis à la disposition de l’acheteur conformément à cet accord. Si le délai de livraison est passé et que l’acheteur ne reçoit pas un produit mis à sa disposition ou mis à sa disposition conformément à l’accord, l’acheteur assume le risque de perte ou de dommage causé par les caractéristiques du produit lui-même.

\n\n
\n\n\n
\n

Annulation et retours

\n\n

Lorsque vous passez commande chez SmartResQ/CorPatch® en ligne ou hors ligne, vous avez 14 jours pour changer d’avis et annuler votre commande, pendant lesquels vous pouvez nous informer que vous avez changé d’avis et nous renvoyer l’article dans le même état que celui dans lequel il a été reçu. \n
\nNous n’acceptons que les retours d’articles inutilisés dans leur emballage d’origine, scellé et intact et ils doivent être correctement emballés pour l’expédition, sinon les produits seront considérés comme utilisés et aucun remboursement partiel ne s’appliquera. Le droit de rétractation ne s’applique qu’aux produits déscellés à la réception.

\n\n \n\n

Raisons acceptables pour renvoyer un produit

\n
    \n
  • Utilisation du droit de rétractation de 14 jours
  • \n\n
  • Produit non conforme à la description (garantie)
  • \n\n
  • Le produit est défectueux
  • \n
\n \n\n

Les conditions de retour de CorPatch® suivent les règles standard de l’UE.

\n\n \n\n \n\n

Si vous renvoyez le produit, conservez l’emballage d’origine et ne l’endommagez pas, ne collez et/ou n’écrivez rien dessus. Procurez-vous et utilisez un emballage de retour dédié, par exemple une boîte en carton.

\n\n \n\n

Pour CorPatch® Trainer, les conditions de rétractation pour ce produit obéissent aux règles standard de l’UE.

\n\n \n\n

Pour exercer le droit de rétractation, vous devez nous en informer dans les 14 jours suivant la réception des articles. Les demandes d’annulation doivent être envoyées par e-mail à info@corpatch.com, en indiquant clairement que vous souhaitez utiliser vos droits de rétractation et pourquoi.

\n\n \n\n

Veuillez renvoyer les articles dès que possible après l’avis d’annulation et au plus tard 14 jours après que vous nous en ayez informés par e-mail.

\n\n \n\n

Nous pouvons refuser le remboursement jusqu’à ce que vous ayez renvoyé les articles ou prouvé que vous avez renvoyé les articles. Pour ce remboursement, nous utiliserons le même mode de paiement que celui utilisé lors de la transaction d’origine.

\n\n \n\n

Raisons non acceptables pour renvoyer un produit

\n
    \n
  • Changement d’avis après le droit de rétractation de 14 jours
  • \n\n
  • Si le produit a été activé
  • \n\n
  • Si le produit est utilisé ou endommagé de toute autre manière
  • \n\n
  • Si le logiciel/l’application gratuite est téléchargé, connecté, installé ou associé de toute autre manière au(x) produit(s) physique(s).
  • \n
\n \n\n

Comment renvoyer un produit

\n\n

Nous n’acceptons que les retours d’articles non ouverts dans leur emballage d’origine intact et ils doivent être correctement emballés pour l’expédition, sinon les produits seront considérés comme utilisés et aucun remboursement ne s’appliquera.

\n\n \n\n

Sauf indication contraire, les retours doivent être envoyés à :\n
\nSmartResQ ApS (CorPatch®) \n
\nLundevej 26 \n
\nDK-5700 Svendborg (Suède) \n
\nDanemark

\n\n

IMPORTANT ! Vous assumez la seule responsabilité pour la qualité de l’emballage et des articles jusqu’à leur réception par nous. Veuillez conserver le reçu postal comprenant les informations sur les frais d’expédition et, le cas échéant, le numéro de suivi et de traçabilité. Nous ne couvrons pas les frais d’expédition de retour et nous n’acceptons pas les colis envoyés contre remboursement (COD) ou similaire.

\n\n
\n\n\n
\n

Remboursements

\n\n

SmartResQ/CorPatch® est obligé de réparer, remplacer ou accorder une réduction de prix ou un remboursement complet si l’article s’avère défectueux dans les 2 ans suivant l’achat de l’article. \n
\nLe client n’a pas droit à un remboursement si le problème est mineur, comme des rayures sur l’article ou similaire. \n
\nUne fois que SmartResQ/CorPatch® reçoit l’article du client, un remboursement est initié. La valeur du montant du remboursement dépend de l’état des produits lorsqu’ils sont reçus chez SmartResQ/CorPatch®.

\n\n \n\n

La manière dont le remboursement du client est traité dépend du mode de paiement d’origine. Si le client a payé par carte de crédit ou de débit, les remboursements seront envoyés à la banque émettrice de la carte dans les 5 jours ouvrables suivant la réception de l’article renvoyé ou de la demande d’annulation. Veuillez contacter la banque émettrice de la carte si vous avez des questions sur le moment où le crédit sera crédité sur votre compte.

\n\n
\n\n\n
\n

Traitement des données personnelles

\n\n

Chez SmartResQ/CorPatch®, nous accordons une grande importance à la protection de vos données personnelles grâce à notre effort de conformité des données en trois étapes : a. en conservant une cartographie détaillée de nos flux de données ; b. en entreprenant une évaluation juridique basée sur le flux de données afin de : c. mettre en œuvre les mesures de sécurité nécessaires pour assurer la sécurité de vos données.

\n\n \n\n

Pour utiliser notre boutique en ligne, vous devez au moins fournir les informations suivantes :

\n
    \n
  • Nom
  • \n\n
  • Adresse
  • \n\n
  • Adresse e-mail
  • \n\n
  • Numéro de téléphone
  • \n
\n \n\n

La collecte d’informations personnelles sur les clients s’effectue dans le cadre de la législation en vigueur et de la législation européenne relative au règlement général sur la protection des données (RGPD).

\n\n \n\n

Si vous souhaitez en savoir plus sur le traitement de vos données personnelles par nos soins, veuillez lire notre politique de confidentialité. \n\n

\n\n\n
\n

Réclamations

\n\n

Comment nous adresser une réclamation

\n\n

En cas de problème avec le produit, vous pouvez soit faire réparer ou remplacer un produit défectueux, soit recevoir un remboursement ou une réduction de prix, selon la situation spécifique. \n
\nBien sûr, il est nécessaire que la réclamation soit justifiée et que le défaut ne soit pas causé par une utilisation incorrecte du produit ou un autre comportement incorrect.

\n\n \n\n

Nous vous recommandons de formuler votre réclamation le plus tôt possible et dans la semaine suivant la découverte du défaut.\n
\nN’hésitez pas à nous contacter pour toute question, commentaire ou réclamation en nous envoyant un e-mail à : info@corpatch.com

\n\n

Réclamation auprès d’autres entités au sein de l’UE

\n\n

Veuillez visiter le site officiel de l’Union européenne pour porter plainte auprès d’autres entités au sein de l’UE. Trouvez des informations ici.

\n\n
\n\n\n
\n\n

Modifications apportées à ce document

\n\n

Sur le(s) site(s) Web, application(s) et politiques

\n\n

SmartResQ/CorPatch® se réserve le droit d’apporter des changements, de supprimer, de modifier ou de compléter ses sites Web, applications, politiques et documents à tout moment pour quelque raison que ce soit, sans préavis à quiconque. \n
\nSi l’une de ces conditions est jugée invalide, nulle ou inapplicable pour quelque raison que ce soit, cette condition sera réputée nulle et non avenue et n’affectera pas la validité et l’applicabilité de toute condition restante.

\n\n \n\n

Si nous modifions nos politiques, nous publierons les politiques révisées en ligne avec une date de révision mise à jour. Nous vous encourageons à consulter régulièrement les politiques. Si nous apportons des modifications importantes à nos politiques qui modifient considérablement nos pratiques en la matière, nous pouvons également vous en informer par d’autres moyens, par exemple, en envoyant un e-mail ou en publiant un avis sur notre site Web et/ou sur les réseaux sociaux avant que les modifications ne prennent effet.

\n\n \n\n

En relation avec un achat spécifique

\n\n

Lors de l’achat d’un produit, il vous sera demandé d’accepter une version de certains documents tels qu’ils sont à ce moment précis - cette version ne sera pas modifiée après ce moment et dictera les termes de notre relation avec vous concernant l’achat en question.

\n\n
\n\n\n
\n

Droit et juridiction

\n\n

Les lois du Danemark et le tribunal de district de Svendborg

\n\n \n\n

SmartResQ/CorPatch® privilégie la loi danoise et les tribunaux danois pour tout litige juridique, et non pas la Convention de Vienne sur la vente internationale de marchandises (CVIM). \n
\nTout litige relatif de quelque manière que ce soit à votre visite sur SmartResQ/CorPatch® ou aux produits que vous achetez via SmartResQ/CorPatch® sera soumis à la confidentialité au Danemark, hormis le fait que, dans la mesure où vous avez violé ou menacé de violer les droits de propriété intellectuelle de SmartResQ/CorPatch®, SmartResQ/CorPatch® peut demander une injonction ou toute autre mesure appropriée dans n’importe quel pays. Vous consentez à la compétence et au lieu exclusifs de ces tribunaux.

\n\n \n\n

Si l’accord sur les « Conditions générales » est violé, des poursuites judiciaires seront engagées et une action en justice pourra être intentée devant un tribunal.

\n\n \n\n

Les litiges entre nous-même et tout consommateur sont soumis au tribunal de district de Svendborg, Christiansvej 41, 5700 Svendborg, Danemark.

\n\n
\n\n\n
\n

Coordonnées de contact

\n\n

Merci d’avoir lu les « Conditions générales » de SmartResQ/CorPatch®.\n
\nSi vous avez des questions, des commentaires ou des réclamations, n’hésitez pas à nous contacter.

\n\n \n\n

Notre société est située à l’adresse : Lundevej 26, 5700 Svendborg, Danemark

\n\n \n\n

Vous pouvez nous trouver au registre central des entreprises sous le numéro de TVA DK 38674102

\n\n \n\n

Vous pouvez nous téléphoner au Numéro de téléphone +45 62 200 100

\n\n \n\n

ou

\n\n \n\n

envoyez-nous un e-mail à : info@corpatch.com

\n\n \n\n

© SmartResQ ApS – Tous droits réservés \n
\nDanemark, Version 2.1 – Publication le 25.04.2023

\n\n
\n \n \n \n\n\n\n \n \n\n
\n

Politique de confidentialité SmartResQ / CorPatch®

\n\n

Nous traitons vos données conformément au RGPD

\n\n

SmartResQ/CorPatch® respecte votre vie privée. Cette déclaration de confidentialité décrit vos droits en matière de confidentialité et notre engagement à sécuriser vos informations personnelles.

\n\n

Si vous avez des questions sur le traitement de vos données personnelles, veuillez nous contacter. Le responsable du traitement est :

\n\n

Société : SmartResQ ApS (CorPatch®)

\n\n

Adresse : \n
\nLundevej 26 \n
\n5700 Svendborg (Suède) \n
\nDanemark

\n\n

N° CVR : 38674102

\n\n

N° de téléphone : +45 62 200 100

\n\n

E-mail : info@corpatch.com

\n\n

SmartResQ/CorPatch® est une société danoise/européenne avec des entités juridiques, des processus commerciaux, des structures de gestion et des systèmes techniques qui dépassent les frontières nationales. SmartResQ/CorPatch® fournit des produits, des logiciels et des services aux entreprises publiques/privées en Europe.

\n\n

Le siège social est situé au Danemark et SmartResQ/CorPatch® est soumis à la législation européenne sur la protection des données, y compris le Règlement général sur la protection des données (RGPD). Toutes les décisions importantes de SmartResQ/CorPatch® concernant la protection des données personnelles sont prises au niveau de la direction sous la supervision du délégué à la protection des données.

\n\n

Cette déclaration de confidentialité est disponible sur nos sites Web et dans nos applications.

\n\n

Veuillez ne pas utiliser les pages SmartResQ/CorPatch®, les applications ou nos services si vous n’acceptez pas la manière dont nous traitons les données personnelles dans le cadre de cette déclaration de confidentialité.

\n\n
\n\n\n
\n

Le type d’informations personnelles que nous recueillons

\n\n

Lorsqu’un gestionnaire détermine les finalités et les moyens du traitement de vos données personnelles, il agit en tant que responsable du traitement. Cela inclut les scénarios où SmartResQ/CorPatch® collecte des données personnelles dans le contexte où vous êtes un demandeur d’emploi, un représentant d’un client ou un prospect, ou lorsque vous êtes un utilisateur de logiciel.

\n\n

SmartResQ traite les informations personnelles à diverses fins, en fonction de la relation que nous entretenons avec vous.

\n\n

Nous pouvons traiter les données suivantes :

\n
    \n
  1. Données de base, telles que nom, adresse, numéro de téléphone (portable et/ou fixe) et e-mail
  2. \n\n
  3. Données professionnelles telles que l’employeur, le titre, le poste, y compris les préférences et les intérêts dans un contexte professionnel
  4. \n\n
  5. Feedback, commentaires ou questions sur SmartResQ/CorPatch® ou nos produits et services
  6. \n\n
  7. Photos ou vidéos enregistrées sur nos sites
  8. \n\n
  9. Contenu que vous avez téléchargé, tel que des photos, des vidéos et des performances au fil du temps
  10. \n\n
  11. Informations utilisateur uniques telles que l’identifiant de connexion, le nom d’utilisateur, le mot de passe et la question de sécurité
  12. \n\n
  13. Informations financières, lorsque vous acceptez que nous utilisions vos informations, par exemple pour conserver les détails de votre carte de paiement
  14. \n\n
  15. Informations sur le trafic fournies par votre navigateur Web, telles que le type de navigateur, l’appareil, la langue et l’adresse du site Web d’où vous venez, et d’autres informations sur le trafic, y compris l’adresse IP
  16. \n\n
  17. Comportement en matière de flux de clics et d’activité sur les identifiants de SmartResQ/CorPatch® et dans nos produits et services
  18. \n\n
  19. Comportement en matière d’e-mails, tels que les e-mails de SmartResQ/CorPatch® que vous ouvrez, quand et comment
  20. \n\n
  21. Autres informations personnelles contenues dans votre profil que vous avez librement placées sur des réseaux sociaux tiers, tels que LinkedIn, Facebook, Google, etc.
  22. \n\n
  23. Informations utilisées à des fins scientifiques pour améliorer la survie après un arrêt cardiaque, collectées via nos sites Web et nos applications
  24. \n\n
  25. Informations sur les utilisateurs pour fournir des produits conformes aux exigences de qualité et de sécurité, pour fournir des services aux utilisateurs et pour maintenir et améliorer nos offres
  26. \n\n
  27. Informations sur les candidats pour gérer les candidatures, communiquer sur les offres d’emploi futures et maintenir et améliorer nos processus de recrutement
  28. \n\n
  29. Informations sur les personnes qui se sont inscrites pour recevoir des newsletters et d’autres supports afin de fournir les supports et de maintenir et d’améliorer nos offres
  30. \n\n
  31. Informations sur les cookies pour fournir des publicités personnalisées sur les réseaux sociaux et les sites Web.
  32. \n
\n
\n\n\n
\n

Données collectées et traitées dans la plateforme et les applications CorPatch® Services

\n\n

SmartResQ gère, collecte et conserve les données personnelles suivantes lorsque vous utilisez la plate-forme ou les applications CorPatch® Services.

\n\n

Tous les utilisateurs (Institute Admin, Trainer, Trainee/utilisateur final)

\n
    \n
  • Prénom (si renseigné)
  • \n\n
  • Nom (si renseigné)
  • \n\n
  • Surnom (si renseigné)
  • \n\n
  • Adresse e-mail (obligatoire)
  • \n\n
  • Langue de communication préférée (obligatoire)
  • \n\n
  • Cryptage du mot de passe (obligatoire)
  • \n\n
  • Si l’adresse e-mail a été validée (obligatoire)
  • \n
\n \n\n

En plus pour les trainees/utilisateurs finaux (obligatoire)

\n\n

Données sur le téléphone portable utilisé :

\n\n

Système d’exploitation (Android/iOS) :

\n
    \n
  • Version du système d’exploitation (par exemple 9)
  • \n\n
  • Fabricant (par exemple Samsung)
  • \n\n
  • Modèle (par exemple SM-T518)
  • \n\n
  • Version de l’application (par exemple 1.2.4)
  • \n\n
  • Heure de la dernière activité de premier plan de l’application
  • \n\n
  • Heure de la dernière activité d’arrière-plan de l’application
  • \n
\n \n\n

Données sur le CorPatch® (CPS) utilisé :

\n
    \n
  • Numéro de série / adresse MAC
  • \n\n
  • Version de firmware
  • \n\n
  • Nom de modèle (par exemple CPS_01)
  • \n\n
  • Fabricant (actuellement toujours SRQ)
  • \n\n
  • Nom (actuellement toujours CorPatch®)
  • \n\n
  • État de la batterie
  • \n\n
  • Défauts
  • \n
\n \n\n

Données d’intégration des utilisateurs :

\n
    \n
  • Tutorial terminé (oui/non)
  • \n\n
  • Conditions d’utilisation acceptées (oui/non)
  • \n\n
  • Auto-évaluation effectuée (oui/non)
  • \n\n
  • Test d’entraînement effectué (oui/non)
  • \n\n
  • Première connexion réussie (oui/non)
  • \n\n
  • Un CPS était-il connecté (oui/non)
  • \n
\n \n\n

Données recueillies durant l’entraînement :

\n
    \n
  • Date, heure et durée de l’entraînement
  • \n\n
  • Résultat de l’entraînement
  • \n\n
  • Type d’entraînement ou paramètres du mode Training
  • \n\n
  • En cas d’entraînement au sein d’un institut, des informations complémentaires sur le cours, le trainer (formateur) et l’institut
  • \n
\n \n \n\n

Journaux du serveur

\n\n

Les données suivantes sont conservées dans les journaux du serveur Web :

\n
    \n
  • Adresse IP de la partie accédante
  • \n\n
  • Version du navigateur de la partie accédante
  • \n\n
  • Date/heure d’accès
  • \n\n
  • URL d’accès
  • \n
\n

Services externes qui traitent des données :

\n
    \n
  • Google/Firebase pour l’analyse à distance des connexions, des plantages et des erreurs
  • \n\n
  • Google/Firebase pour l’envoi de notifications
  • \n\n
  • Sendgrid pour l’envoi d’e-mails
  • \n\n
  • Hetzner Online GmbH pour l’hébergement du backend Web et de la base de données
  • \n
\n \n\n

Que se passe-t-il lorsqu’un utilisateur est supprimé ?

\n
    \n
  • L’utilisateur se supprime de notre système sur la page d’accueil des services CorPatch® https://app.corpatch.com \n\n
  • L’utilisateur est marqué comme supprimé. Dès lors, il ne peut plus se connecter, n’est plus visible pour les administrateurs, etc. mais l’utilisateur existe toujours dans la base de données. \n\n
  • Après 14 jours, les données de l’utilisateur sont automatiquement supprimées de la base de données. \n\n
  • Aux fins d’évaluation scientifique et d’amélioration des fonctionnalités, les données d’entraînement et d’utilisation de CorPatch® existeront toujours dans la base de données après la suppression de l’utilisateur, mais la référence (l’ID) à l’utilisateur sera vide, et toutes les références aux données personnelles seront supprimées. \n
\n\n
\n\n\n
\n\n

Comment nous recueillons vos informations personnelles

\n\n

La plupart des informations personnelles que nous traitons nous sont fournies directement par vos soins. Nous collectons et traitons des données lorsque :

\n
    \n
  • Vous vous inscrivez en ligne ou passez une commande pour l’un de nos produits ou services ; par exemple, données démographiques, adresse e-mail, informations de paiement, articles, montant de la commande, niveau et fréquence de ristourne. Ceci comprend l’envoi d’e-mails transactionnels, par exemple confirmation de commande, confirmation d’expédition et confirmation de remboursement.
  • \n\n
  • Vous réagissez aux communications envoyées (e-mail, SMS, publipostage ou téléphone) ; par exemple le taux d’ouverture, le taux de clics et le temps passé à lire les e-mails, le domaine de l’expéditeur et le type de client de messagerie.
  • \n\n
  • Vous répondez volontairement à un sondage auprès des clients ou fournissez des commentaires sur l’un de nos forums de discussion ou par e-mail.
  • \n
\n \n\n

Nous pouvons également recevoir des informations personnelles indirectement, à partir des sources suivantes dans les scénarios suivants :

\n
    \n
  • À partir des cookies : lorsque vous visitez nos sites Web ou nos applications ; par exemple l’adresse IP, le pays, les pages consultées, les produits consultés, les interactions/clics et les recherches.
  • \n\n
  • De vous-même ou de toute autre personne affiliée à notre client. Ces personnes peuvent être un supérieur hiérarchique ou un collègue. Si le client pour lequel vous travaillez achète des produits ou des services auprès de SmartResQ/CorPatch® par l’intermédiaire d’une société partenaire de SmartResQ/CorPatch®, nous pouvons recueillir des informations vous concernant auprès de la société partenaire.
  • \n\n
  • Partenaires marketing de SmartResQ/CorPatch®, sources publiques ou réseaux sociaux de tiers.
  • \n\n
  • SmartResQ/CorPatch® pourra combiner des données personnelles vous concernant recueillies auprès d’une source avec des informations obtenues d’une autre source. Cela nous donne une image plus complète de vous, ce qui nous permet également de vous servir de manière plus pertinente avec un niveau de personnalisation plus élevé.
  • \n
\n\n
\n\n\n
\n

Comment nous utilisons vos données

\n\n

Afin de gérer de manière générale ses relations avec ses clients et de respecter ses engagements envers ses clients, SmartResQ/CorPatch® a besoin d’informations les concernant dans leur rôle de client ou lorsqu’ils utilisent un service. Les finalités du traitement de ces données personnelles sont les suivantes :

\n\n

Traiter votre commande, gérer votre compte

\n
    \n
  • Vous envoyer un e-mail avec des offres spéciales sur d’autres produits et services que nous pensons susceptibles de vous plaire
  • \n\n
  • Réaliser le processus de vente et de contrat pour les clients
  • \n\n
  • Fournir les produits et services demandés aux clients
  • \n\n
  • Effectuer des livraisons conformément aux accords conclus avec vous ou vos clients
  • \n\n
  • Offrir un support technique aux utilisateurs de nos produits et services
  • \n\n
  • Améliorer et développer la qualité, la fonctionnalité et l’expérience utilisateur de nos produits, services et sites Web et applications SmartResQ/CorPatch®
  • \n\n
  • Détecter, limiter et prévenir les menaces de sécurité et effectuer l’entretien, le dépannage et le débogage
  • \n\n
  • Empêcher l’utilisation abusive de nos produits et services
  • \n\n
  • Traiter les commandes, la facturation, les paiements ou tout autre suivi financier
  • \n\n
  • Créer des profils d’intérêt pour promouvoir des produits et services pertinents
  • \n\n
  • Établir des communautés d’utilisateurs pour éduquer et faciliter l’interaction entre les utilisateurs et SmartResQ/CorPatch®.
  • \n
\n \n\n

À propos des prospects

\n\n

SmartResQ/CorPatch® traite les données personnelles des prospects à des fins de marketing. Afin de fournir un contenu ciblé et pertinent aux clients potentiels, SmartResQ/CorPatch® construit un profil d’intérêt basé sur votre activité et vos choix et actions sur les pages SmartResQ/CorPatch®, ainsi que votre réponse au contenu marketing. La base juridique d’un tel traitement est principalement votre consentement.

\n\n

À propos des demandeurs d’emploi

\n\n

Si vous avez posé votre candidature à un emploi, nous traitons vos données personnelles pour évaluer votre potentiel professionnel chez SmartResQ/CorPatch®. Notre plateforme de carrière en ligne sécurisée garantit que nous nous conformons aux dernières lois et réglementations en matière de confidentialité des données. La base juridique d’un tel traitement est votre consentement.

\n\n

À propos des visiteurs du site Web

\n\n

Afin de contrôler l’accès à nos sites, nous traitons des informations personnelles sur les visiteurs. Le traitement est basé sur notre intérêt légitime à protéger nos secrets commerciaux, nos employés, nos sites et vous-même lorsque vous visitez notre site. Nous vous informerons de vos droits dans ce contexte lors de votre inscription à notre système électronique pour les visiteurs.

\n\n

Pour améliorer la qualité de la RCR, notamment moyennant un entraînement à la RCR, SmartResQ/CorPatch® peut partager vos données avec nos sociétés partenaires (Training Institutes) afin qu’elles puissent vous proposer leurs produits et services.

\n\n

Lorsque nous traitons votre commande, notre système peut envoyer vos données à des agences de référence de crédit et également utiliser les informations qui en résultent pour empêcher les achats frauduleux.

\n\n
\n\n\n
\n

Comment nous conservons vos informations personnelles

\n\n

SmartResQ/CorPatch® prend très au sérieux la confiance que vous et nos clients nous accordez. SmartResQ/CorPatch® s’engage à éviter l’accès non autorisé, la divulgation ou tout autre traitement aberrant des données personnelles. SmartResQ/CorPatch® doit garantir la confidentialité des données personnelles traitées par la société, maintenir l’intégrité des données personnelles et assurer leur accessibilité conformément aux lois en vigueur en matière de confidentialité.

\n\n

Dans le cadre de nos engagements, nous appliquons des procédures et des mesures organisationnelles, techniques et physiques raisonnables et adéquates pour protéger les informations que nous recueillons et traitons. Nous prenons en compte le type de données personnelles et le risque auquel nos clients sont exposés par toute faille de sécurité, car il y a une forte probabilité que les causes profondes des violations de données personnelles puissent être trouvées en interne, nous pensons que la construction d’une forte culture d’entreprise dans laquelle le respect et la vigilance de nos collaborateurs sur la protection des données est fondamentale pour assurer le traitement légal et la protection de vos informations. En cas de violation de données, SmartResQ/CorPatch® suivra les pratiques établies par le Datatilsynet danois.

\n\n

Vos informations sont conservées en toute sécurité conformément aux dispositions du RGPD.

\n\n
\n\n\n
\n

Combien de temps conservons-nous vos données personnelles ?

\n\n

SmartResQ/CorPatch® ne conserve vos données personnelles que le temps nécessaire aux fins énoncées, tout en tenant compte de son besoin de répondre aux questions et de résoudre les problèmes, et de se conformer aux exigences légales en vertu de la loi en vigueur.

\n\n

Cela signifie que SmartResQ/CorPatch® peut conserver vos informations personnelles pendant une période raisonnable après votre dernière interaction et la dernière interaction de client avec nous. Lorsque les données personnelles que nous avons collectées ne sont plus nécessaires, nous les supprimons. Nous pouvons traiter des données à des fins statistiques et/ou scientifiques, mais dans de tels cas, les données seront pseudonymisées ou anonymisées.

\n\n \n \n\n

Délai de conservation des données

\n\n

Nous conserverons vos informations personnelles pendant la période nécessaire pour remplir les objectifs décrits dans la présente Politique de confidentialité, sauf si une période de conservation plus longue est requise ou autorisée par la loi, pour des raisons légales, fiscales ou réglementaires, ou à d’autres fins commerciales légitimes et légales.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Objectif Délai
Service client et réglementation comptable 5 ans ou aussi longtemps que nécessaire pour répondre aux exigences légales.\n
\n \nNous supprimons vos données d’inscription dès que vous supprimez votre compte utilisateur chez nous ou à l’expiration de la période de conservation légale. \n
Plateforme des carrières 6 mois pour les dossiers de candidature qui n’aboutissent pas à l’embauche du demandeur d’emploi. \n
\n\nRenouvellement tous les 6 mois si vous souhaitez que votre dossier soit pris en compte pour de futures offres d’emploi et que vous consentez à une période de conservation plus longue. \n
Utilisation marketing 3 ans après votre dernière activité, par exemple visite sur nos sites Web, achat ou communication avec nos services. \n
\n \n\nSi vous avez donné votre autorisation pour le marketing (e-mail, SMS, téléphone, etc.) et tant que nous avons votre autorisation pour vous contacter. \n
\n \n\nNous supprimons automatiquement votre adresse e-mail dans la newsletter, une fois que vous supprimez votre compte utilisateur ou si vous vous désabonnez de notre newsletter. \n
Conservation de l’historique des commandes et des obligations d’exécution des commandes 5 ans ou aussi longtemps que nécessaire pour répondre aux exigences légales.
Expérience client 3 ans après votre dernière activité, par exemple visite sur nos sites Web, achat ou communication avec nos services. \n
\n \n\nSi vous avez donné votre autorisation pour le marketing (e-mail, SMS, téléphone, etc.) et tant que nous avons votre autorisation. \n
\n
Fraude et évaluation des risques 5 ans ou aussi longtemps que nécessaire pour répondre aux exigences légales.
\n\n
\n\n\n
\n\n

Communications Marketing

\n\n

Vous avez le droit de refuser de recevoir des communications marketing de SmartResQ/CorPatch® et vous pouvez le faire en :

\n
    \n
  • suivant les instructions de désactivation dans les communications marketing pertinentes ;
  • \n\n
  • modifiant les préférences dans la section d’édition appropriée pour le compte, si vous avez un compte chez SmartResQ/CorPatch® ;
  • \n\n
  • nous contactant par e-mail à info@corpatch.com
  • \n
\n \n\n

Veuillez noter que même si vous refusez de recevoir des communications marketing, vous pouvez toujours recevoir des messages administratifs de SmartResQ/CorPatch®, tels que des confirmations de commande et des avis nécessaires pour gérer votre compte ou les services fournis à nos clients via, par exemple, des services mobiles ou des applications.

\n\n
\n\n\n
\n

Vos droits en matière de protection des données

\n\n

Il est important pour SmartResQ/CorPatch® que vous soyez totalement au fait de tous vos droits en matière de protection des données.

\n\n

Certaines lois sur la protection des données, y compris le règlement général sur la protection des données (RGPD) de l’Union européenne, la législation correspondante en Allemagne Bundesdatenschutzgesetz (BDSG), en Suisse et au Royaume-Uni, et certaines lois des États américains, vous confèrent certains droits en relation avec les données personnelles que vous nous avez communiquées. Si vous résidez dans l’Espace économique européen, vous pouvez exercer les droits suivants :

\n
    \n
  1. Votre droit d’accès – Vous avez le droit de nous demander des copies de vos informations personnelles. \n\n
  2. Votre droit de rectification – Vous avez le droit de nous demander de corriger toute information personnelle que vous jugeriez inexacte. Vous avez également le droit de nous demander de compléter les informations que vous jugez incomplètes. \n\n
  3. Votre droit à l’effacement – Vous avez le droit de nous demander d’effacer vos informations personnelles sous certaines conditions. \n\n
  4. Votre droit à un traitement restreint – Vous avez le droit de nous demander de restreindre le traitement de vos informations personnelles sous certaines conditions. \n\n
  5. Votre droit de vous opposer au traitement – Vous avez le droit de vous opposer au traitement de vos informations personnelles sous certaines conditions. \n\n
  6. Votre droit à la portabilité des données – Vous avez le droit de demander que nous transférions les informations personnelles que nous avons recueillies à une autre organisation, ou directement à vous-même sous certaines conditions. \n
\n \n\n

Si vous souhaitez exercer l’un de ces droits, veuillez nous contacter à notre adresse e-mail : info@corpatch.com

\n\n
\n\n\n
\n

Que sont les cookies ?

\n\n

Les cookies sont de petits fichiers texte qui contiennent une chaîne de caractères et créent un identifiant unique pour chaque utilisateur. Ils sont renvoyés au site Web et/ou à des tiers. La plupart des navigateurs sont initialement configurés pour accepter les cookies, car la plupart des sites Web sont tenus d’y accéder. Cependant, vous pouvez modifier les paramètres de votre navigateur afin que votre navigateur puisse généralement rejeter les cookies, bloquer les cookies tiers ou spécifier quand un cookie est envoyé.

\n \n \n\n

SmartResQ/CorPatch® s’engage à garantir votre droit d’ajuster vos intérêts et de gérer la portée du marketing numérique de notre part par le biais d’un système de gestion préférentielle.

\n\n
\n\n\n
\n

Comment nous utilisons les cookies

\n\n

SmartResQ/CorPatch® utilise les cookies de différentes manières pour améliorer votre expérience sur ses sites Web, applications et services pour différentes raisons, par exemple :

\n
    \n
  • Fonctionnalité – nous utilisons ces cookies pour vous reconnaître sur notre site Web et mémoriser vos préférences précédemment sélectionnées. Celles-ci incluent la langue que vous préférez et l’endroit où vous vous trouvez. Un mélange de cookies propriétaires et tiers est utilisé.
  • \n\n
  • Publicité – nous utilisons ces cookies pour collecter des informations sur votre visite sur nos sites Web, nos applications, le contenu que vous avez consulté, les liens que vous avez suivis et des informations sur votre navigateur, votre appareil et votre adresse IP. Parfois, nous partageons certains aspects limités de ces données avec des tiers à des fins publicitaires. Nous pouvons également partager des données en ligne collectées via des cookies avec nos partenaires publicitaires. Cela signifie que lorsque vous visitez un autre site Web, des publicités peuvent vous être présentées en fonction de vos habitudes de navigation sur notre site Web.
  • \n
\n
\n\n\n
\n

Le type de cookies que nous utilisons

\n\n

Nos sites Web utilisent les types de cookies suivants :

\n
    \n
  • Google Analytics : Ce cookie nous permet d’afficher des informations sur les activités du site Web pour les utilisateurs, y compris, mais sans s’y limiter, les pages vues, la source et le temps passé sur un site Web. Les informations sont anonymisées et affichées sous forme numérique, ce qui signifie qu’elles ne peuvent pas être attribuées à des individus particuliers. Cela aide à protéger votre vie privée. L’utilisation de Google Analytics nous permet de voir quel contenu est populaire sur nos pages, et de vous proposer autant que possible ce que vous aimez lire et voir. \n\n
  • Remarketing Google Analytics : Place des cookies sur votre ordinateur, ce qui signifie que lorsque vous quittez notre site, Google peut vous montrer des publicités sur SmartResQ/CorPatch® susceptibles de vous intéresser en fonction de votre comportement antérieur sur notre site Web. Ces informations ne sont pas personnellement identifiables. \n\n
  • Google Ads : L’utilisation de Google Ads nous permet de voir quelles pages ont été utiles pour mener à des soumissions via notre formulaire de contact. Ces informations ne sont pas personnellement identifiables, mais les données fournies dans le formulaire de contact le sont. \n\n
  • Remarketing Google Ads : Place des cookies sur votre ordinateur, ce qui signifie que lorsque vous quittez notre site, Google peut vous montrer des publicités sur SmartResQ/CorPatch® susceptibles de vous intéresser en fonction de votre comportement antérieur sur notre site Web. Ces informations ne sont pas personnellement identifiables. \n\n
  • Remarketing Facebook : Le pixel de suivi de Facebook place des cookies sur votre ordinateur qui indiquent à Facebook que vous avez consulté le site. Nous supposons alors que vous avez un intérêt pour SmartResQ/CorPatch® et le contenu de ce site. Lors de vos visites sur Facebook, vous recevrez des informations ou publicités au contenu similaire. Veuillez utiliser vos paramètres de confidentialité sur Facebook pour limiter l’exposition à ce type de marketing. \n\n
  • YouTube : Nous intégrons des vidéos de la plateforme YouTube fournie par Google (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA). Politique de confidentialité : https://www.google.com/policies/privacy/.
  • \n
\n \n
\n\n\n
\n

Comment gérer les cookies

\n\n

Vous pouvez configurer votre navigateur pour qu’il refuse ou supprime les cookies. Cependant, certaines des fonctionnalités de notre site Web risquent de ne pas fonctionner en conséquence. Découvrez comment éviter les cookies dans des navigateurs spécifiques :

\n\n

SmartResQ/CorPatch® utilise certains services tiers de confiance sur ses pages. Ces services peuvent utiliser des cookies. Vous pouvez choisir de refuser les cookies tiers dans votre navigateur en suivant ce lien.

\n\n

Vous pouvez empêcher que les informations générées par le cookie Google concernant votre utilisation de nos sites soient collectées et traitées par Google en téléchargeant et en installant le module complémentaire de navigateur pour la désactivation de Google Analytics pour votre navigateur Web actuel. Ce module complémentaire est disponible ici.

\n\n
\n\n\n
\n

Politiques de confidentialité des autres sites Web

\n\n

Le site Web de SmartResQ/CorPatch® contient des liens vers d’autres sites Web. Notre politique de confidentialité s’applique uniquement à notre site Web, donc si vous cliquez sur un lien vers un autre site Web, vous devriez lire sa politique de confidentialité.

\n\n
\n\n\n
\n

Modifications de notre politique de confidentialité

\n\n

Si nous modifions notre déclaration de confidentialité, nous publierons ici la déclaration révisée avec une date de révision mise à jour. Nous vous encourageons à consulter régulièrement la déclaration. Si nous apportons des modifications importantes à notre déclaration qui modifient considérablement nos pratiques de confidentialité, nous pouvons également vous en informer par d’autres moyens, par exemple, en envoyant un e-mail ou en publiant un avis sur notre site Web et/ou sur les réseaux sociaux avant que les modifications ne prennent effet.

\n\n
\n\n\n
\n

Comment contacter SmartResQ ApS

\n\n

Si vous avez des questions sur la politique de confidentialité de SmartResQ/CorPatch®, les données que nous détenons sur vous, ou si vous souhaitez exercer l’un de vos droits en matière de protection des données, n’hésitez pas à nous contacter.

\n\n

E-mail : info@corpatch.com

\n\n

Site Web : https://corpatch.com

\n\n
\n\n\n
\n\n

Comment contacter l’autorité compétente

\n\n

Si vous souhaitez déposer une plainte ou si vous estimez que SmartResQ/CorPatch® n’a pas répondu à votre problème de manière satisfaisante, vous pouvez contacter le Bureau du Commissaire à l’information (BCI).

\n\n

L’adresse du BCI :\n

\nInformation Commissioner’s Office \n
\nWycliffe House \n
\nWater Lane \n
\nWilmslow \n
\nCheshire \n
\nSK9 5AF

\n\n\n

Numéro d’assistance : +44 303 123 1113

\n\n

Site Web du BCI : https://www.ico.org.uk

\n\n

© SmartResQ ApS – Tous droits réservés \n
\nDanemark, Version 1.3 – Publication 25.04.2023

\n\n
\n
\n\n`\n\nexport const termsOfUse_it_IT: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n
\n\n \n\n\n
\n

Termini e condizioni & Informativa sulla privacy

\n

SmartResQ ApS / CorPatch®

\n \n
\n \n\n
\n\n

Termini e condizioni – SmartResQ ApS / CorPatch®

\n\n

Scopo del documento

\n\n

Benvenuti in SmartResQ/CorPatch®!

\n\n \n\n

State leggendo i nostri Termini e condizioni; un documento contenente informazioni sul vostro rapporto con SmartResQ ApS, iniziato quando siete entrati nel nostro sito web, avete scaricato le nostre applicazioni gratuite, avete acquistato uno dei nostri prodotti o altro.

\n\n \n\n

SmartResQ/CorPatch® e i suoi associati forniscono i propri prodotti e servizi all'utente alle seguenti condizioni. Se visitate o fate acquisti sul nostro sito web o sulla nostra app, accettate queste condizioni. Vi consigliamo vivamente di leggerle attentamente prima di procedere all'utilizzo dei nostri prodotti o servizi.

\n\n \n\n

Questo documento verte su:

\n
    \n
  • Come contattare SmartResQ
  • \n\n
  • Prodotti, proprietà e uso corretto
  • \n\n
  • Esclusioni di responsabilità e garanzie
  • \n\n
  • Ordini
  • \n\n
  • Pagamenti
  • \n\n
  • Consegna
  • \n\n
  • Responsabilità e diritti relativi alla vendita
  • \n\n
  • Resi
  • \n\n
  • Trattamento dei dati personali
  • \n\n
  • Reclami
  • \n\n
  • Modifiche al presente documento
  • \n\n
  • Leggi e giurisdizione
  • \n\n
  • Informazioni di contatto
  • \n
\n \n\n

In caso di domande relative ai \"Termini e condizioni\" di SmartResQ, si prega di contattarci.

\n\n\n

Come contattare SmartResQ

\n\n

L'obiettivo di SmartResQ è quello di far aumentare la sopravvivenza attraverso una RCP di qualità in caso di arresto cardiaco. Vogliamo preparare e guidare gli astanti a intervenire fin dai primi minuti cruciali, dopo aver assistito a un arresto cardiaco. Pertanto, abbiamo sviluppato CorPatch® – Vi aiutiamo a salvare una vita.

\n\n \n\n

La nostra azienda si trova a Lundevej 26, 5700 Svendborg, Danimarca

\n\n \n\n

Ci trovate nel Registro Centrale delle Imprese con il numero di partita IVA DK 38674102

\n\n \n\n

Potete chiamarci al numero di telefono +45 62 200 100

\n\n \n\n

oppure

\n\n \n\n

contattateci all'indirizzo e-mail: info@corpatch.com

\n\n \n\n

Domande, commenti o reclami?

\n\n

Apprezziamo la vostra opinione, quindi vi invitiamo a contattarci attraverso le informazioni di contatto di cui sopra o utilizzando il modulo di contatto sul nostro sito web o sulla nostra app.

\n\n
\n\n\n
\n

Prodotti, proprietà e uso corretto

\n\n

I nostri siti web, app e prodotti

\n\n

I paragrafi seguenti descrivono le proprietà, i diritti e le responsabilità essenziali relative all'uso dei servizi, delle app e dei prodotti SmartResQ/CorPatch®. \n
\nCi sforziamo di includere informazioni accurate e aggiornate nei siti web e nelle applicazioni. Tuttavia, SmartResQ/CorPatch® non fornisce alcuna garanzia o dichiarazione in merito all'accuratezza delle informazioni. Non ci assumiamo alcuna responsabilità per eventuali errori o omissioni nei contenuti del sito web, nei prodotti e nelle applicazioni. Le informazioni fornite in questo sito web o nelle app non sostituiscono un'adeguata assistenza medica. Ci assumiamo la responsabilità dei nostri prodotti e delle nostre applicazioni in base alla direttiva sui dispositivi medici UE 745/2017 (MDR).

\n\n \n\n

Copyright

\n\n

Tutti i contenuti inclusi in questo sito, come testo, grafica, loghi, icone di pulsanti, immagini, clip audio, download digitali, compilazioni di dati e software, sono di proprietà di SmartResQ/CorPatch® o dei suoi fornitori di contenuti e sono protetti dalle leggi internazionali sul copyright. La stesura di tutti i contenuti di questo sito è di esclusiva proprietà di SmartResQ/CorPatch®, il cui copyright è di SmartResQ/CorPatch® ed è protetto dalle leggi internazionali sul copyright.

\n\n \n\n

Marchi registrati e design

\n\np>I marchi SmartResQ/CorPatch®, la veste commerciale e il design del prodotto non possono essere utilizzati in relazione ad alcun prodotto o servizio che non sia SmartResQ/CorPatch®, in alcun modo che possa causare confusione tra i clienti o in qualsiasi modo che denigri o screditi SmartResQ/CorPatch®. Tutti gli altri marchi non di proprietà di SmartResQ/CorPatch® o delle sue consociate che appaiono su questo sito sono di proprietà dei rispettivi titolari, che possono o meno essere affiliati, collegati o sponsorizzati da SmartResQ/CorPatch® o dalle sue consociate. \n\n \n\n

Licenza e accesso al sito

\n\n

SmartResQ/CorPatch® concede all'utente una licenza limitata per l'accesso e l'uso personale dei siti e delle applicazioni di SmartResQ/CorPatch® e non consente di scaricare (ad eccezione della memorizzazione nella cache della pagina) o modificare il sito o parte di esso, salvo espresso consenso scritto di SmartResQ/CorPatch®. Questa licenza non include alcuna rivendita o uso commerciale di questi siti o applicazioni o dei loro contenuti: (a) la raccolta e l'uso di elenchi, descrizioni o prezzi dei prodotti; (b) qualsiasi uso derivato di questo sito o dei suoi contenuti: (c) qualsiasi download o copia di informazioni sull'account a beneficio di un altro commerciante; o (d) qualsiasi uso di data mining, robot o strumenti simili di raccolta ed estrazione di dati.

\n\n \n\n

Questo sito o app o qualsiasi parte di questo sito non possono essere riprodotti, re-ingegnerizzati, duplicati, copiati, venduti, rivenduti, visitati o sfruttati in altro modo per qualsiasi scopo commerciale senza l'esplicito consenso scritto di SmartResQ/CorPatch®. Non è consentito incorniciare o utilizzare tecniche di framing per racchiudere marchi, loghi o altre informazioni di proprietà (compresi immagini, testi, layout di pagina o moduli) di SmartResQ/CorPatch® e dei nostri associati senza un esplicito consenso scritto.

\n\n \n\n

Non è consentito utilizzare meta tag o qualsiasi altro \"testo nascosto\" che utilizzi il nome o i marchi SmartResQ/CorPatch® senza l'esplicito consenso scritto di SmartResQ/CorPatch®. Qualsiasi uso non autorizzato pone fine all'autorizzazione o alla licenza concessa da SmartResQ/CorPatch®.

\n\n \n\n

All'utente viene concesso il diritto limitato, revocabile e non esclusivo di creare un collegamento ipertestuale alla home page di SmartResQ/CorPatch®, a condizione che il collegamento non ritragga SmartResQ/CorPatch®, i suoi associati o i loro prodotti o servizi in modo falso, fuorviante, spregiativo o altrimenti offensivo. Non è consentito utilizzare alcun logo SmartResQ/CorPatch® o altri marchi o grafici di proprietà come parte del link senza un'espressa autorizzazione scritta. \n
\nIn caso di violazione dell'accordo sulla licenza e sull'accesso al sito, verranno intraprese azioni legali e potrà essere intentata una causa in tribunale.

\n\n

Comunicazioni elettroniche

\n\n

Quando visitate la homepage e i canali di social media di SmartResQ/CorPatch® o ci inviate e-mail, comunicate con noi per via elettronica. L'utente acconsente a ricevere le nostre comunicazioni per via elettronica. Comunicheremo con voi tramite e-mail o pubblicando avvisi sui nostri siti web o nelle app sotto forma di pop-up o notifiche. L'utente accetta che tutti gli accordi, gli avvisi, le divulgazioni e le altre comunicazioni che gli forniamo elettronicamente soddisfino qualsiasi requisito legale che preveda la forma scritta di tali comunicazioni. Si prega di consultare la nostra Informativa sulla privacy in un documento separato che può essere trovato sulla nostra homepage.

\n\n \n\n

I visitatori del nostro sito web e dei nostri canali di social media possono essere invitati a pubblicare recensioni, commenti e altri contenuti, ad esempio, inviare suggerimenti, idee, commenti, domande o altre informazioni, purché il contenuto non sia illegale, osceno, minaccioso, diffamatorio, lesivo della privacy, lesivo dei diritti di proprietà intellettuale o altrimenti dannoso per terzi o discutibile e non consista di o contenga virus software, campagne politiche, richieste commerciali, catene di Sant'Antonio, mailing di massa o qualsiasi forma di \"spam\".

\n\n \n\n

Non è consentito utilizzare un indirizzo e-mail falso, impersonare una persona o un'entità o ingannare in altro modo sull'origine di una carta o di altri contenuti. SmartResQ/CorPatch® si riserva il diritto (ma non l'obbligo) di rimuovere o modificare i suddetti contenuti, ma non controlla regolarmente i contenuti pubblicati. Se l'utente pubblica contenuti o invia materiale e, a meno che non sia indicato diversamente, concede a SmartResQ/CorPatch® e ai suoi associati il diritto non esclusivo, esente da royalty, perpetuo, irrevocabile e completamente trasmissibile di utilizzare, riprodurre, modificare, adattare, pubblicare, tradurre, creare opere derivate, distribuire e visualizzare tali contenuti in tutto il mondo su qualsiasi supporto. L'utente concede a SmartResQ/CorPatch® e ai suoi associati e sublicenziatari il diritto di utilizzare il nome da lui inviato in relazione ai suddetti contenuti, se lo desiderano.

\n\n \n\n

L'utente dichiara e garantisce di possedere o di controllare in altro modo tutti i diritti sul contenuto che pubblica; che il contenuto è accurato; che l'uso del contenuto fornito non viola la presente informativa e non causerà danni a persone o entità; e che indennizzerà SmartResQ/CorPatch® o i suoi associati per tutti i reclami derivanti dal contenuto fornito. SmartResQ/CorPatch® ha il diritto, ma non l'obbligo, di monitorare e modificare o rimuovere qualsiasi attività o contenuto. SmartResQ/CorPatch® non si assume alcuna responsabilità per i contenuti pubblicati dall'utente o da terzi.

\n\n
\n\n\n
\n

Esclusioni di responsabilità e garanzie

\n\n

Informazioni sul prodotto – CorPatch® e Trainer CorPatch®

\n\n

Per un uso corretto di qualsiasi prodotto o servizio SmartResQ/CorPatch® è necessario seguire sempre le guide, le istruzioni e le descrizioni più aggiornate. Sono disponibili sul nostro sito web e sotto la descrizione di ogni prodotto.

\n\n \n\n

Il prodotto CorPatch® è certificato come dispositivo medico. In caso di emergenza per un adulto in arresto cardiaco, il prodotto deve essere estratto dal suo alloggiamento, posizionato e fissato correttamente sul torace della vittima. Il prodotto è in grado di raccogliere dati su compressione, profondità, frequenza e ritorno indietro e può trasmetterli via Bluetooth® a potenziali dispositivi. Le applicazioni gratuite sui dispositivi possono guidare l'astante nell'esercizio della RCP e mostrare la frazione di flusso, la profondità, il ritorno indietro e la frequenza se attivate e correttamente installate, cioè Bluetooth®, smartphone, app, batteria, ecc. SmartResQ/CorPatch® non è responsabile di fattori esterni, ad esempio segnali di comunicazione interferenti, mancanza di copertura dei dati, mancanza di batteria, impostazioni hardware o software errate, che possono influire sull'esperienza dell'utente o simili.

\n\n \n\n

Allo stesso modo, SmartResQ/CorPatch® non è responsabile di eventuali danni fisici causati dall'uso del prodotto nel caso in cui non venga applicato o utilizzato secondo le istruzioni, ad esempio eseguendo le compressioni toraciche in modo non ergonomico o con una posizione delle mani non adatta. SmartResQ/CorPatch® ha valutato i rischi tecnici nell'ambito della gestione del rischio prescritta dalla legge per i dispositivi medici, ma non viene fornita alcuna garanzia per gli errori che vanno oltre tali prescrizioni. In caso di malfunzionamenti imprevisti o di comportamenti non plausibili del sistema SmartResQ/CorPatch® , l'utente è tenuto a eseguire manualmente la RCP. In questo caso, SmartResQ/CorPatch® non è responsabile in quanto fuori dal controllo di SmartResQ/CorPatch®. \n
\nSmartResQ/CorPatch® monitora i livelli della batteria e lo stato di salute, ma se la batteria si scarica, il prodotto non funziona. È responsabilità esclusiva dell'utente assicurarsi che il dispositivo sia aggiornato, non danneggiato e che abbia la batteria sufficiente per funzionare correttamente, cosa che può essere verificata facilmente eseguendo un'esercitazione che ne convalidi la corretta funzionalità. Si consiglia di esercitarsi con il CorPatch® per 4 minuti ogni tre mesi.

\n\n \n\n

Importante! Il prodotto CorPatch® deve essere utilizzato esclusivamente su una persona in una situazione reale e solo su persone in arresto cardiaco. Non è progettato per l'uso su persone affette, ad esempio, da ictus, infarto o altre patologie non legate all'arresto cardiaco. Il CorPatch® non è destinato all'uso se la persona è sdraiata su una superficie morbida, ad esempio un divano o un letto, poiché il feedback sulla profondità in queste condizioni potrebbe essere imprecisa. Le soluzioni SmartResQ/CorPatch® non sono destinate all'uso in un ambiente in movimento, comprese, ma non solo, le ambulanze aeree, marittime o stradali. Se utilizzato durante il trasporto del paziente o se viene sollevato/rimosso dal corpo durante la RCP, il dispositivo potrebbe fornire un feedback impreciso. Il CorPatch® deve essere applicato al torace del paziente con il patch. Assicurarsi che il paziente sia sdraiato su una superficie stabile, piana e non in movimento e che il CorPatch® sia fissato al torace con il patch.

\n\n \n\n

Il prodotto Trainer CorPatch® deve essere utilizzato esclusivamente su manichini o oggetti simili durante le Training session e mai in una situazione reale su una persona colpita da arresto cardiaco o da qualsiasi altra malattia.

\n\n \n\n

È possibile formare le proprie prestazioni di RCP in relazione alle compressioni toraciche utilizzando regolarmente CorPatch®️ o CorPatch®️ Trainer. Si consiglia di fare pratica su un manichino, ma se non si ha accesso a un manichino, si può utilizzare in sostituzione una sedia da ufficio con un movimento di ritorno adatto o un divano rigido. Considerare l'elasticità e la durezza dell'oggetto con cui si fa pratica. Durante l’esercitazione, SmartResQ sconsiglia l'uso di oggetti morbidi, tra cui cuscini o divani morbidi, poiché l'esperienza dell'utente non sarà corretta.

\n\n

Se non è possibile reperire un manichino o un oggetto sostitutivo per le esercitazioni, considerare di fare pratica per le eventuali situazioni che si verificano prima di iniziare le compressioni toraciche. Ad esempio, si possono seguire le informazioni fornite dall'applicazione gratuita sull'identificazione di un arresto cardiaco e sulla chiamata ai servizi di emergenza ed estrarre il CorPatch® dal porta chiavi. In questo caso, sarete pronti ad applicare rapidamente il CorPatch® in caso di arresto cardiaco.

\n\n \n\n

Non utilizzare i sistemi SmartResQ/CorPatch® per le esercitazioni o a fini di svago su persone (vive o morte), animali domestici o altri esseri umani o creature viventi.

\n\n \n\n

Esclusione di responsabilità per prodotti, siti web e applicazioni

\n\n

SmartResQ/CorPatch® non rilascia alcuna dichiarazione o garanzia e non è responsabile della competenza di nessuna persona che possa ricevere informazioni formative e/o formazione medica fornite attraverso o basate sul sistema o dell'esercizio delle proprie competenze da parte di tale persona dopo il completamento di qualsiasi formazione, corso o programma di studio che utilizzi il sistema. SmartResQ/CorPatch® non garantisce che chiunque riceva informazioni formative e/o formazione medica attraverso il sistema raggiunga un particolare livello di abilità o la competenza necessaria a qualificarsi per qualsiasi licenza, certificato o valutazione rilasciata da qualsiasi agenzia di regolamentazione o autorità governativa.

\n\n

SmartResQ/CorPatch® e i suoi associati cercano di essere il più accurati possibile. Tuttavia, SmartResQ/CorPatch® non dichiara e non garantisce che il sistema e le informazioni, i prodotti e la formazione qui forniti: (a) siano sempre o comunque disponibili; o (b) siano privi di errori, completi, accurati, veritieri, aggiornati e/o non fuorvianti. Quando si utilizza il sistema, si è a conoscenza e si è consapevoli di rinunciare a qualsiasi reclamo nei confronti di SmartResQ/CorPatch® per aver fatto affidamento su qualsiasi informazione o formazione presentata attraverso il sistema.

\n\n \n\n

I nostri prodotti non sono destinati all'uso da parte dei bambini. I prodotti sono piccoli e colorati e possono essere scambiati per giocattoli, ma i prodotti SmartResQ/CorPatch® non sono giocattoli! Si raccomanda di non lasciare i prodotti all'aperto e di tenerli fuori dalla portata dei bambini. SmartResQ/CorPatch® non si assume alcuna responsabilità in relazione all'uso dei prodotti da parte dei bambini. L'uso di CorPatch® da parte di bambini o adolescenti deve essere consentito e monitorato da adulti responsabili, ad esempio genitori, familiari o insegnanti.

\n\n \n\n

Esclusione di garanzie e limitazione di responsabilità: questo sito è fornito da SmartResQ/CorPatch® \"così com'è\" e \"come disponibile\". SmartResQ/CorPatch® non rilascia dichiarazioni o garanzie di alcun tipo, espresse o implicite, in merito al funzionamento di questo sito o alle informazioni, ai contenuti, ai materiali o ai prodotti inclusi in questo sito. L'utente accetta espressamente che l’utilizzo di questo sito è a suo esclusivo rischio. \n
\nNella misura massima consentita dalle leggi vigenti, SmartResQ/CorPatch® non riconosce alcuna garanzia, espressa o implicita, incluse, a titolo esemplificativo, le garanzie implicite di commerciabilità e idoneità a uno scopo particolare. SmartResQ/CorPatch® non garantisce che questo sito, i suoi server o le e-mail inviate da SmartResQ/CorPatch® siano privi di virus/spam o altri componenti dannosi.

\n\n \n\n

SmartResQ/CorPatch® non sarà responsabile per eventuali danni di alcun tipo derivanti dall'uso di questo sito o dei suoi prodotti, inclusi, ma non limitati a, danni diretti, indiretti, incidentali, punitivi e consequenziali. \n
\nAlcune leggi statali non consentono limitazioni alle garanzie implicite o l'esclusione o la limitazione di determinati danni. Se queste leggi sono applicabili all'utente, alcune o tutte le esclusioni, i limiti o le limitazioni di cui sopra potrebbero non essere applicabili e l'utente potrebbe avere ulteriori diritti.

\n\n \n\n

Le informazioni presentate in questo sito non devono essere interpretate come consulenza professionale. Prima di prendere qualsiasi decisione, si consiglia sempre di rivolgersi a consulenti professionisti che conoscono la situazione al fine di ottenere consigli su questioni specifiche.

\n\n \n\n

Il sito web può contenere link che conducono a siti web gestiti da individui o organizzazioni su cui SmartResQ/CorPatch® non ha alcun controllo. SmartResQ/CorPatch® non dichiara e non fornisce alcuna garanzia in merito all'accuratezza o a qualsiasi altro aspetto delle informazioni contenute in tali siti web.

\n\n \n\n

La responsabilità di qualsiasi opinione, consiglio, dichiarazione o altra informazione contenuta in articoli o testi di questo sito web è esclusivamente dell'autore e non riflette necessariamente le opinioni e le politiche di SmartResQ/CorPatch®.

\n\n \n\n

Esclusione di responsabilità legale

\n\n

Acquistando, concedendo in licenza, visualizzando, utilizzando e/o accedendo ai nostri siti web, prodotti e applicazioni, l'utente riconosce e accetta che:

\n
    \n
  1. I sistemi forniti da SmartResQ/CorPatch® sono prodotti specifici da utilizzare esclusivamente per l'uso previsto indicato nel manuale del prodotto. Leggere attentamente le istruzioni e i manuali d'uso e assicurarsi di avere familiarità con i nostri prodotti medici prima di utilizzarli.
  2. \n\n
  3. I sistemi forniti da SmartResQ/CorPatch® sono prodotti e strumenti didattici e di formazione medica specifici non sono certificati come dispositivi medici, a meno che non sia esplicitamente indicato; non sono destinati ad alcun uso clinico o diagnostico e devono essere utilizzati esclusivamente per scopi di formazione medica e miglioramento delle prestazioni.
  4. \n\n
  5. In qualsiasi momento l’utente utilizzerà e accederà al sistema esclusivamente in relazione a tali scopi di formazione medica e di miglioramento delle prestazioni; in conformità con tutte le leggi e i regolamenti applicabili e in conformità con qualsiasi documentazione per l'utente, manuale di istruzioni, guida e/o requisito che gli forniremo elettronicamente o di persona.
  6. \n\n
  7. In nessun caso il sistema SmartResQ/CorPatch®, da solo, possa diagnosticare, trattare o curare la condizione di un essere umano o in una situazione di salvataggio; supportare decisioni mediche professionali, diagnosi o trattamenti o sostituire qualsiasi diagnosi, raccomandazione, consiglio, trattamento o decisione da parte di un medico adeguatamente formato e autorizzato.
  8. \n\n
  9. L'associazione di un dispositivo con un danno o un esito per il paziente non significa che il dispositivo abbia causato il danno o l'esito.
  10. \n\n
  11. SmartResQ/CorPatch® non si assume alcuna responsabilità per i danni derivanti da un uso irragionevole dei nostri prodotti o da un uso che va oltre l'uso previsto del prodotto.
  12. \n
\n\n

Informazioni sulle prestazioni

\n\n

Le informazioni contenute nel presente documento sono presentate solo come guida per l'applicazione dei prodotti SmartResQ/CorPatch®. SmartResQ/CorPatch® lavora continuamente per migliorare la qualità e l'affidabilità dei suoi prodotti. Ciononostante, i nostri dispositivi possono funzionare male o guastarsi a causa della loro intrinseca sensibilità elettrica e vulnerabilità alle sollecitazioni fisiche e ai segnali di comunicazione avversi. È responsabilità dell'acquirente, quando utilizza i prodotti SmartResQ/CorPatch®, osservare gli standard di sicurezza e di collaudo ed evitare situazioni in cui un malfunzionamento o un guasto potrebbero causare lesioni fisiche o danni alle cose.

\n\n \n\n

Garanzia standard

\n\n

La Garanzia limitata standard SmartResQ/CorPatch® è subordinata all'uso corretto dei prodotti, dei siti web e delle applicazioni. \n
\nLa presente Garanzia è limitata al primo acquirente del prodotto e solo se il prodotto viene acquistato da un rivenditore autorizzato SmartResQ/CorPatch®. I produttori, i fornitori o gli editori, diversi da SmartResQ/CorPatch®, possono fornire le proprie garanzie: per ulteriori informazioni, contattarli.

\n\n \n\n

La garanzia non copre:

\n
    \n
  1. difetti o danni derivanti da incidenti, uso improprio, uso anomalo, condizioni anomale, stoccaggio improprio, esposizione a liquidi, umidità, sabbia o sporcizia, negligenza o insolite sollecitazioni fisiche, elettriche o elettromeccaniche,
  2. \n\n
  3. difetti o danni derivanti da una forza eccessiva o dall'uso di oggetti metallici,
  4. \n\n
  5. apparecchiature con numero di produzione o codice dati di miglioramento rimosso, deturpato, danneggiato, alterato o reso illeggibile,
  6. \n\n
  7. l'usura ordinaria o il normale invecchiamento del prodotto,
  8. \n\n
  9. graffi, ammaccature e danni estetici, a meno che il guasto non sia dovuto a un difetto di materiale o di lavorazione,
  10. \n\n
  11. difetti o danni derivanti dall'uso dei prodotti in combinazione o in connessione con accessori, prodotti o apparecchiature ausiliarie/periferiche non forniti o approvati da SmartResQ/CorPatch®,
  12. \n\n
  13. difetti o danni derivanti da test, funzionamento, manutenzione, installazione, servizio o regolazione impropri non forniti o approvati da SmartResQ/CorPatch®,
  14. \n\n
  15. danni causati dal funzionamento del prodotto SmartResQ/CorPatch® al di fuori delle linee guida pubblicate,
  16. \n\n
  17. dimostrazione/installazione del prodotto acquistato,
  18. \n\n
  19. difetti o danni derivanti da cause esterne quali collisione con un oggetto, incendio, allagamento, sporcizia, tempesta di vento, fulmine, terremoto, esposizione a condizioni atmosferiche, furto, fusibili bruciati o uso improprio di qualsiasi fonte elettrica,
  20. \n\n
  21. difetti o danni derivanti da trasmissione o virus, o altri problemi di software introdotti nei Prodotti,
  22. \n\n
  23. se le batterie vengono ricaricate con caricabatterie diversi da quelli compatibili con Trainer CorPatch®,
  24. \n\n
  25. se i sigilli del vano batteria o delle celle sono rotti o presentano segni di manomissione,
  26. \n\n
  27. prodotti riparati, utilizzati o acquistati da un'azienda diversa da SmartResQ/CorPatch®,
  28. \n\n
  29. se SmartResQ/CorPatch® riceve informazioni dalle autorità pubbliche competenti che il prodotto è stato rubato o se l'utente non è in grado di disattivare il codice di accesso o altre misure di sicurezza volte a prevenire l'accesso non autorizzato al prodotto o se non può dimostrare di essere l'utente autorizzato del prodotto,
  30. \n\n
  31. se i prodotti vengono utilizzati al di fuori delle condizioni specificate nei manuali, ad esempio, intervallo di temperatura, pressione e umidità.
  32. \n
\n \n\n

Batterie e caricabatterie

\n\n

I prodotti SmartResQ/CorPatch® contengono batterie non sostituibili (CorPatch®) o batterie ricaricabili (Trainer CorPatch®). I tipi di batterie utilizzati nei nostri prodotti sono descritti in ogni singolo prodotto. SmartResQ/CorPatch® non si assume alcuna responsabilità se le batterie ricaricabili non vengono maneggiate correttamente secondo le istruzioni per l'uso.

\n\n\n

In relazione alla vendita di dispositivi contenenti batterie, siamo tenuti a far notare quanto segue: \n
\nIn qualità di utenti finali, lo smaltimento corretto è un obbligo di legge. Il simbolo del bidone barrato indica che la batteria non può essere gettata insieme ai rifiuti domestici.

\n\n
\n\n\n
\n

Ordini

\n\n

Il negozio online di Corpatch.com è aperto 24 ore su 24 ed è possibile acquistare in qualsiasi momento. Tuttavia, potremmo chiudere il negozio per manutenzione. L'acquisto di grandi volumi può avvenire direttamente con SmartResQ/CorPatch®.

\n\n \n\n

SmartResQ/CorPatch® non offre prodotti in vendita ai minori. I prodotti destinati ai bambini possono essere acquistati solo da adulti. Per acquistare da SmartResQ/CorPatch® è necessario avere almeno 18 anni e possedere una carta di credito valida o altri mezzi di pagamento accettati.

\n\n \n\n

La presentazione dei prodotti nel negozio online non è un'offerta giuridicamente vincolante, ma un catalogo online non vincolante. Al momento dell'acquisto, selezionare gli articoli che si desidera acquistare e metterli nel \"carrello\". È possibile modificare il contenuto del carrello fino al momento dell'ordine. Eventuali pagamenti extra, come spese di spedizione o di carta di debito, saranno calcolati immediatamente prima del pagamento.

\n\n \n\n

Quando si è pronti per l'ordine, cliccare su \"Checkout/Cassa\" e inserire le informazioni necessarie. È possibile modificare il contenuto del carrello fino alla conferma dell'acquisto che avviene cliccando il pulsante \"Paga\". A questo punto l’utente ha effettuato un ordine vincolante per la merce contenuta nel carrello, che non può più essere modificato. \n
\nSmartResQ/CorPatch® può accettare l'ordine inviando una conferma d'ordine via e-mail o consegnando la merce entro il termine di consegna.

\n\n \n\n

Alcuni paesi possono impedire l'uso e il possesso dei nostri prodotti. L'utente ha la responsabilità esclusiva di informarsi se questo prodotto sia legale da importare e/o utilizzare nel proprio paese. Invieremo i prodotti ordinati e non ci assumiamo alcuna responsabilità per questioni doganali o per eventuali implicazioni legate al possesso o all'utilizzo di questo dispositivo.

\n\n
\n\n\n
\n

Pagamenti

\n\n

I nostri siti web, app e negozi online

\n\n

I nostri siti web e le nostre app sono liberi di essere utilizzati a condizione che le nostre politiche legali siano accettate e rispettate. Si noti che gli acquisti dei nostri prodotti potrebbero essere disponibili nei negozi online, sui nostri siti e nelle app.

\n\n \n\n

I nostri prodotti

\n\n

SmartResQ/CorPatch® utilizza QuickPay come gateway di pagamento. QuickPay è certificato dal Consiglio per gli standard di sicurezza dell'industria delle carte di pagamento (PCI – Payment Card Industry) in base all'ultima versione degli standard di sicurezza dei dati (DSS – Data Security Standard) PCI di livello 1, che comprende: (a) un rapporto annuale – relazione di conformità (ROC – Report on Compliance) condotto da un controllore della sicurezza qualificato (QSA – Qualified Security Assessor); (b) scansioni trimestrali della rete eseguite da Approved Scan Vendor (ASV), e (c) un gran numero di regole e linee guida per il flusso di lavoro e l'elaborazione dei dati.

\n\n \n\n

Accettiamo pagamenti con:

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • MasterCard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n

I pagamenti saranno detratti dal vostro conto al momento della spedizione della merce. Tutti gli importi sono in euro e l'imposta sul valore aggiunto prevista dalla legge è già inclusa in tutti i prezzi indicati. Tutti i titolari di carte di credito/debito sono soggetti a controlli di convalida e autorizzazione da parte dell'emittente della carta o del fornitore di pagamenti. SmartResQ/CorPatch® non è responsabile nel caso in cui il fornitore della carta di pagamento si rifiuti di autorizzare i pagamenti.

\n\n

Utilizziamo la crittografia per i dati della carta di credito attraverso il protocollo Secure Socket Layer (SSL). Questo garantisce che altri non possano intercettare il numero della carta di credito o altre informazioni durante la transazione con il nostro fornitore.

\n\n \n\n

Prima di concludere il contratto, il cliente deve controllare e accettare i costi di spedizione e logistica aggiunti al prezzo di acquisto, in quanto tali costi vengono addebitati al cliente. Dopo aver effettuato un ordine, riceverete un'e-mail di conferma della ricezione dell'ordine. Si noti che questo non significa che l'ordine sia stato accettato. L'ordine costituisce un'offerta a SmartResQ/CorPatch® per l'acquisto di un prodotto (e SmartResQ/CorPatch® si riserva il diritto di rifiutare ordini di prodotti). Non esisterà alcun contratto in relazione ai prodotti fino a quando non avremo confermato via e-mail che il prodotto o i prodotti sono stati spediti. Avremo accettato completamente l'offerta e il contratto verrà stipulato tra le parti quando invieremo una mail di conferma della spedizione.

\n\n \n\n

I costi di spedizione sono sempre indicati in relazione a ogni singolo ordine.

\n\n \n\n

SmartResQ/CorPatch® mantiene la proprietà dell'articolo acquistato fino al completo pagamento dell'importo della fattura da parte del cliente e viene automaticamente \"prelevato\" poco prima della spedizione.

\n\n \n\n

I clienti hanno diritto alla compensazione solo se le loro domande riconvenzionali sono state legalmente stabilite o sono incontestate o riconosciute da SmartResQ/CorPatch®. Inoltre, i clienti hanno un diritto di ritenzione solo se e nella misura in cui la loro domanda riconvenzionale si basa sullo stesso rapporto contrattuale.

\n\n \n\n

Se il cliente è in arretrato con noi in merito a qualsiasi obbligo di pagamento, tutti i crediti esistenti diventano immediatamente esigibili.

\n\n \n\n

Commissioni di rincaro

\n\n

A partire dal 1° gennaio 2018, le regole relative al sovrapprezzo sono state modificate. Pertanto, non è più legale applicare commissioni sui pagamenti effettuati con le carte dei consumatori se queste sono emesse da banche/emittenti di carte all'interno dell'UE. Questo vale sia per le carte di debito che per quelle di credito. Le carte per i consumatori sono carte emesse a favore di un consumatore privato. \n
\nTuttavia, se la carta è aziendale o una carta per i consumatori emessa al di fuori dell'UE, la commissione della transazione sarà maggiorata. Ciò significa che il titolare della carta paga automaticamente la commissione di transazione. \n
\nLa commissione non sarà superiore a quella addebitata a SmartResQ/CorPatch® dall'acquirente. L'imposta sarà chiaramente indicata separatamente nella finestra di pagamento.

\n\n
\n\n\n
\n

Consegna

\n\n

Ci impegniamo a spedire gli ordini entro un giorno lavorativo e ci avvaliamo di un'agenzia di spedizioni di fiducia a livello internazionale. Il prezzo totale dell'acquisto, compresa la consegna, è indicato alla cassa prima di accettare l'ordine finale.

\n\n \n\n

Se il cliente non accetta la merce, SmartResQ/CorPatch® può recedere dal contratto o ricevere un risarcimento per inadempimento dopo un periodo di due settimane a copertura delle spese di gestione e spedizione.

\n\n \n\n

Se il cliente ha fornito dati errati sull'indirizzo di consegna, è possibile ritirare il pacco presso il punto di ritiro indicato nel nostro negozio online, altrimenti il pacco andrà perso.

\n\n \n\n

Il cliente non riceverà mai consegne parziali se non esplicitamente indicato da SmartResQ/CorPatch®.

\n\n \n\n

Rischio di perdita

\n\n

Il rischio sul prodotto viene trasferito all'acquirente quando il prodotto viene messo a disposizione dell'acquirente in base al presente accordo. Se il termine di consegna è scaduto e l'acquirente non riceve un prodotto messo a disposizione per lui/lei o a sua disposizione in base al contratto, l'acquirente detiene il rischio di perdita o danno causato dalle caratteristiche del prodotto stesso.

\n\n
\n\n\n
\n

Cancellazione e restituzione

\n\n

Quando si effettua un acquisto presso SmartResQ/CorPatch®, online o offline, ci sono 14 giorni di tempo per cambiare idea e annullare il contratto, informandoci di aver cambiato idea e restituendoci l'articolo nello stesso stato in cui è stato ricevuto. \n
\nAccettiamo solo resi di articoli inutilizzati in confezioni originali, sigillate e non danneggiate e devono essere adeguatamente imballati per la spedizione, altrimenti i prodotti saranno considerati usati e non si applicheranno rimborsi parziali. Il diritto di recesso si applica solo ai prodotti non sigillati al momento della ricezione.

\n\n \n\n

Motivi accettabili per la restituzione di un prodotto

\n
    \n
  • Applicazione del diritto di recesso di 14 giorni
  • \n\n
  • Prodotto non conforme alla descrizione (garanzia)
  • \n\n
  • Il prodotto è difettoso
  • \n
\n \n\n

Le condizioni per la restituzione di CorPatch® seguono le regole standard dell'UE.

\n\n

In caso di restituzione del prodotto, conservare l'imballaggio originale e non danneggiarlo, incollarlo o scriverci sopra. Procurarsi e utilizzare un imballaggio dedicato alla restituzione, ad esempio una scatola di cartone.

\n\n \n\n

Per Trainer CorPatch®, i termini di ritiro di questo prodotto sono conformi alle norme standard dell'UE.

\n\n \n\n

Per esercitare il diritto di recesso, è necessario comunicarlo entro 14 giorni dalla ricezione degli articoli. Le richieste di recesso devono essere inviate via e-mail a info@corpatch.com, indicando chiaramente che si desidera avvalersi dei diritti di recesso e il motivo.

\n\n \n\n

Ci aspettiamo che il cliente restituisca gli articoli il prima possibile dopo aver comunicato il recesso e non più tardi di 14 giorni dopo averci informato via e-mail.

\n\n \n\n

Possiamo rifiutare il rimborso finché non saranno restituiti gli articoli o non sarà dimostrato di averli restituiti. Per questo rimborso utilizzeremo lo stesso metodo di pagamento usato nella transazione originale.

\n\n \n\n

Motivi non accettabili per la restituzione di un prodotto

\n
    \n
  • Ripensamento dopo il diritto di recesso di 14 giorni.
  • \n\n
  • Se il prodotto è stato attivato.
  • \n\n
  • Se il prodotto viene utilizzato o danneggiato in qualsiasi altro modo.
  • \n\n
  • Se il software/applicazione gratuita viene scaricato, collegato, installato o in qualsiasi altro modo combinato con i prodotti fisici.
  • \n
\n \n\n

Come restituire il prodotto

\n\n

Accettiamo solo resi di articoli non aperti, nella confezione originale e non danneggiata e devono essere adeguatamente imballati per la spedizione, altrimenti i prodotti saranno considerati usati e non si applicheranno rimborsi.

\n \n\n

Se non diversamente indicato, i resi devono essere inviati a: \n
\nSmartResQ ApS (CorPatch®) \n
\nLundevej 26 \n
\nDK-5700 Svendborg \n
\nDanimarca

\n\n

IMPORTANTE! Il cliente è l'unico responsabile della qualità dell'imballaggio e degli articoli fino al ricevimento da parte nostra. Si prega di conservare la ricevuta postale con le informazioni sulle spese di spedizione e, se del caso, il numero di tracciabilità. Non copriamo le spese di spedizione per la restituzione e non accettiamo pacchi inviati in contrassegno o simili.

\n\n
\n\n\n
\n \n\n

Rimborsi

\n\n

SmartResQ/CorPatch® è obbligata a riparare, sostituire o concedere una riduzione di prezzo o un rimborso completo se l'articolo si rivela difettoso entro 2 anni dall'acquisto. \n
\nIl cliente non ha diritto al rimborso se il problema è di lieve entità, come ad esempio graffi o simili. \n
\nUna volta che SmartResQ/CorPatch® riceve l'articolo del cliente, viene avviato il rimborso. Il valore dell'importo del rimborso dipende dallo stato dei prodotti al momento della ricezione presso SmartResQ/CorPatch®.

\n\n\n

Il modo in cui viene elaborato il rimborso del cliente dipende dal metodo di pagamento originale. Se il cliente ha pagato con carta di credito o di debito, il rimborso sarà inviato alla banca emittente della carta entro cinque giorni lavorativi dal ricevimento dell'articolo restituito o della richiesta di cancellazione. Per sapere quando il rimborso verrà accreditato sul conto, contattare la banca che ha emesso la carta.

\n\n
\n\n\n
\n

Trattamento dei dati personali

\n\n

Noi di SmartResQ/CorPatch® proteggiamo i vostri dati personali con il nostro impegno al rispetto dei dati in tre fasi: a. mantenere una mappa dettagliata del nostro flusso di dati, b. eseguire valutazioni legali in base al flusso di dati al fine di, c. adottare le misure di sicurezza necessarie per mantenere i dati al sicuro.

\n\n \n\n

Per poter utilizzare il nostro negozio online è necessario fornire almeno le seguenti informazioni:

\n
    \n
  • Nome
  • \n\n
  • Indirizzo
  • \n\n
  • Indirizzo e-mail
  • \n\n
  • Numero di telefono
  • \n
\n \n\n

La raccolta dei dati personali dei clienti avviene nell'ambito della legislazione vigente e del Regolamento generale sulla protezione dell'UE (RGDP).

\n\n \n\n

Per ulteriori informazioni sul trattamento dei dati personali, consultare la nostra Informativa sulla privacy.

\n\n
\n\n\n
\n

Reclami

\n\n

Come presentare un reclamo

\n\n

Se c'è qualcosa che non va nel prodotto, è possibile far riparare o sostituire il prodotto difettoso, ricevere un rimborso o una riduzione del prezzo, a seconda della situazione specifica. \n
\nNaturalmente, è necessario che il reclamo sia giustificato e che il difetto non sia causato da un uso scorretto del prodotto o da un altro comportamento scorretto.

\n\n \n\n

Si consiglia di presentare il reclamo il prima possibile ed entro una settimana da quando si riscontra il difetto.\n
\nNon esitate a contattarci per qualsiasi domanda, commento o reclamo via e-mail: info@corpatch.com

\n\n

Presentare un reclamo ad altri enti all'interno dell'UE

\n\n

Per presentare reclami ad altri enti dell'UE, vi consigliamo di visitate il sito ufficiale dell'Unione europea. Sono disponibili più informazioni qui.

\n\n
\n\n\n
\n

Modifiche al presente documento

\n\n

Sui siti web, app e politiche

\n\n

SmartResQ/CorPatch® si riserva il diritto di apportare modifiche, eliminare, modificare o integrare i propri siti web, le app, le politiche e i documenti in qualsiasi momento e per qualsiasi motivo, senza alcun preavviso. \n
\nSe una qualsiasi delle presenti condizioni dovesse essere ritenuta non valida, nulla o per qualsiasi motivo inapplicabile, tale condizione sarà considerata separabile e non pregiudicherà la validità e l'applicabilità delle altre condizioni.

\n \n\n

In caso di modifiche alle nostre informative, le pubblicheremo online con la data di revisione aggiornata. Vi invitiamo a controllare regolarmente le informative. Nel caso in cui apportassimo modifiche sostanziali alla nostra informativa che cambiano in modo significativo le nostre policy, possiamo anche informarvi in altri modi, ad esempio inviando un'e-mail o pubblicando un avviso sul nostro sito web e/o sui social media prima che le modifiche entrino in vigore.

\n\n \n\n

Informazioni su un acquisto specifico

\n\n

Al momento dell'acquisto di un prodotto, verrà chiesto di accettare una versione di determinati documenti così come sono in quel preciso momento; tale versione non potrà essere modificata dopo tale momento e detterà i termini del nostro rapporto con l'utente in merito a quell'esatto acquisto.

\n\n
\n\n\n
\n

Leggi e giurisdizione

\n\n

Le leggi della Danimarca e il Tribunale distrettuale di Svendborg

\n\n \n\n

SmartResQ/CorPatch® applica la legge e sceglie le sedi danesi per qualsiasi controversia legale, ma non la CISG (Convenzione sulla vendita internazionale di beni). \n
\nQualsiasi controversia relativa in qualsiasi modo alla visita dell'utente a SmartResQ/CorPatch® o ai prodotti acquistati tramite SmartResQ/CorPatch® sarà sottoposta alla giurisdizione confidenziale della Danimarca, ad eccezione del fatto che, nella misura in cui l'utente abbia in qualsiasi modo violato o minacciato di violare i diritti di proprietà intellettuale di SmartResQ/CorPatch®, SmartResQ/CorPatch® potrà chiedere un'ingiunzione o altri provvedimenti appropriati in qualsiasi paese e l'utente acconsente alla giurisdizione esclusiva e allo svolgimento in sede in tali tribunali.

\n\n \n\n

In caso di violazione dell'accordo \"Termini e condizioni\", verranno intraprese azioni legali e potrà essere intentata una causa in tribunale.

\n\n \n\n

Le controversie tra noi e qualsiasi consumatore sono soggette al tribunale distrettuale di Svendborg, Christiansvej 41, 5700 Svendborg, Danimarca.

\n\n
\n\n\n
\n

Informazioni di contatto

\n\n

Grazie per aver letto i \"Termini e condizioni\" di SmartResQ/CorPatch®. \n
\nIn caso di domande, commenti o reclami, non esitate a contattarci.

\n\n \n\n

La nostra azienda si trova presso: Lundevej 26, 5700 Svendborg, Danimarca

\n \n\n

Ci trovate nel Registro Centrale delle Imprese con il numero di partita IVA DK 38674102

\n\n \n\n

Potete chiamarci al numero di telefono +45 62 200 100

\n\n \n\n

oppure

\n\n \n\n

contattateci all'indirizzo e-mail: info@corpatch.com

\n\n \n\n

© SmartResQ ApS – Tutti i diritti riservati\n
\nDanimarca, Versione 2.1 – Pubblicato il 25.04.2023

\n\n
\n \n \n \n \n\n\n \n \n\n
\n

Informativa sulla privacy SmartResQ / CorPatch®

\n\n\n

Come trattiamo i dati in conformità al RGDP

\n\n

SmartResQ/CorPatch® rispetta la vostra privacy. Questa dichiarazione sulla privacy descrive i diritti alla privacy e il nostro impegno a proteggere le informazioni personali.

\n\n

In caso di domande sul trattamento dei vostri dati personali da parte nostra, contattateci. Il titolare del trattamento è:

\n\n

Azienda: SmartResQ ApS (CorPatch®)

\n\n

Indirizzo: \n
\nLundevej 26 \n
\n5700 Svendborg \n
\nDanimarca

\n

N. CVR: 38674102

\n\n

N. di telefono: +45 62 200 100

\n\n

E-mail: info@corpatch.com

\n\n

SmartResQ/CorPatch® è un'azienda danese/europea con entità legali, processi aziendali, strutture gestionali e sistemi tecnici situati oltre i confini nazionali. SmartResQ/CorPatch® fornisce prodotti, software e servizi ad aziende pubbliche e private in Europa.

\n\n

La sede centrale si trova in Danimarca e SmartResQ/CorPatch® è soggetta alla legislazione europea sulla protezione dei dati, compreso il Regolamento generale sulla protezione dei dati (RGDP). Tutte le decisioni più importanti in SmartResQ/CorPatch® riguardanti la protezione dei dati personali vengono prese a livello dirigenziale, sotto la supervisione del Responsabile della protezione dei dati.

\n\n

Questa dichiarazione sulla privacy è disponibile sui nostri siti web e nelle nostre applicazioni.

\n\n

Si prega di non utilizzare le pagine di SmartResQ/CorPatch®, le app o i nostri servizi se non si accetta la nostra modalità di trattamento dei dati personali ai sensi della presente informativa sulla privacy.

\n\n
\n\n\n
\n

Il tipo di informazioni personali che raccogliamo

\n\n

Quando un responsabile determina le finalità e i mezzi del trattamento dei vostri dati personali, agisce come titolare del trattamento. Ciò include scenari in cui SmartResQ/CorPatch® raccoglie dati personali nel contesto di una ricerca di lavoro, di un rappresentante di un cliente o di un potenziale cliente, o se si è utenti del software.

\n\n

SmartResQ tratta i dati personali per una serie di scopi, a seconda del rapporto in essere.

\n\n

Possiamo trattare:

\n
    \n
  1. Informazioni di base sui contatti, come nome, indirizzo, numero di telefono (cellulare e/o fisso) ed e-mail
  2. \n\n
  3. Informazioni sull'occupazione, come il datore di lavoro, il titolo, la posizione, comprese le preferenze e gli interessi in un contesto professionale
  4. \n\n
  5. Feedback, commenti o domande su SmartResQ/CorPatch® o sui nostri prodotti e servizi
  6. \n\n
  7. Foto o video registrati nei nostri siti
  8. \n\n
  9. Contenuti caricati dall'utente, come foto, video e prestazioni nel tempo
  10. \n\n
  11. Informazioni univoche sull'utente, come ID di accesso, nome utente, password e domanda di sicurezza,
  12. \n\n
  13. informazioni finanziarie, qualora l'utente acconsenta all'utilizzo delle sue informazioni, ad esempio per la memorizzazione dei dati della sua carta di pagamento,
  14. \n\n
  15. Informazioni sul traffico fornite dal vostro browser web, come il tipo di browser, il dispositivo, la lingua e l'indirizzo del sito web da cui provenite, e altre informazioni sul traffico, tra cui l'indirizzo IP,
  16. \n\n
  17. comportamento e attività sugli ID di SmartResQ/CorPatch® e con nostri prodotti e servizi,
  18. \n\n
  19. comportamento della posta elettronica, come ad esempio i messaggi e-mail di SmartResQ/CorPatch® che apre quando e come,
  20. \n\n
  21. altre informazioni personali contenute nel vostro profilo che avete liberamente inserito in social network terzi, come LinkedIn, Facebook, Google, ecc.,
  22. \n\n
  23. Informazioni utilizzate a fini scientifici per migliorare la sopravvivenza dopo un arresto cardiaco, raccolte tramite i nostri siti web e le nostre applicazioni,
  24. \n\n
  25. informazioni sugli utenti per fornire prodotti conformi ai requisiti di qualità e sicurezza, per fornire servizi agli utenti e per mantenere e migliorare le nostre offerte,
  26. \n\n
  27. informazioni sui candidati per gestire le domande di lavoro, per comunicare le offerte di lavoro future e per mantenere e migliorare i nostri processi di selezione del personale,
  28. \n\n
  29. informazioni sulle persone che si sono iscritte per ricevere newsletter e altri materiali, per la consegna di materiali e per mantenere e migliorare le nostre offerte,
  30. \n\n
  31. informazioni sui cookie per fornire pubblicità su misura sui social media e sui siti web.
  32. \n
\n\n
\n\n\n
\n

Dati raccolti e gestiti nella piattaforma e nelle applicazioni dei servizi CorPatch®

\n\n

SmartResQ gestisce, raccoglie e memorizza i seguenti dati personali quando utilizza la piattaforma o le applicazioni dei Servizi CorPatch®.

\n\n \n \n\n

Tutti gli utenti (Institute Admin, Trainer, Trainee/utente finale)

\n
    \n
  • Nome (se inserito)
  • \n\n
  • Cognome (se inserito)
  • \n\n
  • Soprannomi (se inseriti)
  • \n\n
  • Indirizzo e-mail (obbligatorio)
  • \n\n
  • Lingua di comunicazione preferita (obbligatorio)
  • \n\n
  • Hash della password (obbligatorio)
  • \n\n
  • Se l'indirizzo e-mail è stato convalidato (obbligatorio)
  • \n
\n \n\n

Dati aggiuntivi per Trainee/utenti finali (obbligatorio)

\n\n

Dati sul telefono cellulare utilizzato:

\n\n

Sistema operativo (Android/iOS):

\n
    \n
  • Versione del sistema operativo (ad es. 9)
  • \n\n
  • Produttore (ad es. Samsung)
  • \n\n
  • Modello (ad es. SM-T518)
  • \n\n
  • Versione dell'app (ad es. 1.2.4)
  • \n\n
  • Ora dell'ultima attività in primo piano dell'app
  • \n\n
  • Ora dell'ultima attività in background dell'app
  • \n
\n \n\n

Dati sul CorPatch® (CPS) utilizzato:

\n
    \n
  • Numero di serie / indirizzo MAC
  • \n\n
  • Versione del firmware
  • \n\n
  • Nome del modello (ad es. CPS_01)
  • \n\n
  • Produttore (attualmente sempre SRQ)
  • \n\n
  • Nome (attualmente sempre CorPatch®)
  • \n\n
  • Condizioni della batteria
  • \n\n
  • Difetti
  • \n
\n \n\n

Dati di inserimento degli utenti:

\n
    \n
  • Tutorial completato (sì/no)
  • \n\n
  • Condizioni di utilizzo accettate (sì/no)
  • \n\n
  • Autovalutazione completata (sì/no)
  • \n\n
  • Formazione al test completata (sì/no)
  • \n\n
  • Primo accesso riuscito (sì/no)
  • \n\n
  • Connessione di CPS (sì/no)
  • \n
\n \n\n

Dati raccolti durante le esercitazioni:

\n
    \n
  • Data, ora e durata delle esercitazioni
  • \n\n
  • Risultati delle esercitazioni
  • \n\n
  • Tipo di esercitazione o impostazioni dell'esercitazione
  • \n\n
  • In caso di esercitazione all'interno di un istituto, informazioni aggiuntive sul corso, sul trainer e sull'istituto.
  • \n
\n \n \n\n

Registri del server

\n\n

I seguenti dati vengono memorizzati nei registri del server web:

\n
    \n
  • Indirizzo IP della parte che effettua l'accesso
  • \n\n
  • Versione del browser della parte che accede
  • \n\n
  • Data/ora dell'accesso
  • \n\n
  • URL dell'accesso
  • \n
\n

Servizi esterni di elaborazione dei dati

\n
    \n
  • Google/Firebase per l'accesso remoto, analisi degli errori e dei crash
  • \n\n
  • Google/Firebase per l'invio di notifiche
  • \n\n
  • Sendgrid per l'invio di e-mail
  • \n\n
  • Hetzner Online GmbH per l'hosting del backend web e del database
  • \n
\n \n\n

Cosa succede quando un utente viene eliminato

\n
    \n
  • L'utente elimina il proprio profilo dal nostro sistema sulla homepage dei servizi di CorPatch® https://app.corpatch.com
  • \n\n
  • L'utente viene contrassegnato come eliminato. Dopo di che, non avrà più accesso, non sarà visibile agli amministratori, ecc.ma l'utente esiste ancora nel database.
  • \n\n
  • Dopo 14 giorni, i dati dell'utente vengono automaticamente eliminati dal database.
  • \n\n
  • Ai fini della valutazione scientifica e del miglioramento della funzionalità, i dati relativi alla pratica e all'utilizzo di CorPatch® continueranno a essere presenti nel database anche dopo la cancellazione dell'utente, ma il riferimento (ID) all'utente sarà vuoto e tutti i riferimenti ai dati personali saranno rimossi.
  • \n
\n\n
\n\n\n
\n

Come raccogliamo i dati personali

\n\n

La maggior parte dei dati personali che trattiamo ci vengono forniti direttamente dall'utente. Raccogliamo e trattiamo i dati quando:

\n
    \n
  • ci si registra online o si effettua un ordine per uno qualsiasi dei nostri prodotti o servizi; ad esempio, dati demografici, indirizzo e-mail, informazioni di pagamento, articoli, importo dell'ordine, livello e frequenza degli sconti. Compreso l'invio di e-mail transazionali, ad esempio la conferma dell'ordine, la conferma della spedizione e la conferma del rimborso,
  • \n\n
  • si interagisce con le comunicazioni inviate (e-mail, SMS, posta o telefono); ad esempio, tasso di apertura, tasso di clic e tempo di lettura delle e-mail, dominio del mittente e tipo di client e-mail,
  • \n\n
  • è possibile compilare volontariamente un sondaggio tra i clienti o fornire un feedback su una qualsiasi delle nostre bacheche o via e-mail.
  • \n
\n \n\n

Potremmo anche ricevere informazioni personali indirettamente, dalle seguenti fonti, nei seguenti scenari:

\n
    \n
  • Dai cookie: quando si visitano i nostri siti web o le nostre app; ad esempio, indirizzo IP, paese, pagine visualizzate, prodotti visualizzati, interazioni/clic e ricerche.
  • \n\n
  • Dall'utente o da qualsiasi altra persona affiliata al nostro cliente. Questa persona può essere un manager o un collega. Se il cliente per cui si lavora acquista prodotti o servizi da SmartResQ/CorPatch® attraverso una società partner di SmartResQ/CorPatch®, potremmo raccogliere informazioni su di voi dalla società partner.
  • \n\n
  • Partner di marketing di SmartResQ/CorPatch®, fonti pubbliche o social network di terzi.
  • \n\n
  • SmartResQ/CorPatch® potrà combinare i dati personali dell'utente raccolti da una fonte con informazioni ottenute da un'altra fonte. Questo ci permette di avere un quadro più completo dell'utente e di servirlo in modo più pertinente e con un livello di personalizzazione più elevato.
  • \n
\n\n
\n\n\n
\n

Come usiamo i dati

\n\n

Per gestire in generale le relazioni con i clienti e per rispettare gli impegni assunti con i clienti, SmartResQ/CorPatch® ha bisogno di informazioni sull'utente in qualità di cliente o quando utilizza un servizio. Le finalità del trattamento di tali dati personali sono:

\n\n
    \n
  • elaborare l'ordine, gestire l'account
  • \n\n
  • inviare e-mail con offerte speciali su altri prodotti e servizi che riteniamo possano essere graditi
  • \n\n
  • sviluppare il processo di vendita e di contratto per i clienti
  • \n\n
  • fornire ai clienti i prodotti e i servizi richiesti
  • \n\n
  • effettuare consegne in conformità agli accordi stipulati con l'utente o con i clienti
  • \n\n
  • offrire assistenza agli utenti dei nostri prodotti e servizi
  • \n\n
  • migliorare e sviluppare la qualità, la funzionalità e l'esperienza utente dei nostri prodotti, servizi e dei siti web e delle applicazioni SmartResQ/CorPatch®
  • \n\n
  • rilevare, limitare e prevenire le minacce alla sicurezza ed eseguire la manutenzione, la risoluzione dei problemi e il debug
  • \n\n
  • prevenire l'uso improprio dei nostri prodotti e servizi
  • \n\n
  • elaborare ordini, fatture, pagamenti o altri procedimenti finanziari
  • \n\n
  • creare profili di interesse per promuovere prodotti e servizi rilevanti
  • \n\n
  • creare comunità di utenti per educare e facilitare l'interazione tra gli utenti e SmartResQ/CorPatch®
  • \n
\n \n\n

Informazioni dei potenziali clienti

\n\n

SmartResQ/CorPatch® elabora i dati personali dei contatti per scopi di marketing. Al fine di fornire contenuti mirati e pertinenti ai potenziali clienti, SmartResQ/CorPatch® costruisce un profilo di interessi basato sull'attività dell'utente e sulle sue scelte e azioni sulle pagine di SmartResQ/CorPatch®, nonché sulla sua risposta ai contenuti di marketing. La base giuridica di questo trattamento è principalmente il vostro consenso.

\n\n

Informazioni di chi cerca lavoro

\n\n

Se ha fatto domanda per lavorare presso di noi, tratteremo i suoi dati personali al fine di valutare il suo potenziale come dipendente SmartResQ/CorPatch®. La nostra piattaforma di offerta lavori online, sicura e protetta, garantisce il rispetto delle più recenti leggi e normative in materia di privacy dei dati. La base giuridica di questo trattamento è il vostro consenso.

\n\n

Informazioni dei visitatori del sito web

\n\n

Per monitorare l'accesso ai nostri siti, trattiamo i dati personali dei visitatori. Il trattamento si basa sul nostro legittimo interesse a proteggere i nostri segreti aziendali, i nostri dipendenti, le nostre sedi e i visitatori. L'utente sarà informato dei suoi diritti in questo contesto al momento della registrazione nel nostro sistema elettronico per i visitatori.

\n\n

Per migliorare la qualità della RCP, in particolare attraverso la formazione sulla RCP, SmartResQ/CorPatch® potrebbe condividere i dati con le nostre società partner (Training Institute) affinché possano offrire i loro prodotti e servizi.

\n\n

Durante l'elaborazione dell'ordine, il nostro sistema può inviare i dati dell'utente alle agenzie di riferimento creditizio e utilizzare le informazioni che ne derivano per prevenire acquisti fraudolenti.

\n\n
\n\n\n
\n

Come conserviamo i dati personali

\n\n

SmartResQ/CorPatch® prende molto sul serio la fiducia che voi e i nostri clienti ci dimostrate. SmartResQ/CorPatch® si impegna a evitare l'accesso non autorizzato, la divulgazione o altri trattamenti aberranti dei dati personali. SmartResQ/CorPatch® garantirà la riservatezza dei dati personali trattati, ne manterrà l'integrità e ne garantirà l'accessibilità in conformità alle leggi sulla riservatezza applicabili.

\n\n

Nell'ambito dei nostri impegni, adottiamo procedure e misure organizzative tecniche e fisiche ragionevoli e adeguate per proteggere le informazioni che raccogliamo ed elaboriamo. Tenendo conto del tipo di dati personali e del rischio a cui i nostri clienti sono esposti da eventuali violazioni della sicurezza, poiché è molto probabile che le cause delle violazioni dei dati personali siano da ricercare internamente, riteniamo importante la costruzione di una solida cultura aziendale in cui il rispetto e la vigilanza sulla protezione dei dati tra i nostri dipendenti sia fondamentale per garantire il trattamento legale e la protezione dei dati. In caso di violazione dei dati, SmartResQ/CorPatch® seguirà le pratiche stabilite dalla Datatilsynet danese.

\n\n

Le sue informazioni sono conservate in modo sicuro in conformità le norme GDPR.

\n \n
\n\n\n
\n

Per quanto tempo conserviamo i dati personali?

\n\n

SmartResQ/CorPatch® conserva i dati personali dell'utente solo per il tempo necessario a raggiungere gli scopi indicati, tenendo conto della necessità di rispondere alle richieste e risolvere i problemi, nonché di ottemperare ai requisiti legali previsti dalla normativa vigente.

\n\n

Ciò significa che SmartResQ/CorPatch® può conservare i dati personali per un periodo ragionevole dopo l'ultima interazione con noi da parte vostra e dei nostri clienti. Quando i dati personali raccolti non sono più necessari, li cancelliamo. Possiamo trattare i dati a fini statistici e/o scientifici, ma in tal caso i dati saranno pseudonimizzati o anonimizzati.

\n\n \n \n\n

Tempi di archiviazione dei dati

\n\n

Conserveremo le informazioni personali dell'utente per il periodo necessario ad adempiere agli scopi delineati nella presente Informativa sulla Privacy, a meno che un periodo di conservazione più lungo sia richiesto o consentito dalla legge, per motivi legali, fiscali o normativi, o per altri scopi commerciali legittimi e leciti.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Scopo Periodo di tempo
Servizio clienti e normativa contabile Cinque anni o finché siamo obbligati a soddisfare i requisiti legali necessari. \n
\n \nI dati di registrazione vengono cancellati non appena l'utente cancella il proprio account o quando scade il periodo di conservazione previsto dalla legge. \n
Piattaforma di offerta lavori Sei mesi per i documenti di candidatura che non comportano l'assunzione del candidato. \n
\n \n\nRinnovo ogni sei mesi se si desidera essere presi/e in considerazione per future offerte di lavoro e si acconsente a un periodo di conservazione più lungo. \n
A scopo di marketing Tre anni dopo l'ultima attività, ad esempio la visita ai nostri siti web, l'acquisto o la partecipazione a una comunicazione. \n
\n \nSe è stato dato il consenso al marketing (e-mail, SMS, telefono ecc.) e finché abbiamo il permesso di contattarvi. \n
\n\nCancelliamo automaticamente l'indirizzo e-mail nella newsletter, una volta cancellato il proprio account utente o all'annullamento dell'iscrizione alla nostra newsletter. \n
Memorizzazione della cronologia degli ordini e degli obblighi di evasione degli stessi Cinque anni o finché siamo obbligati a soddisfare i requisiti legali necessari
Esperienza del cliente Tre anni dopo l'ultima attività, ad esempio la visita ai nostri siti web, l'acquisto o la partecipazione a una comunicazione.\n
\n \nSe è stato dato il consenso al marketing (e-mail, SMS, telefono ecc.) e finché abbiamo il permesso. \n
Frode e valutazione del rischio Cinque anni o finché siamo obbligati a soddisfare i requisiti legali necessari.
\n\n
\n\n\n
\n

Comunicazioni di marketing

\n\n

L'utente ha il diritto di rinunciare a ricevere comunicazioni di marketing da SmartResQ/CorPatch® e può farlo in due modi:

\n
    \n
  • seguendo le istruzioni di opt-out contenute nelle comunicazioni di marketing pertinenti,
  • \n\n
  • modificando le preferenze nella sezione di modifica relativa all'account, se si dispone di un account con SmartResQ/CorPatch®,
  • \n\n
  • contattandoci via e-mail all'indirizzo info@corpatch.com.
  • \n
\n\n

Si prega di notare che, anche se si sceglie di non ricevere comunicazioni di marketing, si possono comunque ricevere messaggi amministrativi da SmartResQ/CorPatch®, come conferme d'ordine e avvisi necessari per la gestione del proprio account o dei servizi forniti ai nostri clienti tramite, ad esempio, servizi mobili o app.

\n\n
\n\n\n
\n

Diritti sulla protezione dei dati

\n\n

Per SmartResQ/CorPatch® è importante che l'utente sia pienamente consapevole di tutti i suoi diritti in materia di protezione dei dati.

\n\n

Alcune leggi sulla protezione dei dati, tra cui il Regolamento generale sulla protezione dei dati (RGDP) dell'Unione Europea, la legislazione corrispondente in Germania Bundesdatenschutzgesetz (BDSG), in Svizzera e nel Regno Unito, e alcune leggi statali statunitensi, forniscono all'utente alcuni diritti in relazione ai dati personali condivisi con noi. Se si risiede nello Spazio Economico Europeo, è possibile godere dei seguenti diritti:

\n
    \n
  1. Diritto di accesso: l'utente ha il diritto di chiederci copia delle sue informazioni personali.
  2. \n\n
  3. Diritto di rettifica: l'utente ha il diritto di richiedere la rettifica delle informazioni personali che ritiene inesatte. L'utente ha inoltre il diritto di richiedere il completamento delle informazioni che ritiene incomplete.
  4. \n\n
  5. Diritto alla cancellazione: l'utente ha il diritto di richiedere la cancellazione dei propri dati personali a determinate condizioni.
  6. \n\n
  7. Diritto di limitare il trattamento: l'utente ha il diritto di chiederci di limitare il trattamento delle informazioni personali a determinate condizioni.
  8. \n\n
  9. Diritto di opposizione al trattamento: l'utente ha il diritto di opporsi al trattamento dei dati personali a determinate condizioni.
  10. \n\n
  11. Diritto alla portabilità dei dati: l'utente ha il diritto di richiedere il trasferimento delle informazioni personali da noi raccolte a un'altra organizzazione o direttamente a lui, a determinate condizioni.
  12. \n
\n\n

Se si desidera esercitare uno di questi diritti, contattare l'indirizzo e-mail: info@corpatch.com.

\n\n
\n\n\n
\n

Cosa sono i cookie?

\n\n

I cookie sono piccoli file di testo che contengono una stringa di caratteri e creano un identificatore unico per un utente. Vengono restituiti al sito web e/o a terzi. La maggior parte dei browser è inizialmente impostata per accettare i cookie, in quanto la maggior parte dei siti web è obbligata ad accedervi. Tuttavia, è possibile modificare le impostazioni del browser in modo da poter generalmente rifiutare i cookie, bloccare i cookie di terzi o specificare quando un cookie viene inviato.

\n

SmartResQ/CorPatch® si impegna a garantire il diritto di regolare i propri interessi e di gestire l'ambito del marketing digitale da parte nostra attraverso un sistema di gestione preferenziale.

\n\n
\n\n\n
\n

Come usiamo i cookie

\n\n

SmartResQ/CorPatch® utilizza i cookie in diversi modi per migliorare la vostra esperienza sui nostri siti web, app e servizi per diversi motivi, ad esempio:

\n
    \n
  • Funzionalità: utilizziamo questi cookie per riconoscere l'utente sul nostro sito web e ricordare le preferenze selezionate in precedenza. Tra questi, la lingua preferita e la località in cui ci si trova. Viene utilizzato un mix di cookie di prima parte e di terze parti.
  • \n\n
  • Pubblicità: utilizziamo questi cookie per raccogliere informazioni sulla visita ai nostri siti web, alle nostre app, sui contenuti visualizzati, sui link seguiti e sulle informazioni relative al browser, al dispositivo e all'indirizzo IP. A volte condividiamo alcuni aspetti limitati di questi dati con terze parti per scopi pubblicitari. Possiamo anche condividere i dati online raccolti attraverso i cookie con i nostri partner pubblicitari. Ciò significa che quando visitate un altro sito web, potreste ricevere pubblicità basata sulle vostre abitudini di navigazione sul nostro sito.
  • \n
\n\n
\n\n\n
\n

I tipi di cookie che usiamo

\n\n

I nostri siti web utilizzano i seguenti tipi di cookie:

\n
    \n
  • Google Analytics: Questo cookie ci consente di visualizzare informazioni sulle attività del sito web degli utenti, tra cui, a titolo esemplificativo ma non esaustivo, le visualizzazioni di pagina, la fonte e il tempo trascorso su un sito web. Le informazioni sono anonime e vengono visualizzate come numeri, il che significa che non possono essere ricondotte a singoli individui. In questo modo, si contribuisce a proteggere la privacy. Utilizzando Google Analytics, possiamo vedere quali sono i contenuti più popolari sulle nostre pagine e cerchiamo di offrire sempre di più ciò che piace leggere e vedere agli utenti. \n\n
  • Google Analytics remarketing: Inserisce dei cookie nel computer, il che significa che quando si lascia il nostro sito, Google potrebbe mostrare annunci pubblicitari su SmartResQ/CorPatch® che potrebbero interessare in base ai propri precedenti comportamenti sul nostro sito web. Queste informazioni non sono identificabili personalmente. \n\n
  • Google Ads: Utilizzando Google Ads, possiamo vedere quali pagine sono state utili per ottenere l'invio del modulo di contatto. Queste informazioni non sono identificabili personalmente, mentre lo sono i dati forniti nel modulo di contatto. \n\n
  • Google Ads remarketing: Inserisce dei cookie nel computer, il che significa che quando si lascia il nostro sito, Google potrebbe mostrare annunci pubblicitari su SmartResQ/CorPatch® che potrebbero interessare in base ai propri precedenti comportamenti sul nostro sito web. Queste informazioni non sono identificabili personalmente. \n\n
  • Facebook Remarketing: Il pixel di tracciamento di Facebook inserisce dei cookie nel computer dell'utente che indicano a Facebook che l'utente ha visitato il sito. Si presume quindi che l'utente sia interessato a SmartResQ/CorPatch® e ai contenuti di questo sito. Quando si visita Facebook, saranno esposte informazioni o pubblicità con contenuti simili. Utilizzare le impostazioni sulla privacy di Facebook per limitare l'esposizione a questo tipo di marketing. \n\n
  • YouTube: Integriamo i video dalla piattaforma YouTube fornita da Google (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA). Informativa sulla privacy: https://www.google.com/policies/privacy/.
  • \n
\n \n
\n\n\n
\n

Come gestire i cookie

\n\n

È possibile impostare il proprio browser in modo da non accettare o eliminare i cookie. Tuttavia, alcune funzionalità del nostro sito web potrebbero non funzionare di conseguenza. Ecco come evitare i cookie in browser specifici:

\n\n \n\n

SmartResQ/CorPatch® utilizza alcuni servizi di terze parti affidabili sulle nostre pagine. Questi servizi potrebbero utilizzare dei cookie. È possibile scegliere di rifiutare i cookie di terze parti nel browser seguendo questo link.

\n\n

È possibile impedire che le informazioni generate dal cookie di Google sull'utilizzo dei nostri siti vengano raccolte ed elaborate da Google scaricando e installando il componente aggiuntivo del browser Google Analytics Opt-out per il browser web utilizzato. Questo componente aggiuntivo è disponibile qui.

\n\n
\n\n\n
\n

Politiche sulla privacy di altri siti

\n\n

I siti web SmartResQ/CorPatch® contengono link ad altri siti web. La nostra politica sulla privacy si applica solo al nostro sito web, quindi se si clicca su un link a un altro sito web, è necessario leggere la loro politica sulla privacy.

\n\n
\n\n\n
\n

Modifiche alla nostra informativa sulla privacy

\n\n

Se modifichiamo la nostra informativa sulla privacy, pubblicheremo qui l'informativa modificata con la data di revisione aggiornata. Vi invitiamo a verificare regolarmente l’informativa. Se apportiamo modifiche sostanziali all’informativa che cambiano in modo significativo le nostre pratiche in materia di privacy, possiamo anche informarvi in altri modi, ad esempio inviando un'e-mail o pubblicando un avviso sul nostro sito web e/o sui social media prima che le modifiche entrino in vigore.

\n\n
\n\n\n
\n

Come contattare SmartResQ ApS

\n\n

In caso di domande sull’informativa sulla privacy di SmartResQ/CorPatch®, sui dati in nostro possesso o se desiderate esercitare uno dei vostri diritti di protezione dei dati, non esitate a contattarci.

\n\n

E-mail: info@corpatch.com

\n\n

Sito web: https://corpatch.com

\n\n
\n\n\n
\n\n

Come contattare l'autorità competente

\n\n

Se si desidera presentare un reclamo o se si ritiene che SmartResQ/CorPatch® non abbia affrontato il problema in modo soddisfacente, è possibile contattare l'Ufficio del responsabile per l'informazione (ICO).

\n\n

L'indirizzo dell'ICO è: \n

\nInformation Commissioner's Office \n
\nWycliffe House \n
\nWater Lane \n
\nWilmslow \n
\nCheshire \n
\nSK9 5AF

\n \n\n

Numero dedicato: +44 303 123 1113

\n\n

Sito web dell'ICO: https://www.ico.org.uk

\n\n

© SmartResQ ApS – Tutti i diritti riservati \n
\nDanimarca, Versione 1.3 – Pubblicato il 25.04.2023

\n\n
\n\n
\n\n`\n\nexport const termsOfUse_es_ES: string = `\n\n\n \n \n \n Combined Document: T&C 2.1 and PP 1.3\n\n \n\n\n\n\n
\n\n \n\n \n
\n

Términos y Condiciones & Política de Privacidad

\n

SmartResQ ApS / CorPatch®

\n
\n\n
\n

Condiciones generales de contrato – SmartResQ ApS / CorPatch®

\n\n

Objeto del presente documento

\n\n

¡Bienvenido a SmartResQ/CorPatch®!

\n\n\n\n

Actualmente está leyendo nuestros Términos y Condiciones; un documento con información sobre su relación\ncon SmartResQ ApS, que comenzó cuando entró en nuestro sitio web, descargó nuestra(s) app(s) gratuita(s),\ncompró uno de nuestros productos o similar.

\n\n\n\n

SmartResQ/CorPatch® y nuestros asociados le proporcionamos nuestros productos y servicios sujetos a las\nsiguientes condiciones. Si visita o compra en nuestro(s) sitio(s) web o aplicación(es), usted acepta estas\ncondiciones. Le recomendamos encarecidamente que las lea detenidamente antes de utilizar nuestros productos\no servicios.

\n\n\n\n

Este documento abarca:

\n
    \n
  • Cómo ponerse en contacto con SmartResQ
  • \n\n
  • Productos, propiedades y uso adecuado
  • \n\n
  • Renuncias y garantías
  • \n\n
  • Pedidos
  • \n\n
  • Pago
  • \n\n
  • Entrega
  • \n\n
  • Responsabilidades y derechos relacionados con la venta
  • \n\n
  • Devolución
  • \n\n
  • Tratamiento de datos personales
  • \n\n
  • Reclamación
  • \n\n
  • Cambios en este documento
  • \n\n
  • Derecho y jurisdicción
  • \n\n
  • Información de contacto
  • \n\n\n
\n

Si tiene alguna pregunta en relación con los Términos y Condiciones de SmartResQ, póngase en contacto con\nnosotros.

\n\n\n\n

Cómo ponerse en contacto con SmartResQ

\n\n

En SmartResQ pretendemos aumentar la supervivencia mediante una RCP de calidad en caso de parada cardiaca.\nQueremos preparar y guiar a los transeúntes para que actúen desde los primeros minutos cruciales tras\npresenciar una parada cardiaca. Por ello, hemos desarrollado CorPatch® – Le ayudamos a salvar una vida.

\n\n\n\n

Nuestra empresa se encuentra en Lundevej 26, 5700 Svendborg, Dinamarca

\n\n\n\n

Puede encontrarnos en el Registro Mercantil Central con el número de IVA DK 38674102

\n\n\n\n

Puede llamarnos al número de teléfono +45 62 200 100

\n\n\n\n

o

\n\n\n\n

envíenos un correo electrónico a info@corpatch.com.

\n\n\n\n

¿Alguna pregunta, comentario o reclamación?

\n\n

Agradecemos su opinión, así que póngase en contacto con nosotros a través de la información de contacto\nmencionada anteriormente o utilice el formulario de contacto de nuestro(s) sitio(s) web o app(s).

\n\n\n
\n\n\n
\n

Productos, propiedades y uso adecuado

\n\n

Nuestros sitios web, aplicaciones y productos

\n\n

Los siguientes párrafos describen las propiedades, derechos y responsabilidades esenciales relacionados con el\nuso de los servicios, aplicaciones y productos SmartResQ/CorPatch®.\n
\nHacemos todos los esfuerzos razonables para incluir información precisa y actualizada en los sitios web y en las\naplicaciones. Sin embargo, SmartResQ/CorPatch® no garantiza la exactitud de la información. No asumimos\nninguna responsabilidad por cualquier error u omisión en el contenido del sitio web, productos y aplicaciones.\nLa información proporcionada en este sitio web o en las aplicaciones no sustituye la atención médica. Asumimos\nla responsabilidad de nuestros productos y aplicaciones de acuerdo con la Directiva de Productos Sanitarios UE\n745/2017 (MDR).

\n\n\n\n

Copyright

\n\n

ATodo el contenido incluido en este sitio, como texto, gráficos, logotipos, iconos de botones, imágenes, clips de\naudio, descargas digitales, compilaciones de datos y software, es propiedad de SmartResQ/CorPatch® o de sus\nproveedores de contenido y está protegido por las leyes internacionales de derechos de autor. La compilación\nde todo el contenido de este sitio es propiedad exclusiva de SmartResQ/CorPatch®, con derechos de autor para\nesta colección por SmartResQ/CorPatch® y protegido por leyes internacionales de derechos de autor.

\n\n\n\n

Marcas y diseños registrados

\n\n

Las marcas registradas SmartResQ/CorPatch®, la imagen comercial y el diseño del producto no pueden ser\nusados en conexión con ningún producto o servicio que no sea SmartResQ/CorPatch®, de ninguna manera que\npueda causar confusión entre los clientes, o de ninguna manera que menosprecie o desacredite a\nSmartResQ/CorPatch®. Todas las demás marcas comerciales que no son propiedad de SmartResQ/CorPatch® o\nsus subsidiarias que aparecen en este sitio son propiedad de sus respectivos dueños, quienes pueden o no estar\nafiliados, conectados o patrocinados por SmartResQ/CorPatch® o sus subsidiarias.

\n\n\n\n

Licencia y acceso al sitio

\n\n

SmartResQ/CorPatch® le concede una licencia limitada para acceder y hacer uso personal de nuestro(s) sitio(s) y\naplicaciones y no para descargar (excepto el almacenamiento en caché de páginas) o modificarlo o cualquier\nparte del mismo, excepto con el consentimiento expreso por escrito de SmartResQ/CorPatch®. Esta licencia no\nincluye ninguna reventa o uso comercial de este sitio(s) o aplicaciones o su contenido: (a) cualquier recopilación\ny uso de cualquier listado de productos, descripciones o precios: (b) cualquier uso derivado de este sitio o sus\ncontenidos: (c) cualquier descarga o copia de información de la cuenta en beneficio de otro comerciante: o (d)\ncualquier uso de minería de datos, robots o herramientas similares de recopilación y extracción de datos.

\n\n\n\n

Este sitio o aplicación o cualquier parte de este sitio no puede ser reproducido, rediseñado, duplicado, copiado,\nvendido, revendido, visitado o explotado para cualquier propósito comercial sin el consentimiento expreso y por\nescrito de SmartResQ/CorPatch®. Usted no puede enmarcar o utilizar técnicas de enmarcado para adjuntar\ncualquier marca registrada, logotipo u otra información de propiedad (incluyendo imágenes, texto, diseño de\npágina o forma) de SmartResQ/CorPatch® y nuestros asociados sin el consentimiento expreso por escrito.

\n\n\n\n

Usted no puede utilizar ninguna etiqueta meta o cualquier otro “texto oculto” utilizando el nombre\nSmartResQ/CorPatch® o marcas registradas sin el consentimiento expreso y por escrito de\nSmartResQ/CorPatch®. Cualquier uso no autorizado termina el permiso o licencia concedida por\nSmartResQ/CorPatch®.

\n\n\n\n

Se le concede un derecho limitado, revocable y no exclusivo para crear un hipervínculo a la página principal de\nSmartResQ/CorPatch® siempre y cuando el enlace no represente a SmartResQ/CorPatch®, sus asociados o sus\nproductos o servicios de manera falsa, engañosa, despectiva u ofensiva. Usted no puede utilizar ningún logotipo\nSmartResQ/CorPatch® u otro gráfico o marca registrada como parte del enlace sin permiso expreso por escrito.\n
\nSi se incumple el acuerdo sobre la licencia y el acceso al sitio, se emprenderán acciones legales y se podrá\npresentar una demanda ante los tribunales.

\n\n

Comunicación electrónica

\n\n

Cuando visita la página de inicio y los canales de medios sociales de SmartResQ/CorPatch® o nos envía correos\nelectrónicos, se está comunicando con nosotros electrónicamente. Usted da su consentimiento para recibir\nnuestras comunicaciones electrónicamente. Nos comunicaremos con usted por correo electrónico o mediante\nla publicación de avisos en nuestros sitios web o en las aplicaciones en forma de ventanas emergentes o\nnotificaciones. Usted acepta que todos los acuerdos, avisos, divulgaciones y otras comunicaciones que le\nproporcionemos electrónicamente satisfacen cualquier requisito legal de que dichas comunicaciones se realicen\npor escrito. Consulte nuestra política de privacidad en un documento aparte que puede encontrar en nuestra\npágina de inicio.

\n\n\n\n

Los visitantes de nuestro sitio web y canales de redes sociales pueden ser invitados a publicar reseñas,\ncomentarios y otros contenidos, por ejemplo, sugerencias, ideas, comentarios, preguntas u otra información,\nsiempre que el contenido no sea ilegal, obsceno, amenazador, difamatorio, invasivo de la privacidad, infractor\nde los derechos de propiedad intelectual, o de otro modo perjudicial para terceros o censurable y no consista en\no contenga virus de software, campañas políticas, solicitudes comerciales, cartas en cadena, correos masivos, o\ncualquier forma de “spam”.

\n\n\n\n

Usted no puede utilizar una dirección de correo electrónico falsa, hacerse pasar por cualquier persona o entidad,\no inducir a error sobre el origen de una tarjeta u otro contenido. SmartResQ/CorPatch® se reserva el derecho\n(pero no la obligación) de eliminar o editar dicho contenido, pero no revisa regularmente el contenido publicado.\nSi publica contenido o envía material y a menos que indiquemos lo contrario, usted otorga a\nSmartResQ/CorPatch® y sus asociados un derecho no exclusivo, libre de regalías, perpetuo, irrevocable y\ntotalmente sublicenciable para usar, reproducir, modificar, adaptar, publicar, traducir, crear trabajos derivados,\ndistribuir y mostrar dicho contenido en todo el mundo en cualquier medio. Usted otorga a SmartResQ/CorPatch®\ny sus asociados y sublicenciatarios el derecho a utilizar el nombre que usted envíe en relación con dicho\ncontenido si así lo desean.

\n\n\n\n

Usted declara y garantiza que posee o controla todos los derechos sobre el contenido que usted publica; que el\ncontenido es exacto; que el uso del contenido que usted suministra no viola esta política y no causará daño a\nninguna persona o entidad; y que indemnizará a SmartResQ/CorPatch® o sus asociados por todas las\nreclamaciones resultantes del contenido que usted suministra. SmartResQ/CorPatch® tiene el derecho pero no\nla obligación de supervisar y editar o eliminar cualquier actividad o contenido. SmartResQ/CorPatch® no se hace\nresponsable y no asume ninguna responsabilidad por cualquier contenido publicado por usted o cualquier\ntercero.

\n\n\n
\n\n
\n

Renuncias y garantías

\n\n

Información del producto – CorPatch® y CorPatch® Trainer

\n\n

Para el uso correcto de cualquier producto o servicio SmartResQ/CorPatch® debe seguir siempre las últimas guías\nde usuario, instrucciones y descripciones. Puede encontrarlas en nuestro sitio web y en la descripción de cada\nproducto.

\n\n\n\n

El producto CorPatch® está certificado como dispositivo médico. En caso de emergencia con una persona adulta\nque sufra un paro cardíaco, el producto debe sacarse de su caja, colocarse y fijarse correctamente en el pecho\nde la víctima. El producto puede recoger datos sobre compresión, profundidad, frecuencia y descompresión, y\npodría transmitirlos por Bluetooth® a posibles dispositivos. Las aplicaciones gratuitas de los dispositivos pueden\nguiar al transeúnte en el ejercicio de la RCP y mostrar la ratio de compresiones torácicas, la profundidad, la\ndescompresión y la frecuencia si están activadas y correctamente instaladas, es decir, Bluetooth®, smartphone,\naplicación, batería, etc. SmartResQ/CorPatch® no se hace responsable de factores externos, por ejemplo, señales\nde comunicación interferentes, falta de cobertura de datos, falta de batería, hardware incorrecto o ajustes de\nsoftware, que puedan afectar a la experiencia del usuario o similares.

\n\n\n\n

Del mismo modo, SmartResQ/CorPatch® no se hace responsable de ningún daño físico causado durante el uso\ndel producto en caso de que no se aplique o utilice de acuerdo con las instrucciones, por ejemplo, realizando las\ncompresiones torácicas de forma no ergonómica o teniendo una posición inadecuada de las manos.\nSmartResQ/CorPatch® ha evaluado los riesgos técnicos como parte de la gestión de riesgos legalmente prescrita\npara los productos sanitarios, pero no se ofrece ninguna garantía por errores que vayan más allá. En caso de mal\nfuncionamiento inesperado o de comportamiento no plausible de un sistema SmartResQ/CorPatch®, el usuario\ndeberá realizar la RCP manualmente. En este caso, SmartResQ/CorPatch® no se hace responsable, ya que está\nfuera del control de SmartResQ/CorPatch®.

\n\n

SmartResQ/CorPatch® controla los niveles de batería y el estado de salud, pero si la batería se agota, el producto\nno funcionará. Es responsabilidad exclusiva del usuario asegurarse de que el dispositivo está actualizado, no sufre\ndaños y tiene batería suficiente para funcionar correctamente, lo que puede hacerse fácilmente realizando un\nentrenamiento que valide su correcto funcionamiento. Recomendamos realizar un entrenamiento de 4 minutos\ncada 3 meses con su CorPatch®.

\n\n\n\n

¡Importante! El producto CorPatch® debe utilizarse exclusivamente en una persona en una situación real y sólo si\nla persona sufre un paro cardíaco. No está destinado a ser utilizado en personas que sufran, por ejemplo, un\nderrame cerebral, un infarto de miocardio u otras enfermedades relacionadas con la salud que no sean un paro\ncardíaco. El CorPatch® no está diseñado para utilizarse si la persona está tumbada sobre una superficie blanda,\npor ejemplo, un sofá o una cama, ya que la respuesta de profundidad en tales condiciones podría ser imprecisa.\nLas soluciones SmartResQ/CorPatch® no están diseñadas para su uso en un entorno en movimiento, incluyendo,\nentre otros, una ambulancia aérea, marítima o de carretera. Si se utiliza durante el transporte del paciente o se\nlevanta/se retira del cuerpo durante la RCP, el dispositivo puede proporcionar una información inexacta. El\nCorPatch® debe fijarse al tórax del paciente con el parche. Asegúrese de que el paciente esté tumbado sobre una\nsuperficie firme, plana y que no se mueva y de que el CorPatch® esté sujeto al tórax con el parche.

\n\n\n\n

El producto CorPatch® Trainer debe utilizarse exclusivamente en maniquíes u objetos similares en sesiones de\nformación y nunca en una situación real en una persona real que sufra una parada cardiaca o cualquier otra\nenfermedad relacionada con la salud.

\n\n\n\n

Es posible entrenar su rendimiento en RCP en relación con las compresiones torácicas utilizando CorPatch®️ o\nCorPatch®️ Trainer con regularidad. Le recomendamos que entrene con un maniquí, pero si no tiene acceso a un\nmaniquí, puede utilizar como sustituto una silla de oficina con suficiente retroceso o un sofá duro. Tenga en\ncuenta la elasticidad y dureza del objeto con el que entrena. SmartResQ no recomienda el uso de objetos blandos,\nincluyendo pero no limitado a almohadas o sofás blandos cuando se entrena, ya que la experiencia del usuario\nno será la correcta.

\n\n\n

Si no puede localizar un maniquí o un objeto de sustitución para el entrenamiento, considere la posibilidad de\nentrenar la situación que se produce antes de iniciar las compresiones torácicas. Esto podría consistir en seguir\nla información proporcionada por la aplicación gratuita sobre la identificación de una parada cardiaca y la llamada\na los servicios de emergencia y desembalar el CorPatch® del colgador de llaves. En este caso, estará preparado\npara aplicar rápidamente el CorPatch® en caso de presenciar una parada cardiaca.

\n\n\n\n

No utilice ningún sistema SmartResQ/CorPatch®️ para entrenar o “por diversión” con personas (vivas o muertas),\nmascotas o cualquier otro ser humano o criatura viva.

\n\n\n\n

Descargo de responsabilidad sobre productos, sitios web y aplicaciones

\n\n

SmartResQ/CorPatch® no hace representaciones o garantías y no será responsable de la competencia de\ncualquier persona que pueda recibir información educativa y / o formación médica proporcionada a través de o\nbasado en el sistema o para el ejercicio de sus habilidades por dicha persona después de la finalización de\ncualquier formación, cursos o planes de estudio utilizando el sistema. SmartResQ/CorPatch® no garantiza que\ncualquier persona que reciba información educativa y/o formación médica del sistema alcanzará cualquier nivel\nde habilidad particular o la competencia necesaria para calificar para cualquier licencia, certificados o\ncalificaciones emitidas por cualquier agencia reguladora o autoridad gubernamental.

\n\n\n\n

SmartResQ/CorPatch® y sus asociados intentan ser lo más precisos posible. Sin embargo, SmartResQ/CorPatch®\nno declara ni garantiza que el sistema y la información, los productos y la formación que en él se ofrecen (a)\nestén siempre disponibles o disponibles en absoluto; o (b) estén libres de errores, sean completos, exactos,\nverdaderos, actualizados y/o no engañosos. Al utilizar el sistema, usted sabe y es consciente de que renuncia a\ncualquier reclamación que pueda tener contra SmartResQ/CorPatch® por confiar en cualquier información o\nformación presentada a través del sistema.

\n\n\n\n

Nuestros productos no están destinados al uso infantil. Los productos son pequeños y coloridos y pueden\nconfundirse con juguetes, pero los productos SmartResQ/CorPatch® no son juguetes. Recomendamos no dejar\nlos productos al aire libre y al alcance de los niños. SmartResQ/CorPatch® no asume ninguna responsabilidad en\nrelación con el uso de los productos por parte de los niños. Cualquier uso de CorPatch® por parte de niños o\nadolescentes debe ser permitido y supervisado por adultos responsables, por ejemplo, padres, familiares o\nprofesores.

\n\n\n\n

Renuncia de garantías y limitación de responsabilidad, este sitio es proporcionado por SmartResQ/CorPatch® “tal\ncual” y “según disponibilidad”. SmartResQ/CorPatch® no hace representaciones o garantías de ningún tipo,\nexpresa o implícita, en cuanto a la operación de este sitio o la información, contenido, materiales o productos\nincluidos en este sitio. Usted acepta expresamente que el uso de este sitio es bajo su propio riesgo\n
\nEn la medida permitida por la ley aplicable, SmartResQ/CorPatch® renuncia a todas las garantías, expresas o\nimplícitas, incluyendo, pero no limitado a, las garantías implícitas de comerciabilidad e idoneidad para un\npropósito particular. SmartResQ/CorPatch® no garantiza que este sitio, sus servidores o el correo electrónico\nenviado desde SmartResQ/CorPatch® estén libres de virus/spam u otros componentes dañinos.

\n\n\n\n

SmartResQ/CorPatch® no será responsable de ningún daño de cualquier tipo que surja del uso de este sitio o sus\nproductos, incluyendo, pero no limitado a daños directos, indirectos, incidentales, punitivos y consecuentes.\n
\nLa legislación de algunos estados no permite la limitación de las garantías implícitas ni la exclusión o limitación\nde determinados daños. Si estas leyes son de aplicación en su caso, es posible que algunas o todas las renuncias,\nexclusiones o limitaciones anteriores no se apliquen en su caso, y podría tener derechos adicionales.

\n\n\n\n

La información presentada en este sitio web no debe interpretarse como asesoramiento profesional. Antes de\ntomar una decisión, consulte siempre a asesores profesionales que conozcan su situación concreta.

\n\n\n\n

El sitio web puede contener enlaces que conducen a sitios web mantenidos por personas u organizaciones sobre\nlas que SmartResQ/CorPatch® no tiene ningún control. SmartResQ/CorPatch® no hace ninguna representación y\nno ofrece ninguna garantía con respecto a la exactitud o cualquier otro aspecto de la información contenida en\ndichos sitios web.

\n\n\n\n

La responsabilidad de cualquier opinión, consejo, declaración u otra información contenida en cualquier artículo\no texto de este sitio web es exclusivamente del autor y no refleja necesariamente las opiniones y políticas de\nSmartResQ/CorPatch®.

\n\n\n\n

Aviso legal

\n\n

Al comprar, obtener licencias, ver, utilizar y/o acceder a nuestro(s) sitio(s) web, productos y aplicaciones, usted\nreconoce y acepta que:

\n
    \n
  1. Los sistemas proporcionados por SmartResQ/CorPatch® son productos específicos que deben\nutilizarse únicamente para el uso previsto indicado en el manual del producto. Lea atentamente las\ninstrucciones de uso y los manuales, y asegúrese de estar familiarizado con nuestros productos\nmédicos antes de utilizarlos.
  2. \n\n
  3. Los sistemas proporcionados por SmartResQ/CorPatch® son productos y herramientas educativos y\nde formación médica específicos, no están certificados como productos sanitarios a menos que se\nindique explícitamente, no están destinados a ningún uso clínico o de diagnóstico y están pensados\npara ser utilizados únicamente con fines de formación médica y mejora del rendimiento.
  4. \n\n
  5. En todo momento, usted utilizará y accederá al sistema únicamente en relación con dichos fines de\nformación médica y mejora del rendimiento; en cumplimiento de todas las leyes y normativas\naplicables; y de acuerdo con cualquier documentación de usuario, manual de instrucciones, guía y/o\nrequisito que le proporcionemos por vía electrónica o en persona.
  6. \n\n
  7. En ningún momento cualquier sistema SmartResQ/CorPatch® por sí solo puede diagnosticar, tratar o\ncurar la condición de un ser humano o en una situación de salvar la vida; apoyar las decisiones\nmédicas profesionales, diagnósticos o tratamientos o reemplazar cualquier diagnóstico,\nrecomendación, consejo, tratamiento o decisión de un médico debidamente capacitado y licenciado.
  8. \n\n
  9. La asociación de un producto con cualquier daño o resultado en un paciente no significa que el\nproducto haya causado el daño o el resultado.
  10. \n\n
  11. SmartResQ/CorPatch® no se hace responsable de los daños resultantes de un uso no razonable de\nnuestros productos o de un uso que exceda el uso previsto del producto.
  12. \n\n\n
\n

Información de rendimiento

\n\n

La información aquí contenida se presenta únicamente como guía para la aplicación de los productos\nSmartResQ/CorPatch®. SmartResQ/CorPatch® trabaja continuamente para mejorar la calidad y fiabilidad de sus\nproductos. No obstante, nuestros dispositivos pueden funcionar mal o fallar debido a su inherente sensibilidad\neléctrica y vulnerabilidad al estrés físico y a señales de comunicación adversas. Es responsabilidad del comprador,\nal utilizar productos SmartResQ/CorPatch®, observar las normas de seguridad y pruebas y evitar situaciones en\nlas que un mal funcionamiento o fallo pueda provocar lesiones corporales o daños materiales.

\n\n\n\n

Garantía estándar

\n\n

La garantía limitada estándar de SmartResQ/CorPatch® está condicionada al uso adecuado de los productos,\nsitios web y aplicaciones.\n
\nEsta Garantía se limita al primer comprador del producto únicamente y sólo si el producto se compra a un\ndistribuidor autorizado de SmartResQ/CorPatch®. Los fabricantes, proveedores o editores, distintos de\nSmartResQ/CorPatch®, pueden proporcionarle sus propias garantías – póngase en contacto con ellos para\nobtener más información.

\n\n\n\n

La garantía no cubre:

\n
    \n
  1. defectos o daños resultantes de accidentes, uso indebido, uso anormal, condiciones anormales,\nalmacenamiento inadecuado, exposición a líquidos, humedad, arena o suciedad, negligencia o\ntensión física, eléctrica o electromecánica inusual,
  2. \n\n
  3. defectos o daños resultantes de una fuerza excesiva o del uso de objetos metálicos,
  4. \n\n
  5. equipos que tengan el número de producción o el código de datos de mejora borrados, desfigurados,\ndañados, alterados o ilegibles,
  6. \n\n
  7. desgaste ordinario o envejecimiento normal del producto,
  8. \n\n
  9. arañazos, abolladuras y daños estéticos, a menos que el fallo se haya producido debido a un defecto\nen los materiales o en la mano de obra,
  10. \n\n
  11. defectos o daños resultantes del uso de los productos en conjunción o conexión con accesorios,\nproductos o equipos auxiliares/periféricos no suministrados o aprobados por SmartResQ/CorPatch®,
  12. \n\n
  13. defectos o daños resultantes de pruebas, operación, mantenimiento, instalación, servicio o ajuste\ninadecuados no suministrados o aprobados por SmartResQ/CorPatch®,
  14. \n\n
  15. daños causados por el funcionamiento del producto SmartResQ/CorPatch® fuera de las directrices\npublicadas,
  16. \n\n
  17. demostración/instalación del producto adquirido,
  18. \n\n
  19. Los defectos o daños resultantes de causas externas como colisión con un objeto, incendio,\ninundación, suciedad, vendaval, rayo, terremoto, exposición a condiciones climatológicas, robo,\nfusible fundido o uso inadecuado de cualquier fuente eléctrica,
  20. \n\n
  21. defectos o daños resultantes de la transmisión o virus, u otros problemas de software introducidos en\nlos Productos,
  22. \n\n
  23. si las baterías se cargan con cargadores que no sean compatibles con CorPatch® Trainer,
  24. \n\n
  25. alguno de los precintos de la caja de la batería o de las celdas está roto o presenta indicios de\nmanipulación,
  26. \n\n
  27. productos reparados por, utilizados o comprados a otra empresa que no sea SmartResQ/CorPatch®,
  28. \n\n
  29. si SmartResQ/CorPatch® recibe información de las autoridades públicas pertinentes de que el\nproducto ha sido robado o si no puede desactivar el código de acceso u otras medidas de seguridad\ndiseñadas para evitar el acceso no autorizado al producto o no puede demostrar que es el usuario\nautorizado del producto,
  30. \n\n
  31. si los productos se utilizan fuera de las condiciones especificadas en los manuales, por ejemplo, rango\nde temperatura, presión y humedad.
  32. \n\n\n
\n

Baterías y cargadores

\n\n

Los productos SmartResQ/CorPatch® contienen pilas no sustituibles (CorPatch®) o pilas recargables (CorPatch®\nTrainer). Los tipos de pilas utilizados en nuestros productos se describen en cada producto individual.\nSmartResQ/CorPatch® no asume ninguna responsabilidad si las pilas recargables no se manipulan correctamente\nde acuerdo con el manual de uso.

\n\n\n\n

En relación con la venta de aparatos que contienen pilas, tenemos la obligación de poner en su conocimiento lo\nsiguiente:\n
\nComo usuario final, tiene la obligación legal de desecharlas correctamente. El símbolo del cubo de basura\ntachado significa que la pila no puede desecharse con la basura doméstica.

\n\n\n
\n \n\t
\n\t

Pedidos

\n\n

La tienda web Corpatch.com está abierta las 24 horas del día y puede comprar prácticamente en cualquier\nmomento. Sin embargo, es posible que cerremos la tienda por mantenimiento. La compra en grandes volúmenes\npuede realizarse directamente con SmartResQ/CorPatch®.

\n\n\n\n

SmartResQ/CorPatch® no ofrece productos para la venta a menores. Los productos destinados a niños sólo\npueden ser comprados por adultos. Para comprar en SmartResQ/CorPatch® debe tener al menos 18 años y\nposeer una tarjeta de crédito válida u otro medio de pago que aceptemos.

\n\n\n\n

La presentación de los productos en la tienda en línea no es una oferta jurídicamente vinculante, sino un catálogo\nen línea no vinculante. Cuando esté listo para comprar, seleccione los artículos que desee e introdúzcalos en la\n “cesta de la compra”. Puede modificar el contenido de la cesta hasta el momento de hacer el pedido. Cualquier\npago adicional, como gastos de envío o de tarjeta de débito, se calculará inmediatamente antes de que pague.

\n\n\n\n

Cuando esté listo para realizar el pedido, haga clic en “Realizar pedido” e introduzca la información pertinente.\nPuede modificar el contenido de la cesta de la compra hasta que confirme su compra haciendo clic en el botón\n“Pagar”. A partir de ese momento, realizará un pedido vinculante de los productos contenidos en la cesta de la\ncompra que ya no podrá modificar.\n
\nSmartResQ/CorPatch® puede aceptar el pedido enviando una confirmación de pedido por correo electrónico o\nentregando la mercancía dentro del plazo de entrega.

\n\n\n\n

Algunos países pueden impedir el uso y la propiedad de nuestros productos. Usted es el único responsable de\naveriguar si este producto puede importarse o utilizarse legalmente en su país. Le enviaremos los productos que\npida y no podemos aceptar ninguna responsabilidad por cuestiones aduaneras o cualquier implicación de su\npropiedad o uso de este dispositivo.

\n\n
\n\n \n
\n

Pago

\n\n

Nuestro(s) sitio(s) web, aplicación(es) y tienda(s) web

\n\n

El uso de nuestro(s) sitio(s) web y aplicación(es) es gratuito siempre que se acepten y cumplan nuestras políticas\nlegales. Tenga en cuenta que las compras de nuestros productos pueden estar disponibles en la(s) tienda(s) web\nde nuestro(s) sitio(s) web y en la(s) aplicación(es).

\n\n\n\n

Nuestros productos

\n\n

SmartResQ/CorPatch® utiliza QuickPay como pasarela de pago. QuickPay está certificada por el Consejo de\nNormas de Seguridad de la Industria de Tarjetas de Pago (PCI) siguiendo la última versión del Nivel 1 de la Norma\nde Seguridad de Datos (DSS) de la PCI, que incluye: (a) un informe anual – “Report on Compliance” (ROC) realizado\npor un Qualified Security Assessor (QSA), (b) escaneos trimestrales de la red realizados por Approved Scan\nVendor (ASV), y (c) un gran número de normas y directrices para el flujo de trabajo y el tratamiento de datos.

\n\n\n\n

Aceptamos pagos por:

\n
    \n
  • VISA
  • \n\n
  • Dankort
  • \n\n
  • MasterCard
  • \n\n
  • MobilePay
  • \n\n
  • PayPal
  • \n\n
  • Apple Pay
  • \n\n
  • Maestro
  • \n
\n\n\n

Los pagos se deducirán de su cuenta en el momento del envío de la mercancía. Todos los importes se expresan\nen euros y el impuesto sobre el valor añadido legal ya está incluido en todos los precios mencionados. Todos los\ntitulares de tarjetas de crédito/débito están sujetos a comprobaciones de validación y autorización por parte del\nemisor de la tarjeta o del proveedor de pago. SmartResQ/CorPatch® no se hace responsable en caso de que el\nproveedor de su tarjeta de pago se niegue a autorizar los pagos.

\n\n\n

Utilizamos el protocolo SSL (Secure Socket Layer) para cifrar la información de las tarjetas de crédito. Esto\ngarantiza que otros no puedan interceptar el número de tarjeta de crédito u otra información durante la\ntransacción con nuestro proveedor.

\n\n\n\n

Antes de finalizar el contrato, el cliente debe revisar y aceptar los gastos de envío y logística añadidos al precio\nde compra, ya que estos gastos corren a su cargo. Después de realizar un pedido, recibirá un correo electrónico\nnuestro acusando recibo de su pedido. Tenga en cuenta que esto no significa que su pedido haya sido aceptado.\nSu pedido constituye una oferta a SmartResQ/CorPatch® para comprar un producto (y SmartResQ/CorPatch® se\nreserva el derecho de rechazar pedidos de productos). No existirá ningún contrato en relación con los productos\nhasta que le hayamos confirmado por correo electrónico que el/los producto(s) ha(n) sido enviado(s). Nuestra\naceptación a su oferta se considerará completa y el contrato entre nosotros se formará cuando le enviemos un\ncorreo de confirmación de envío.

\n\n\n\n

Los gastos de envío se indican siempre en relación con cada pedido individual.

\n\n\n\n

SmartResQ/CorPatch® conserva la propiedad del artículo adquirido hasta que el importe de la factura haya sido\nabonado en su totalidad por el cliente y “retirado” automáticamente justo antes del envío.

\n\n\n\n

Los clientes sólo tienen derecho a compensación si sus contrademandas han sido legalmente establecidas o son\nindiscutibles o reconocidas por SmartResQ/CorPatch®. Además, los clientes solo tienen derecho de retención si\ny en la medida en que su contrademanda se base en la misma relación contractual.

\n\n\n\n

Si el cliente se retrasa en el cumplimiento de sus obligaciones de pago con nosotros, todas las reclamaciones\nexistentes vencerán inmediatamente.

\n\n\n\n

Recargo de tasas

\n\n

A partir del 1 de enero de 2018, se han modificado las normas relativas a los recargos. Por lo tanto, ya no es legal\ncobrar recargos en los pagos con tarjetas de consumidores si son emitidas por bancos o emisores de tarjetas de\nla UE. Esto se aplica tanto a las tarjetas de débito como a las de crédito. Las tarjetas de consumidores son tarjetas\nemitidas a un consumidor privado.

\n\n

Sin embargo, si la tarjeta es una tarjeta de empresa o una tarjeta de consumidor emitida fuera de la UE, la\ncomisión por transacción tendrá un recargo. Esto significa que el titular de la tarjeta paga automáticamente la\ncomisión por transacción.\n
\nLa comisión no será superior a lo que cobre la entidad adquirente por SmartResQ/CorPatch®. La tasa se mostrará\nclaramente como un cargo separado en la ventana de pago.

\n\n
\n\n \n
\n

Entrega

\n\n

Nos esforzamos por enviar los pedidos de día laborable a día laborable y utilizamos una agencia de transporte\nde confianza internacional. Encontrará el precio total de su compra, incluida la entrega, en la caja antes de\naceptar su pedido final.

\n\n\n\n

Si el cliente no acepta la mercancía, SmartResQ/CorPatch® puede rescindir el contrato o recibir una\nindemnización por incumplimiento tras un periodo de dos semanas para cubrir los gastos de manipulación y\nenvío.

\n\n\n\n

Si el cliente ha facilitado datos incorrectos sobre la dirección de entrega, es posible recoger el paquete en la\ntienda de paquetería indicada en nuestra tienda web; de lo contrario, el paquete se pierde.

\n\n\n\n

El cliente nunca recibirá entregas parciales a menos que SmartResQ/CorPatch® lo indique explícitamente.

\n\n\n\n

Riesgo de pérdida

\n\n

La propiedad del riesgo del producto se transfiere al comprador cuando el producto se pone a su disposición\nsegún este acuerdo. Si ha transcurrido el plazo de entrega y el comprador no recibe un producto puesto a su\ndisposición o a su disposición según el acuerdo, el comprador asume el riesgo de pérdida o daño causado por las\ncaracterísticas del propio producto.

\n\n
\n\n \n
\n

Anulación y devoluciones

\n\n

Cuando usted compra con SmartResQ/CorPatch® en línea o fuera de línea, tiene 14 días para arrepentirse y\ncancelar donde puede informarnos que ha cambiado de opinión y devolvernos el artículo en el mismo estado en\nque lo recibió.\n
\nSólo aceptamos devoluciones de artículos sin usar en su embalaje original, precintado y sin daños, y deben estar\ncorrectamente embalados para su envío; de lo contrario, los productos se considerarán usados y no se aplicarán\nreembolsos parciales. El derecho de desistimiento sólo se aplica a los productos desprecintados en el momento\nde la recepción.

\n\n\n\n

Motivos aceptables para devolver un producto

\n
    \n
  • Uso del derecho de cancelación de 14 días
  • \n\n
  • Producto no conforme a la descripción (garantía)
  • \n\n
  • Producto defectuoso
  • \n
\n\n\n

Las condiciones de devolución de CorPatch® siguen las normas estándar de la UE.

\n\n\n\n\n\n

Si devuelve el producto, conserve el embalaje original y no lo dañe, pegue ni escriba en él. Obtén y utiliza un\nembalaje de devolución específico, por ejemplo, una caja de cartón.

\n\n\n\n

En el caso de CorPatch® Trainer, las condiciones de retirada de este producto siguen las normas estándar de la\nUE.

\n\n\n\n

Para ejercer el derecho de cancelación, deberá notificárnoslo en un plazo de 14 días a partir de la recepción de\nlos artículos. Las solicitudes de cancelación se enviarán por correo electrónico a info@corpatch.com, indicando\nclaramente que desea hacer uso de sus derechos de cancelación y el motivo.

\n\n\n\n

Esperamos que devuelva los artículos lo antes posible después de haber notificado la cancelación y, a más tardar,\n14 días después de habernos informado por correo electrónico.

\n\n\n\n

Podemos rechazar el reembolso hasta que haya devuelto los artículos o hasta que demuestre que los ha\ndevuelto. Para este reembolso utilizaremos el mismo método de pago que se utilizó en la transacción original.

\n\n\n\n

Razones no aceptables para devolver un producto

\n
    \n
  • Cambio de opinión tras el derecho de cancelación de 14 días.
  • \n\n
  • Si el producto ha sido activado.
  • \n\n
  • Si el producto se utiliza o daña de cualquier otra forma.
  • \n\n
  • Si el software o la aplicación gratuita se descargan, conectan, instalan o combinan de cualquier otro\nmodo con los productos físicos.
  • \n
\n\n\n

Cómo volver

\n\n

Sólo aceptamos devoluciones de artículos sin abrir, en su embalaje original y sin daños, y deben estar\ncorrectamente embalados para su envío; de lo contrario, los productos se considerarán usados y no se\naplicarán reembolsos.

\n\n\n\n

Salvo que se indique lo contrario, las devoluciones deben enviarse a: \n
\nSmartResQ ApS (CorPatch®)\n
\nLundevej 26\n
\nDK-5700 Svendborg\n
\nDinamarca\n

\n\n\n

¡IMPORTANTE! Usted es el único responsable de la calidad del embalaje y de los artículos hasta que los\nrecibamos. Conserve el recibo postal, incluida la información sobre los gastos de envío y, si procede, el número\nde seguimiento y localización. No cubrimos los gastos de envío de las devoluciones y no aceptamos paquetes\nenviados “contra reembolso” o similares.

\n\n
\n\n\n
\n

Reembolsos

\n\n

SmartResQ/CorPatch® está obligado a reparar, sustituir, rebajar el precio o reembolsar el importe íntegro si el\nartículo resulta defectuoso en un plazo de 2 años a partir de la fecha de compra.\n
\nEl cliente no tiene derecho a devolución si el problema es menor, como arañazos en el artículo o similares.\n
\nUna vez que SmartResQ/CorPatch® recibe el artículo del cliente, se inicia el reembolso. El valor del importe del\nreembolso depende del estado de los productos cuando se reciben en SmartResQ/CorPatch®.

\n\n\n\n

La forma en que se procesa el reembolso del cliente depende del método de pago original. Si el cliente pagó con\ntarjeta de crédito o débito, el reembolso se enviará al banco emisor de la tarjeta en un plazo de 5 días laborables\na partir de la recepción del artículo devuelto o de la solicitud de cancelación. Póngase en contacto con el banco\nemisor de la tarjeta si tiene preguntas sobre cuándo se abonará el importe en su cuenta.

\n
\n\n\n
\n\n

Tratamiento de datos personales

\n\n\n

En SmartResQ/CorPatch® valoramos sus datos personales a través de nuestro esfuerzo de cumplimiento de datos\nen tres pasos: a. mantener un mapa detallado de nuestro flujo de datos, b. emprender una evaluación legal\nbasada en el flujo de datos para, c. implementar las medidas de seguridad necesarias para mantener sus datos\nseguros.

\n\n\n\n

Para poder utilizar nuestra tienda virtual, debe facilitar como mínimo la siguiente información:

\n
    \n
  • Nombre
  • \n\n
  • Dirección
  • \n\n
  • Correo electrónico
  • \n\n
  • Número de teléfono
  • \n
\n\n\n

La recopilación de información personal de los clientes tiene lugar en el marco de la legislación vigente y de la\nlegislación del Reglamento General de Protección de la UE (GDPR).

\n\n\n\n

Si desea saber más sobre el tratamiento que hacemos de sus datos personales, lea nuestra política de privacidad.

\n\n
\n\n\n
\n

Quejas

\n\n

Cómo presentar una reclamación

\n\n

Si hay algún problema con el producto, puede solicitar la reparación o sustitución del producto defectuoso, el\nreembolso o una reducción del precio, dependiendo de la situación concreta.\n
\nPor supuesto, es requisito que la reclamación esté justificada y que el defecto no se deba a un uso incorrecto del\nproducto o a otra conducta incorrecta.

\n\n\n\n

Le recomendamos que reclame lo antes posible y en el plazo de una semana desde que se descubra el defecto.\n
\nSi tiene alguna pregunta, comentario o queja, no dude en ponerse en contacto con nosotros por correo\nelectrónico: info@corpatch.com.

\n\n

Reclamar ante otras entidades de la UE

\n\n

Visite el sitio web oficial de la Unión Europea para reclamar ante otras entidades de la UE. Encuentre información aquí.

\n\n
\n\n\n
\n

Modificaciones de este documento

\n\n

En sitio(s) web, aplicación(es) y políticas

\n\n

SmartResQ/CorPatch® se reserva el derecho de realizar cambios, eliminar, modificar o complementar nuestro(s)\nsitio(s) web, aplicación(es), políticas y documentos en cualquier momento y por cualquier motivo sin previo aviso\na nadie.\n
\nSi alguna de estas condiciones se considerara inválida, nula o inaplicable por cualquier motivo, dicha condición\nse considerará separable y no afectará a la validez y aplicabilidad de las condiciones restantes.

\n\n\n\n

Si cambiamos nuestras políticas, publicaremos las políticas revisadas en línea con una fecha de revisión\nactualizada. Le recomendamos que revise las políticas con regularidad. Si introducimos cambios sustanciales en\nnuestras políticas que modifiquen significativamente nuestras prácticas, también podremos notificárselo de\notras formas, por ejemplo, enviándole un correo electrónico o publicando un aviso en nuestro sitio web y/o en\nlas redes sociales antes de que los cambios entren en vigor.

\n\n\n\n

Relacionar una compra específica

\n\n

Al comprar un producto, se le pedirá que acepte una versión de ciertos documentos tal y como son en ese\nmomento exacto - esa versión no se cambiará después de ese momento y dictará los términos de nuestra relación\ncon usted con respecto a esa compra exacta.

\n\n
\n\n\n
\n

Derecho y jurisdicción

\n\n

Las leyes de Dinamarca y el Tribunal de Distrito de Svendborg

\n\n\n\n

SmartResQ/CorPatch® aplica la ley danesa y el lugar para cualquier disputa legal, pero no CISG.\n
\nCualquier disputa relacionada de alguna manera con su visita a SmartResQ/CorPatch® o a los productos que\nusted compra a través de SmartResQ/CorPatch® se someterá a confidencial en Dinamarca, salvo que, en la\nmedida en que usted ha violado o amenazado con violar los derechos de propiedad intelectual\nSmartResQ/CorPatch®, SmartResQ/CorPatch® podrá solicitar medidas cautelares u otras medidas apropiadas en\ncualquier país y usted acepta la jurisdicción exclusiva y el lugar en dichos tribunales.

\n\n\n\n

Si se incumple el acuerdo de “Términos y Condiciones”, se emprenderán acciones legales y se podrá presentar\nuna demanda ante los tribunales.

\n\n\n\n

Los litigios entre nosotros y cualquier consumidor se someterán al Tribunal de Distrito de Svendborg,\nChristiansvej 41, 5700 Svendborg, Dinamarca.

\n\n
\n\n\n
\n

Información de contacto

\n\n

Gracias por leer los “Términos y Condiciones” de SmartResQ/CorPatch®.\n
\nSi tiene alguna pregunta, comentario o queja, no dude en ponerse en contacto con nosotros.

\n\n\n\n

Nuestra empresa se encuentra en: Lundevej 26, 5700 Svendborg, Dinamarca

\n\n\n\n

Puede encontrarnos en el Registro Mercantil Central con el número de IVA DK 38674102

\n\n\n\n

Puede llamarnos al número de teléfono +45 62 200 100

\n\n\n\n

o

\n\n\n\n

envíenos un correo electrónico a: info@corpatch.com

\n\n\n\n

© SmartResQ ApS – Todos los derechos reservados\n
\nDinamarca, Versión 2.1 – Publicada el 2024.05.25

\n\n
\n\n \n\n\n\n \n\n\n
\n\n

Política de privacidad de SmartResQ / CorPatch®

\n \n

Tratamos sus datos de conformidad con el GDPR

\n\n

SmartResQ/CorPatch® respeta su privacidad. Esta declaración de privacidad describe sus derechos de privacidad y nuestro compromiso para asegurar su información personal.

\n\n

Si tiene alguna pregunta sobre el tratamiento de sus datos personales, póngase en contacto con nosotros. El responsable del tratamiento de datos es:

\n\n

Empresa: SmartResQ ApS (CorPatch®)

\n\n

Dirección: \n
\nLundevej 26\n
\n5700 Svendborg\n
\nDinamarca

\n\n\n\n

Nº CVR: 38674102

\n\n

Teléfono: +45 62 200 100

\n\n

Correo electrónico: info@corpatch.com

\n\n

SmartResQ/CorPatch® es una empresa danesa/europea con entidades jurídicas, procesos empresariales, estructuras de gestión y sistemas técnicos transfronterizos. SmartResQ/CorPatch® ofrece productos, software y servicios a empresas públicas y privadas de Europa

\n\n

La sede central se encuentra en Dinamarca y SmartResQ/CorPatch® está sujeta a la legislación europea de protección de datos, incluido el Reglamento General de Protección de Datos (RGPD). Todas las decisiones importantes en SmartResQ/CorPatch® relativas a la protección de datos personales se toman a nivel directivo bajo la supervisión del responsable de protección de datos.

\n\n

Esta declaración de privacidad está disponible en nuestros sitios web y en nuestras aplicaciones.

\n\n

No utilice las páginas, aplicaciones o servicios de SmartResQ/CorPatch® si no está de acuerdo con la forma en que procesamos los datos personales en virtud de esta declaración de privacidad.

\n\n
\n\n\n
\n\n

Tipo de información personal que recopilamos

\n\n

Cuando un responsable del tratamiento determine los fines y medios del tratamiento de sus datos personales, actuará como responsable del tratamiento. Esto incluye situaciones en las que SmartResQ/CorPatch® recopila datos personales en el contexto de que usted es un demandante de empleo, un representante de un cliente o un cliente potencial, o cuando usted es un usuario de software.

\n\n

SmartResQ procesa información personal para una variedad de propósitos, dependiendo de la relación que tengamos con usted.

\n\n

Podemos tratar:

\n
    \n
  1. información básica de contacto, como nombre, dirección, número de teléfono (móvil y/o fijo) y correo electrónico,
  2. \n\n
  3. información laboral como empleador, cargo, puesto, incluidas preferencias e intereses en un contexto profesional,
  4. \n\n
  5. opiniones, comentarios o preguntas sobre SmartResQ/CorPatch® o nuestros productos y servicios,
  6. \n\n
  7. fotos o vídeos grabados en nuestras instalaciones,
  8. \n\n
  9. los contenidos que has subido, como fotos, vídeos y actuaciones a lo largo del tiempo,
  10. \n\n
  11. información exclusiva del usuario, como identificación de inicio de sesión, nombre de usuario, contraseña y pregunta de seguridad,
  12. \n\n
  13. información financiera, cuando usted acepte que utilicemos su información, por ejemplo, para almacenar los datos de su tarjeta de pago,
  14. \n\n
  15. información de tráfico proporcionada por su navegador web, como el tipo de navegador, el dispositivo, el idioma y la dirección del sitio web del que procede y otra información de tráfico, incluida la dirección IP,
  16. \n\n
  17. el comportamiento de los clics y la actividad en SmartResQ/CorPatch® ID y en nuestros productos y servicios,
  18. \n\n
  19. comportamiento del correo electrónico, como los mensajes de correo electrónico de SmartResQ/CorPatch® que abre, cuándo y cómo,
  20. \n\n
  21. otra información personal contenida en su perfil que haya colocado libremente en redes sociales de terceros, como LinkedIn, Facebook, Google, etc.,
  22. \n\n
  23. información utilizada con fines científicos para mejorar la supervivencia tras un paro cardíaco recopilada a través de nuestros sitios web y aplicaciones,
  24. \n\n
  25. información sobre los usuarios para suministrar productos que cumplan los requisitos de calidad y seguridad, prestar servicios a los usuarios y mantener y mejorar nuestras ofertas,
  26. \n\n
  27. información sobre los solicitantes de empleo para gestionar las solicitudes de empleo, comunicar futuras ofertas de empleo y mantener y mejorar nuestros procesos de contratación,
  28. \n\n
  29. información sobre las personas que se han inscrito para recibir boletines y otros materiales con el fin de entregar los materiales y mantener y mejorar nuestras ofertas,
  30. \n\n
  31. información de cookies para ofrecer publicidad personalizada en redes sociales y sitios web.
  32. \n
\n\n
\n\n\n
\n

Datos recogidos y tratados en la plataforma CorPatch® Services y sus aplicaciones

\n\n

SmartResQ maneja, recopila y almacena los siguientes datos personales cuando usted utiliza la plataforma o las aplicaciones de CorPatch® Services.

\n\n\n\n\n

Todos los usuarios (administrador del centro, formador, alumno/usuario final)

\n
    \n
  • Nombre (si se ha introducido)
  • \n\n
  • Apellidos (si se han introducido)
  • \n\n
  • Apodos (si se han introducido)
  • \n\n
  • Dirección de correo electrónico (obligatorio)
  • \n\n
  • Idioma de comunicación preferido (obligatorio)
  • \n\n
  • Contraseña hash (obligatorio)
  • \n\n
  • Si se ha validado la dirección de correo electrónico (obligatorio)
  • \n
\n\n\n

Además, para alumnos/usuarios finales (obligatorio)

\n\n

Datos sobre el teléfono móvil utilizado:

\n\n\n

Sistema operativo (Android/iOS):

\n
    \n
  • Versión del sistema operativo (por ejemplo, 9)
  • \n\n
  • Fabricante (por ejemplo, Samsung)
  • \n\n
  • Modelo (por ejemplo, SM-T518)
  • \n\n
  • Versión de la aplicación (por ejemplo, 1.2.4)
  • \n\n
  • Hora de la última actividad en primer plano de la aplicación
  • \n\n
  • Hora de la última actividad en segundo plano de la aplicación
  • \n\n
\n\n

Datos sobre el CorPatch® (CPS) utilizado:

\n
    \n
  • Número de serie / Dirección MAC
  • \n\n
  • Versión del firmware
  • \n\n
  • Nombre del modelo (por ejemplo, CPS_01)
  • \n\n
  • Fabricante (actualmente siempre SRQ)
  • \n\n
  • Nombre (actualmente siempre CorPatch®)
  • \n\n
  • Estado de la batería
  • \n\n
  • Defectos
  • \n
\n\n\n

Datos de incorporación de usuarios:

\n
    \n
  • Tutoría finalizada (sí/no)
  • \n\n
  • Condiciones de uso aceptadas (sí/no)
  • \n\n
  • Autoevaluación completada (sí/no)
  • \n\n
  • Pruebas de formación realizadas (sí/no)
  • \n\n
  • Primer inicio de sesión con éxito (sí/no)
  • \n\n
  • Se conectó un SPI (sí/no)
  • \n\n
\n\n

Datos recogidos a través de la formación:

\n
    \n
  • Fecha, hora y duración de la formación
  • \n\n
  • Resultado de la formación
  • \n\n
  • Tipo de formación o configuración de la formación
  • \n\n
  • En caso de formación en un instituto, información adicional sobre el curso, el formador y el centro
  • \n\n
\n\n\n

Registros del servidor

\n\n

Los siguientes datos se almacenan en los registros del servidor web:

\n
    \n
  • Dirección IP de la parte que accede
  • \n\n
  • Versión del navegador de la parte que accede
  • \n\n
  • Fecha/hora de acceso
  • \n\n
  • URL de acceso
  • \n
\n

Servicios externos que procesan datos:

\n
    \n
  • Google/Firebase para el registro remoto y el análisis de fallos y errores
  • \n\n
  • Google/Firebase para enviar notificaciones
  • \n\n
  • Sendgrid para enviar correos electrónicos
  • \n\n
  • Hetzner Online GmbH para el alojamiento del backend web y la base de datos
  • \n\n
\n\n

¿Qué ocurre cuando se elimina un usuario?

\n
    \n
  • El usuario se da de baja de nuestro sistema en la página de inicio de CorPatch® Services https://app.corpatch.com
  • \n\n
  • El usuario se marca como eliminado. Después de eso, ya no puede iniciar sesión, ya no es visible para los administradores, etc., pero el usuario sigue existiendo en la base de datos.
  • \n\n
  • Transcurridos 14 días, los datos del usuario se eliminan automáticamente de la base de datos.
  • \n\n
  • A efectos de evaluación científica y mejora de la funcionalidad, los datos de las formaciones y del uso de CorPatch® seguirán existiendo en la base de datos tras la eliminación del usuario, pero la referencia (el ID) al usuario estará vacía, y se eliminarán todas las referencias a datos personales.
  • \n
\n\n
\n\n\n
\n

Cómo recopilamos sukk información personal

\n\n

La mayoría de los datos personales que procesamos nos los proporciona usted directamente. Recogemos y tratamos datos cuando usted:

\n
    \n
  • registrarse en línea o realizar un pedido de cualquiera de nuestros productos o servicios; por ejemplo, datos demográficos, dirección de correo electrónico, información de pago, artículos, importe del pedido, nivel y frecuencia de los descuentos. Incluido el envío de correos electrónicos transaccionales, por ejemplo, confirmación de pedido, confirmación de envío y confirmación de reembolso,
  • \n\n
  • participación en la comunicación enviada (correo electrónico, SMS, correo directo o teléfono); por ejemplo, tasa de apertura, tasa de clics y tiempo dedicado a leer los correos electrónicos, dominio del remitente y tipo de cliente de correo electrónico,
  • \n\n
  • rellenar voluntariamente una encuesta de clientes o dar su opinión en cualquiera de nuestros tablones de anuncios o por correo electrónico.
  • \n
\n\n\n

También podríamos recibir información personal indirectamente, de las siguientes fuentes en los siguientes escenarios:

\n
    \n
  • De cookies: cuando visita nuestros sitios web o aplicaciones; por ejemplo, dirección IP, país, páginas vistas, productos vistos, interacción/clics y búsquedas.
  • \n\n
  • De usted o de cualquier otra persona relacionada con nuestro cliente. Estas personas pueden ser un gerente o un colega. Si el cliente para el que usted trabaja compra productos o servicios de SmartResQ/CorPatch® a través de una empresa asociada a SmartResQ/CorPatch®, podemos recopilar información sobre usted de la empresa asociada.
  • \n\n
  • Socios de marketing de SmartResQ/CorPatch®, fuentes públicas o redes sociales de terceros.
  • \n\n
  • SmartResQ/CorPatch® podrá combinar datos personales sobre usted recogidos de una fuente con información obtenida de otra fuente. Esto nos da una imagen más completa de usted, lo que también nos permite servirle de una manera más relevante con un mayor nivel de personalización.
  • \n
\n\n
\n\n\n
\n

Cómo utilizamos sus datos

\n\n

Con el fin de gestionar en general nuestras relaciones con los clientes y cumplir nuestros compromisos con ellos, SmartResQ/CorPatch® necesita información sobre usted en su calidad de cliente o cuando utiliza un servicio. Los fines del tratamiento de dichos datos personales son:

\n\n
    \n
  • Tramitar su pedido, gestionar su cuenta,
  • \n\t\n
  • enviarle por correo electrónico ofertas especiales sobre otros productos y servicios que consideremos de su interés,
  • \n\n
  • enviarle por correo electrónico ofertas especiales sobre otros productos y servicios que consideremos de su interés,
  • \n\n
  • realizar el proceso de venta y contratación para los clientes,
  • \n\n
  • ofrecer a los clientes los productos y servicios solicitados,
  • \n\n
  • realizar entregas de conformidad con los acuerdos celebrados con usted o con los clientes,
  • \n\n
  • mejorar y desarrollar la calidad, funcionalidad y experiencia de usuario de nuestros productos, servicios y sitios web y aplicaciones de SmartResQ/CorPatch®,
  • \n\n
  • detectar, limitar y prevenir las amenazas a la seguridad y realizar tareas de mantenimiento y solución de problemas y depuración,
  • \n\n
  • prevenir el uso indebido de nuestros productos y servicios,
  • \n\n
  • para procesar pedidos, facturación, pagos u otro seguimiento financiero,
  • \n\n
  • crear perfiles de interés para promocionar productos y servicios relevantes,
  • \n\n
  • establecer comunidades de usuarios para educar y facilitar la interacción entre los usuarios y SmartResQ/CorPatch®.
  • \n\n
\n\n

Acerca de las pistas

\n\n

SmartResQ/CorPatch® procesa datos personales de clientes potenciales con fines de marketing. Con el fin de proporcionar contenido específico y relevante a los clientes potenciales, SmartResQ/CorPatch® construye un perfil de interés basado en su actividad y sus elecciones y acciones en las páginas de SmartResQ/CorPatch®, así como su respuesta al contenido de marketing. La base jurídica de dicho tratamiento es principalmente su consentimiento.

\n\n

Sobre los demandantes de empleo

\n\n

Si es usted un candidato a un puesto de trabajo, procesamos sus datos personales para evaluar su potencial como empleado de SmartResQ/CorPatch®. Nuestra plataforma segura de carreras profesionales en línea garantiza que cumplimos las leyes y normativas más recientes en relación con la privacidad de los datos. La base jurídica de dicho tratamiento es su consentimiento.

\n\n

Acerca de los visitantes del sitio web

\n\n

Para controlar el acceso a nuestros sitios, procesamos información personal sobre los visitantes. El tratamiento se basa en nuestro interés legítimo de proteger nuestros secretos comerciales, empleados, ubicaciones y a usted como visitante. Se le informará de sus derechos en este contexto cuando se registre en nuestro sistema electrónico para visitantes.

\n\n

Para mejorar la calidad de la RCP, especialmente a través de la formación en RCP, SmartResQ/CorPatch® podría compartir sus datos con nuestras empresas asociadas (Institutos de Formación) para que puedan ofrecerle sus productos y servicios.

\n\n

Cuando procesamos su pedido, nuestro sistema puede enviar sus datos a las agencias de referencia de crédito, y también utilizar la información resultante de las mismas, para evitar compras fraudulentas.

\n\n
\n\n\n
\n

Cómo almacenamos su información personal

\n\n

SmartResQ/CorPatch® se toma muy en serio la confianza que usted y nuestros clientes nos demuestran. SmartResQ/CorPatch® se compromete a evitar el acceso no autorizado, la divulgación u otro tratamiento aberrante de los datos personales. SmartResQ/CorPatch® garantizará la confidencialidad de los datos personales que procesamos, mantendrá la integridad de los datos personales y garantizará su accesibilidad de acuerdo con las leyes de privacidad aplicables.

\n\n

Como parte de nuestros compromisos, adoptamos procedimientos y medidas organizativas, técnicas y físicas razonables y adecuadas para proteger la información que recopilamos y procesamos. Tenemos en cuenta el tipo de datos personales y el riesgo al que nuestros clientes están expuestos por cualquier violación de seguridad, ya que hay una alta probabilidad de que las causas fundamentales de las violaciones de datos personales se pueden encontrar internamente, creemos que la construcción de una fuerte cultura corporativa en la que el respeto y la vigilancia sobre la protección de datos entre nuestros empleados es fundamental para garantizar el tratamiento legal y la protección de su información. En caso de violación de datos, SmartResQ/CorPatch® seguirá las prácticas establecidas por el Datatilsynet danés.

\n\n

Su información se almacena de forma segura de acuerdo con la normativa GDPR.

\n\n
\n\n\n
\n

¿Cuánto tiempo conservamos sus datos personales?

\n\n

SmartResQ/CorPatch® conserva sus datos personales sólo durante el tiempo que sea necesario para los fines indicados, teniendo en cuenta nuestra necesidad de responder a las consultas y resolver los problemas y cumplir con los requisitos legales en virtud de la legislación aplicable.

\n\n

Esto significa que SmartResQ/CorPatch® puede almacenar su información personal durante un período razonable después de su última interacción y la de nuestro cliente con nosotros. Cuando los datos personales que hemos recopilado ya no son necesarios, los eliminamos. Podemos procesar datos con fines estadísticos y/o científicos, pero en tales casos los datos serán seudonimizados o anonimizados.

\n\n\n\n\n

Plazo de conservación de los datos

\n\n

Conservaremos su información personal durante el período necesario para cumplir los fines descritos en la presente política de privacidad, a menos que la ley exija o permita un período de conservación más largo, por motivos legales, fiscales o reglamentarios u otros fines empresariales legítimos y legales.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Propósito Plazos
Atención al cliente y normativa contable 5 años o mientras estemos obligados a cumplir el requisito legal necesario.\n
\nEliminamos sus datos de registro tan pronto como elimina su cuenta de usuario con nosotros, o una vez que expira el período de conservación legal.\n
Plataforma profesional 6 meses para los documentos de solicitud que no den lugar a la contratación del solicitante de empleo.\n
\n\n\nRenovación cada 6 meses si desea que se le tenga en cuenta para futuras ofertas de empleo y da su consentimiento para un periodo de almacenamiento más largo.\n
Objetivo de marketing 3 años después de su última actividad, por ejemplo, visita a nuestros sitios web, compra o participación en una comunicación.\n
\n\n\nSi ha dado su permiso de marketing (correo electrónico, SMS, teléfono, etc.) y siempre que tengamos su permiso para ponernos en contacto con usted.\n
\n\n\nEliminamos su dirección de correo electrónico del boletín automáticamente, una vez que elimina su cuenta de usuario o si se da de baja de nuestro boletín.\n
Almacenamiento del historial de pedidos y obligaciones de cumplimiento 5 años o mientras estemos obligados a cumplir los requisitos legales necesarios.
Experiencia del cliente 3 años después de su última actividad, por ejemplo, visita a nuestros sitios web, compra o participación en una comunicación.\n
\n\n\nSi ha dado su permiso de marketing (correo electrónico, SMS, teléfono, etc.) y siempre que tengamos su permiso.\n
Evaluación del riesgo de fraude 5 años o mientras estemos obligados a cumplir el requisito legal necesario.
\n\n
\n\n\n\n
\n

Comunicaciones de marketing

\n\n

Usted tiene derecho a optar por no recibir comunicaciones de marketing de SmartResQ/CorPatch® y puede hacerlo de dos maneras:

\n
    \n
  • siguiendo las instrucciones de exclusión en las comunicaciones comerciales pertinentes,
  • \n\n
  • cambiar las preferencias en la sección de edición correspondiente a la cuenta, si tiene una cuenta con SmartResQ/CorPatch®,
  • \n\n
  • poniéndose en contacto con nosotros por correo electrónico en info@corpatch.com.
  • \n
\n\n\n

Tenga en cuenta que incluso si opta por no recibir comunicaciones de marketing, puede seguir recibiendo mensajes administrativos de SmartResQ/CorPatch®, como confirmaciones de pedidos y avisos necesarios para gestionar su cuenta o los servicios prestados a nuestros clientes a través de, por ejemplo, servicios o aplicaciones móviles.

\n\n
\n\n\n
\n

Sus derechos en materia de protección de datos

\n\n

Para SmartResQ/CorPatch® es importante que usted conozca perfectamente todos sus derechos en materia de protección de datos.

\n\n

Algunas leyes de protección de datos, incluido el Reglamento General de Protección de Datos (RGPD) de la Unión Europea, la legislación correspondiente en Alemania Bundesdatenschutzgesetz (BDSG), en Suiza y en el Reino Unido, y algunas leyes estatales de Estados Unidos, le otorgan ciertos derechos en relación con los datos personales que ha compartido con nosotros. Si usted reside en el Espacio Económico Europeo, puede tener los siguientes derechos:

\n
    \n
  1. Su derecho de acceso – Tiene derecho a solicitarnos copias de su información personal.
  2. \n\n
  3. Derecho de rectificación – Tiene derecho a solicitar que corrijamos cualquier información personal que considere inexacta. También tiene derecho a solicitarnos que completemos la información que considere incompleta.
  4. \n\n
  5. Su derecho a la eliminación – Tiene derecho a solicitarnos que eliminemos su información personal en determinadas condiciones.
  6. \n\n
  7. Su derecho a restringir el tratamiento – tiene derecho a solicitarnos que restrinjamos el tratamiento de sus datos personales en determinadas condiciones.
  8. \n\n
  9. Su derecho a oponerse al tratamiento – Tiene derecho a oponerse al tratamiento de sus datos personales en determinadas condiciones.
  10. \n\n
  11. Su derecho a la portabilidad de los datos – Tiene derecho a solicitar que transfiramos la información personal que hemos recopilado a otra organización, o directamente a usted en determinadas condiciones.
  12. \n\n
\n\n

Si desea ejercer alguno de estos derechos, póngase en contacto con nosotros en nuestra dirección de correo electrónico info@corpatch.com.

\n\n
\n\n\n
\n

¿Qué son las cookies?

\n\n

Las cookies son pequeños archivos de texto que contienen una cadena de caracteres y crean un identificador único para un usuario. Se devuelven al sitio web y/o a terceros. La mayoría de los navegadores están configurados inicialmente para aceptar cookies, ya que la mayoría de los sitios web necesitan acceder a ellas. Sin embargo, el usuario puede cambiar la configuración de su navegador para que, en general, pueda rechazar las cookies, bloquear las cookies de terceros o especificar cuándo se envía una cookie.

\n\n\n\n

SmartResQ/CorPatch® se compromete a garantizar su derecho a ajustar sus intereses y gestionar el alcance de la comercialización digital de nosotros a través de un sistema de gestión preferente.

\n\n
\n\n\n
\n

Cómo utilizamos las cookies

\n\n

SmartResQ/CorPatch® utiliza cookies de diversas formas para mejorar su experiencia en nuestros sitios web, aplicaciones y servicios por diferentes motivos, por ejemplo:

\n
    \n
  • Funcionalidad: utilizamos estas cookies para reconocerle en nuestro sitio web y recordar sus preferencias previamente seleccionadas. Por ejemplo, el idioma que prefiere y la ubicación en la que se encuentra. Se utiliza una combinación de cookies propias y de terceros.
  • \n\n
  • Publicidad: utilizamos estas cookies para recopilar información sobre su visita a nuestros sitios web y aplicaciones, el contenido que ha visto, los enlaces que ha seguido e información sobre su navegador, dispositivo y dirección IP. A veces compartimos algunos aspectos limitados de estos datos con terceros con fines publicitarios. También podemos compartir datos en línea recogidos a través de cookies con nuestros socios publicitarios. Esto significa que cuando visite otro sitio web, es posible que se le muestre publicidad basada en sus patrones de navegación en nuestro sitio web.
  • \n
\n\n
\n\n\n
\n

El tipo de cookies que utilizamos

\n\n

Nuestro(s) sitio(s) web utiliza(n) los siguientes tipos de cookies:

\n
    \n
  • Google Analytics: Esta cookie nos permite ver información sobre las actividades del sitio web para los usuarios, incluyendo pero no limitado a páginas vistas, fuente y tiempo de permanencia en un sitio web. La información es anónima y se muestra en forma de números, lo que significa que no se puede rastrear hasta las personas. Esto ayuda a proteger su privacidad. Mediante el uso de Google Analytics, podemos ver qué contenido es popular en nuestras páginas, y nos esforzamos por ofrecerle más de lo que le gusta leer y ver.
  • \n\n
  • Remarketing de Google Analytics: Coloca cookies en su ordenador, lo que significa que cuando abandona nuestro sitio, Google puede mostrarle anuncios sobre SmartResQ/CorPatch® que pueden interesarle en función de su comportamiento anterior en nuestro sitio web. Esta información no es personalmente identificable.
  • \n\n
  • Anuncios de Google: Mediante el uso de Google Ads, podemos ver qué páginas fueron útiles para conducir a envíos a través de nuestro formulario de contacto. Esta información no es personalmente identificable, pero los datos proporcionados en el formulario de contacto sí lo son.
  • \n\n
  • Google Ads remarketing: Coloca cookies en su ordenador, lo que significa que cuando abandona nuestro sitio, Google puede mostrarle anuncios sobre SmartResQ/CorPatch® que pueden interesarle en función de su comportamiento anterior en nuestro sitio web. Esta información no es personalmente identificable.
  • \n\n
  • Remarketing de Facebook: El píxel de seguimiento de Facebook coloca cookies en su ordenador que indican a Facebook que ha visitado el sitio. A continuación, suponemos que usted tiene un interés en SmartResQ/CorPatch® y el contenido de este sitio. Cuando visite Facebook, estará expuesto a información o anuncios con contenido similar. Por favor, utilice su configuración de privacidad en Facebook para limitar la exposición a la comercialización de este tipo.
  • \n\n
  • YouTube: Integramos vídeos de la plataforma YouTube proporcionada por Google (Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA). Política de privacidad: https://www.google.com/policies/privacy/.
  • \n
\n\n
\n\n\n
\n

Cómo gestionar las cookies

\n\n

Puede configurar su navegador para que no acepte o elimine las cookies. Sin embargo, es posible que algunas funciones de nuestro sitio web no funcionen. Vea cómo evitar las cookies en navegadores específicos:

\n\n\n\n

SmartResQ/CorPatch® utiliza algunos servicios de terceros de confianza en nuestras páginas. Estos servicios pueden utilizar cookies. Puede optar por rechazar las cookies de terceros en su navegador siguiendo este enlace.

\n\n

Puede evitar que Google recopile y procese la información generada por la cookie de Google sobre su uso de nuestros sitios descargando e instalando el complemento de inhabilitación de Google Analytics para su navegador web actual. Este complemento está disponible aquí.

\n\n
\n\n\n
\n\n

Políticas de privacidad de otros sitios web

\n\n

Los sitios web de SmartResQ/CorPatch® contienen enlaces a otros sitios web. Nuestra política de privacidad sólo se aplica a nuestro sitio web, por lo que si hace clic en un enlace a otro sitio web, debe leer su política de privacidad.

\n\n
\n\n\n
\n

Cambios en nuestra política de privacidad

\n\n

Si cambiamos nuestra declaración de privacidad, publicaremos la declaración revisada aquí con una fecha de revisión actualizada. Le recomendamos que revise la declaración con regularidad. Si introducimos cambios sustanciales en nuestra declaración que modifiquen significativamente nuestras prácticas de privacidad, también podremos notificárselo de otras formas, por ejemplo, enviándole un correo electrónico o publicando un aviso en nuestro sitio web y/o redes sociales antes de que los cambios entren en vigor.

\n\n
\n\n\n
\n

Cómo ponerse en contacto con SmartResQ ApS

\n\n

Si tiene alguna pregunta sobre la política de privacidad de SmartResQ/CorPatch® , los datos que tenemos sobre usted, o desea ejercer alguno de sus derechos de protección de datos, no dude en ponerse en contacto con nosotros.

\n\n

Correo electrónico: info@corpatch.com

\n\n

Página web: https://corpatch.com

\n\n
\n\n\n
\n\n

Cómo ponerse en contacto con la autoridad competente

\n\n

Si desea presentar una reclamación o si considera que SmartResQ/CorPatch® no ha resuelto su problema de forma satisfactoria, puede ponerse en contacto con la Oficina del Comisionado de Información (ICO).

\n\n

Dirección del ICO:\n

\nInformation Commissioner’s Office\n
\nWycliffe House\n
\nWater Lane\n
\nWilmslow\n
\nCheshire\n
\nSK9 5AF

\n\n\n\n

Número de teléfono de ayuda: +44 303 123 1113

\n\n

Página web del ICO: https://www.ico.org.uk

\n\n

© SmartResQ ApS – Todos los derechos reservados\n
\nDinamarca, Versión 1.3 – Publicada el 2024.05.25

\n\n
\n
\n\n\n`","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageTitle: {\n id: 'cp.components.imprint.pageTitle',\n defaultMessage: 'Imprint',\n },\n})\n","import React from 'react'\nimport { AppPageLayout } from '../layouts/AppPageLayout'\nimport { useIntl } from 'react-intl'\nimport TermsOfUse from 'components/TermsOfUse/TermsOfUse'\n\nimport messages from './Imprint.messages'\n\nexport const Imprint: React.FunctionComponent = () => {\n const intl = useIntl()\n\n const pageTitle = intl.formatMessage(messages.pageTitle)\n\n return (\n \n \n \n )\n}\n\nexport default Imprint\n","import { Card } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport React from 'react'\nimport { CARD_DEFAULTS } from 'styles/styles'\nimport { theme } from 'theme/theme'\n\nconst useClasses = makeStyles({\n card: {\n ...CARD_DEFAULTS,\n display: 'flex',\n flexDirection: 'column',\n },\n\n container: {\n display: 'flex',\n flexDirection: 'row',\n height: '100%',\n flexGrow: 1,\n },\n\n imgContainer: {\n alignSelf: 'center',\n padding: theme.spacing(1),\n [theme.breakpoints.down('sm')]: {\n display: 'none',\n },\n width: 260,\n },\n img: {\n margin: theme.spacing(),\n maxWidth: 260,\n },\n cardContent: {\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n },\n})\n\ninterface ImageCardProps {\n imgUrl: string\n}\n\nconst useImgCardContentClasses = makeStyles({\n imgCardContent: {\n display: 'flex',\n justifyContent: 'center',\n height: '100%',\n flexGrow: 1,\n flexDirection: 'column',\n padding: theme.spacing(2),\n [theme.breakpoints.down('xs')]: {\n padding: theme.spacing(),\n },\n },\n})\n\nexport const ImageCardContent: React.FC = props => {\n const { imgCardContent } = useImgCardContentClasses()\n return
{props.children}
\n}\n\nconst useImgCardActionsClasses = makeStyles({\n imgCardActions: {\n display: 'flex',\n flexDirection: 'row-reverse',\n padding: theme.spacing(2),\n [theme.breakpoints.down('xs')]: {\n padding: theme.spacing(),\n },\n gap: theme.spacing(2),\n },\n})\n\nexport const ImageCardActions: React.FC = props => {\n const { imgCardActions } = useImgCardActionsClasses()\n return
{props.children}
\n}\n\nexport const ImageCard: React.FC = props => {\n const classes = useClasses()\n const { imgUrl, children } = props\n\n return (\n \n
\n
\n \n
\n
{children}
\n
\n
\n )\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n passwordRequired: {\n id: 'cp.components.changePassword.requiredError',\n defaultMessage: 'The current password is required',\n },\n passwordEqual: {\n id: 'cp.components.changePassword.equalError',\n defaultMessage: 'The new password is equal to the old one',\n },\n newPasswordRequired: {\n id: 'cp.components.changePassword.newRequiredError',\n defaultMessage: 'A new password is required',\n },\n passwordDontMatch: {\n id: 'cp.components.changePassword.matchError',\n defaultMessage: \"New passwords don't match\",\n },\n currentPassword: {\n id: 'cp.components.changePassword.currentPassword',\n defaultMessage: 'Current password',\n },\n newPassword: {\n id: 'cp.components.changePassword.newPassword',\n defaultMessage: 'New Password',\n },\n newPasswordRepeat: {\n id: 'cp.components.changePassword.newPasswordRepeat',\n defaultMessage: 'New Password (repeat)',\n },\n changePasswordButton: {\n id: 'cp.components.changePassword.changePasswordButton',\n defaultMessage: 'Change Password',\n },\n setPasswordButton: {\n id: 'cp.components.changePassword.setPasswordButton',\n defaultMessage: 'Set Password',\n },\n newToShortError: {\n id: 'cp.components.changePassword.newToShortError',\n defaultMessage: 'The provided passwort is to short.',\n },\n})\n","import { Button, TextField } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport React, { ChangeEvent, useState } from 'react'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { useIntl } from 'react-intl'\n\nimport messages from '../ChangePassword/ChangePassword.messages'\nimport { config } from 'config/config'\n\nconst PASSWORD_MIN_LEN = config().passwordMinLen\n\nconst useClasses = makeStyles({\n inputField1: {\n marginTop: theme.spacing(6),\n minHeight: 70,\n [theme.breakpoints.down('xs')]: {\n marginTop: 0,\n width: '100%',\n },\n },\n inputField: {\n marginBottom: theme.spacing(2),\n minHeight: 70,\n },\n})\ninterface InviteSetPasswordProps {\n onSend: (newPassword: string) => any\n}\n\nexport const InviteSetPassword: React.FC = props => {\n const intl = useIntl()\n const requiredError = intl.formatMessage(messages.passwordRequired)\n const matchError = intl.formatMessage(messages.passwordDontMatch)\n const newPassword = intl.formatMessage(messages.newPassword)\n const newPasswordRepeat = intl.formatMessage(messages.newPasswordRepeat)\n const setPasswordButton = intl.formatMessage(messages.setPasswordButton)\n const newToShortError = intl.formatMessage(messages.newToShortError)\n\n const { onSend } = props\n const classes = useClasses()\n\n const [newPassword0, setNewPassword0] = useState('')\n const [errorNewPassword0, setErrorNewPassword0] = useState(false)\n const [errorNewPasswordMessage0, setErrorNewPasswordMessage0] = useState('')\n\n const [newPassword1, setNewPassword1] = useState('')\n const [errorNewPassword1, setErrorNewPassword1] = useState(false)\n const [errorNewPasswordMessage1, setErrorNewPasswordMessage1] = useState('')\n\n const [valid, setValid] = useState(true)\n\n //\n // NewPassword0\n //\n function resetNewPassword0Validation() {\n setErrorNewPassword0(false)\n setErrorNewPasswordMessage0('')\n setValid(true)\n }\n\n function validateNewPassword0() {\n resetNewPassword0Validation()\n\n if (newPassword0 === '') {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(requiredError)\n setValid(false)\n }\n }\n\n //\n // NewPassword1\n //\n function resetNewPassword1Validation() {\n setErrorNewPassword1(false)\n setErrorNewPasswordMessage1('')\n setValid(true)\n }\n\n function validateNewPassword1() {\n resetNewPassword1Validation()\n\n if (newPassword0.length < PASSWORD_MIN_LEN) {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newToShortError)\n }\n\n if (newPassword0 !== newPassword1) {\n setErrorNewPassword1(true)\n setErrorNewPasswordMessage1(matchError)\n setValid(false)\n }\n }\n\n function validate() {\n validateNewPassword0()\n validateNewPassword1()\n\n const errorNewPasswordMatch = newPassword0 !== newPassword1\n\n return !errorNewPasswordMatch && !errorNewPassword0\n }\n\n function handleSetNewPassword0(e: ChangeEvent) {\n resetNewPassword0Validation()\n setNewPassword0(e.target.value)\n }\n\n function handleSetNewPassword1(e: ChangeEvent) {\n resetNewPassword1Validation()\n setNewPassword1(e.target.value)\n }\n\n function sendChangePasswordRequest() {\n const valid = validate()\n if (valid) {\n onSend(newPassword0)\n }\n }\n\n return (\n \n \n \n \n \n \n \n {setPasswordButton}\n \n \n \n )\n}\n\nexport default InviteSetPassword\n","import React, { useState } from 'react'\nimport { makeStyles } from '@material-ui/styles'\nimport { useTitle } from './useTitle.hook'\nimport { useLayoutStyles } from './useLayoutStyles.hook'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { LOGO_HEIGHT } from 'theme/constants'\nimport Footer from 'components/Footer/Footer'\nimport { TranslationButton } from '../NavBar/NavBar'\nimport { Colors } from '../../theme/colors'\n\nconst useClasses = makeStyles({\n header: {\n display: 'flex',\n justifyContent: 'space-between',\n margin: theme.spacing(3),\n [theme.breakpoints.down('xs')]: {\n margin: theme.spacing(2),\n },\n backgroundColor: Colors.neutrals[9],\n },\n logoImg: {\n // width: 150,\n height: LOGO_HEIGHT,\n [theme.breakpoints.down('xs')]: {\n height: 60,\n },\n },\n})\n\ninterface PublicPageLayoutProps {\n title: string\n showTranslationSwitch?: boolean\n}\n\nexport const PublicPageLayout: React.FunctionComponent = props => {\n const { root, deco } = useLayoutStyles()\n const { logoImg, header } = useClasses()\n const { title, showTranslationSwitch = false } = props\n const [isOpen, setIsOpen] = useState(false)\n\n useTitle(title)\n\n return (\n
\n
\n\n
\n logo\n\n {\n setIsOpen(false)\n }}\n handleOpen={() => {\n setIsOpen(true)\n }}\n />\n
\n\n {props.children}\n\n
\n
\n
\n )\n}\n","import { Typography } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport AppDrawer from 'components/AppDrawer/AppDrawer'\nimport { NavBar } from 'components/NavBar/NavBar'\nimport React from 'react'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { MainPageLayout } from '../layouts/MainPageLayout'\nimport { center } from 'styles/styles'\nimport { PublicPageLayout } from 'components/layouts/PublicPageLayout'\n\nconst useStyles = makeStyles({\n container: {\n ...center,\n },\n\n content: {\n ...center,\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(2),\n marginRight: theme.spacing(2),\n [theme.breakpoints.up('md')]: {\n maxWidth: 800,\n },\n\n '& img': {\n width: '50%',\n minHeight: 400,\n [theme.breakpoints.down('xs')]: {\n width: '80%',\n },\n },\n },\n title: {\n margin: theme.spacing(3),\n textAlign: 'center',\n },\n txt: {\n margin: theme.spacing(3),\n },\n})\n\ninterface PageNotFoundProps {\n variant?: 'app' | 'public'\n title?: string\n message?: string\n img?: string\n showBackButton?: boolean\n action?: () => React.ReactNode\n}\n\nexport const PageNotFound: React.FunctionComponent = props => {\n const classes = useStyles()\n const {\n title,\n message,\n img,\n action,\n variant = 'app',\n showBackButton = false,\n } = props\n const url = img || Images.missingUrl\n\n const Title = () => (\n <>\n {title && (\n \n {title}\n \n )}\n \n )\n const Img = () => missing\n\n const Message = () => (\n <>\n {' '}\n {message && {message}}\n \n )\n\n const Action = () => (\n <>{action &&
{action()}
}\n )\n\n const Layout = variant === 'public' ? PublicPageLayout : MainPageLayout\n\n return (\n \n {variant === 'app' && (\n <>\n \n \n \n )}\n
\n
\n \n <Img />\n <Message />\n <Action />\n </div>\n </div>\n </Layout>\n )\n}\n","import { createStateHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useAcceptInvitationState = createStateHook(\n AppStoreProvider,\n state => state.pages.acceptInvitation\n)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageNotFoundTitle: {\n id: 'cp.pages.acceptInvitation.pageNotFound.title',\n defaultMessage: 'Invitation not found',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.acceptInvitation.pageNotFound.message',\n defaultMessage: 'This invitation is not valid anymore.',\n },\n inviteSuccessTitle: {\n id: 'cp.pages.acceptInvitation.title',\n defaultMessage: 'Done.',\n },\n inviteSuccessMessage: {\n id: 'cp.pages.acceptInvitation.message',\n defaultMessage: 'All set up and you are good to go!',\n },\n inviteLoginButton: {\n id: 'cp.pages.acceptInvitation.button',\n defaultMessage: 'To the login page',\n },\n inviteAcceptedWelcome: {\n id: 'cp.pages.acceptInvitation.welcome',\n defaultMessage: 'Welcome',\n },\n})\n","import { Typography, Button } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport { InviteSetPassword } from 'components/InviteSetPassword/InviteSetPassword'\nimport { PublicPageLayout } from 'components/layouts/PublicPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport { Spinner } from 'components/Spinner/Spinner'\nimport React from 'react'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { useAcceptInvitationState } from './AcceptInvitation.restate'\nimport { useDispatchHook } from 'state/store'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { AppRoutes } from 'routes'\nimport { useIntl } from 'react-intl'\n\nimport messages from './AcceptInvitation.messages'\n\nconst useStyles = makeStyles({\n container: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n flexGrow: 1,\n [theme.breakpoints.down('xs')]: {\n margin: '1rem',\n },\n },\n\n welcome: {\n marginBottom: theme.spacing(3),\n },\n})\n\nconst AcceptInvitationLoading = () => {\n const classes = useStyles()\n\n return (\n <PublicPageLayout title=''>\n <div className={classes.container}>\n <Spinner visible={true} />\n </div>\n </PublicPageLayout>\n )\n}\n\nconst AcceptInvitationNotFound: React.FC = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n\n return (\n <PageNotFound\n variant='public'\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.empty}\n />\n )\n}\n\nconst Success = () => {\n const intl = useIntl()\n const inviteSuccessTitle = intl.formatMessage(messages.inviteSuccessTitle)\n const inviteSuccessMessage = intl.formatMessage(messages.inviteSuccessMessage)\n const inviteLoginButton = intl.formatMessage(messages.inviteLoginButton)\n\n const goTo = useGoToHook()\n\n const goToLogin = () => goTo(AppRoutes.Login)\n\n return (\n <PageNotFound\n variant='public'\n title={inviteSuccessTitle}\n message={inviteSuccessMessage}\n img={Images.confirmation}\n action={() => (\n <Button color='secondary' variant='contained' onClick={goToLogin}>\n {inviteLoginButton}\n </Button>\n )}\n />\n )\n}\n\nexport const AcceptInvitation: React.FC<{}> = () => {\n const intl = useIntl()\n const inviteAcceptedWelcome = intl.formatMessage(\n messages.inviteAcceptedWelcome\n )\n const classes = useStyles()\n\n const { loading, notFound, success } = useAcceptInvitationState(s => s.meta)\n const dispatch = useDispatchHook()\n const userInfo = useAcceptInvitationState(s => s.userInfo)\n\n const onSend = (newPassword: string) =>\n dispatch({ type: 'Page/AcceptInvitation/Send', payload: newPassword })\n\n if (loading) return <AcceptInvitationLoading />\n if (notFound) return <AcceptInvitationNotFound />\n if (success) return <Success />\n\n const name = userInfo ? userInfo.firstName + ' ' + userInfo.lastName : ''\n\n return (\n <PublicPageLayout title={inviteAcceptedWelcome}>\n <div className={classes.container}>\n <Typography variant='h4' className={classes.welcome}>\n {inviteAcceptedWelcome} {name}!\n </Typography>\n <InviteSetPassword onSend={onSend} />\n </div>\n </PublicPageLayout>\n )\n}\n\nexport default AcceptInvitation\n","import { EMail } from 'model/Email'\n\n// See https://stackoverflow.com/a/201378\n// And https://github.com/kodira/corpatch/issues/917\n\n// eslint-disable-next-line no-control-regex\nconst EMailRegEx = /(?:[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])/i\n\nexport const isEmail = (email: EMail) => EMailRegEx.test(email)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n inviteCardSubheader: {\n id: 'cp.components.invite.inviteSubheader',\n defaultMessage: 'An invitation will be send to this e-mail account.',\n },\n inviteFirstNameLabel: {\n id: 'cp.components.invite.inviteFirstnameLabel',\n defaultMessage: 'First name',\n },\n inviteSurnameLabel: {\n id: 'cp.components.invite.inviteSurnameLabel',\n defaultMessage: 'Family name',\n },\n inviteSendButton: {\n id: 'cp.components.invite.inviteSendButton',\n defaultMessage: 'Send Invitation',\n },\n inviteCancelButton: {\n id: 'cp.components.invite.inviteCancelButton',\n defaultMessage: 'Cancel',\n },\n inviteInvalidEmail: {\n id: 'cp.components.invite.inviteInvalidEmail',\n defaultMessage: 'This is not an valid email',\n },\n inviteEmailSend: {\n id: 'cp.components.invite.inviteEmailSend',\n defaultMessage: 'Send',\n },\n inviteEmailSent: {\n id: 'cp.components.invite.inviteEmailSent',\n defaultMessage: 'E-Mail sent',\n },\n inviteOk: {\n id: 'cp.components.invite.inviteOk',\n defaultMessage: 'OK',\n },\n inviteEmailRequired: {\n id: 'cp.components.invite.inviteEmailRequired',\n defaultMessage: 'E-Mail *',\n },\n})\n","import {\n Button,\n FormControl,\n Grid,\n TextField,\n Typography,\n Card,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport React, { useState } from 'react'\nimport { useIntl } from 'react-intl'\nimport { CARD_DEFAULTS } from 'styles/styles'\nimport { Colors } from 'theme/colors'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { isEmail } from 'utils/isEmail'\nimport messages from './Invite.messages'\nimport { Spinner } from 'components/Spinner/Spinner'\nimport { useAppState } from 'state/store'\n\nconst useClasses = makeStyles({\n submitButton: {\n marginTop: 40,\n },\n\n form: {\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n },\n\n innerContainer: {\n marginTop: theme.spacing(3),\n marginBottom: theme.spacing(5),\n height: 'auto',\n [theme.breakpoints.down('xs')]: {\n height: 'auto',\n },\n },\n\n error: {\n ...theme.typography.h6,\n color: theme.palette.error.dark,\n padding: theme.spacing(),\n fontSize: '1rem',\n backgroundColor: theme.palette.grey[50],\n border: '1px solid ' + theme.palette.primary.dark,\n },\n\n center: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n flexGrow: 1,\n backgroundColor: Colors.neutrals[9],\n },\n\n card: {\n ...CARD_DEFAULTS,\n },\n\n cardContent: {\n height: '100%',\n },\n\n cardContainer: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n height: '100%',\n },\n\n cardImg: {\n display: 'flex',\n marginLeft: theme.spacing(3),\n marginRight: theme.spacing(3),\n marginTop: theme.spacing() + 5,\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n '& img': {\n width: 220,\n // height: 100,\n },\n [theme.breakpoints.down('xs')]: {\n display: 'none',\n },\n },\n\n cardForm: {},\n\n actions: {\n display: 'flex',\n flexDirection: 'row-reverse',\n alignItems: 'center',\n '& button': {\n marginLeft: theme.spacing(),\n },\n },\n\n send: {\n display: 'flex',\n height: 215,\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n },\n\n checkCircleIcon: {\n width: 80,\n height: 80,\n [theme.breakpoints.down('xs')]: {\n width: 60,\n height: 60,\n margin: theme.spacing(2),\n },\n margin: theme.spacing(3),\n color: Colors.supportingLime[5],\n },\n})\n\ninterface OnSendProps {\n email: string\n firstName: string\n lastName: string\n}\n\ninterface InviteCardProps {\n title: string\n onCancel: () => any\n onSend: (props: OnSendProps) => any\n imgSrc: string\n}\n\nconst LoadingInvite = () => {\n const classes = useClasses()\n\n return (\n <Card className={classes.card}>\n <Spinner visible={true} />\n </Card>\n )\n}\n\nconst InviteCard: React.FC<InviteCardProps> = props => {\n const intl = useIntl()\n const inviteSubheader = intl.formatMessage(messages.inviteCardSubheader)\n const inviteFirstNameLabel = intl.formatMessage(messages.inviteFirstNameLabel)\n const inviteSurnameLabel = intl.formatMessage(messages.inviteSurnameLabel)\n const inviteSendButton = intl.formatMessage(messages.inviteSendButton)\n const inviteCancelButton = intl.formatMessage(messages.inviteCancelButton)\n const invalidEmail = intl.formatMessage(messages.inviteInvalidEmail)\n const eMailRequired = intl.formatMessage(messages.inviteEmailRequired)\n\n const { title, onCancel, onSend, imgSrc } = props\n const classes = useClasses()\n const [firstName, setFirstName] = useState('')\n const [lastName, setLastName] = useState('')\n const [email, setEmail] = useState('')\n const [error, setError] = useState(false)\n const [touched, setTouched] = useState(false)\n\n const handleChange = (e: any) => {\n setTouched(true)\n setError(false)\n setEmail(e.target.value)\n }\n\n const onBlur = () => {\n const isValidEmail = isEmail(email)\n setError(!isValidEmail)\n }\n\n return (\n <ImageCard imgUrl={imgSrc}>\n <ImageCardContent>\n <Typography variant='h5'>{title}</Typography>\n <Typography variant='caption'>{inviteSubheader}</Typography>\n <Grid\n direction='column'\n container={true}\n className={classes.innerContainer}\n >\n <FormControl>\n <TextField\n label={inviteFirstNameLabel}\n value={firstName}\n onChange={e => setFirstName(e.target.value)}\n />\n <TextField\n label={inviteSurnameLabel}\n value={lastName}\n onChange={e => setLastName(e.target.value)}\n />\n <TextField\n id='email'\n type='email'\n label={eMailRequired}\n value={email}\n onChange={handleChange}\n helperText={error ? invalidEmail : ''}\n error={error}\n onBlur={onBlur}\n autoComplete='email'\n />\n </FormControl>\n </Grid>\n </ImageCardContent>\n <ImageCardActions>\n <Button\n type='submit'\n onClick={() => onSend({ email, firstName, lastName })}\n variant='contained'\n color='secondary'\n disabled={error || !touched}\n >\n {inviteSendButton}\n </Button>\n <Button onClick={() => onCancel()}>{inviteCancelButton}</Button>\n </ImageCardActions>\n </ImageCard>\n )\n}\n\ninterface SendProps {\n onOk: () => any\n}\nconst Send: React.FC<SendProps> = props => {\n const intl = useIntl()\n\n const emailSend = intl.formatMessage(messages.inviteEmailSend)\n const emailSent = intl.formatMessage(messages.inviteEmailSent)\n const OK = intl.formatMessage(messages.inviteOk)\n\n const { onOk } = props\n return (\n <ImageCard imgUrl={Images.mail}>\n <ImageCardContent>\n <Typography variant='h5'>{emailSend}</Typography>\n <Typography variant='caption'>{emailSent}</Typography>\n </ImageCardContent>\n <ImageCardActions>\n <Button\n type='submit'\n onClick={onOk}\n variant='contained'\n color='secondary'\n >\n {OK}\n </Button>\n </ImageCardActions>\n </ImageCard>\n )\n}\n\ninterface InviteProps {\n title: string\n send: boolean\n onSend: (props: OnSendProps) => any\n onCancel: () => any\n onOk: () => any\n imgSrc?: string\n}\n\nexport const Invite: React.FC<InviteProps> = props => {\n const {\n send,\n title,\n onOk,\n onSend,\n onCancel,\n imgSrc = Images.mobileApp,\n } = props\n const adminInviteLoading = useAppState(s => s.pages.adminInvite.meta.loading)\n const trainerInviteLoading = useAppState(\n s => s.pages.trainerInvite.meta.loading\n )\n\n if (send) return <Send onOk={onOk} />\n if (adminInviteLoading || trainerInviteLoading) return <LoadingInvite />\n\n return (\n <InviteCard\n title={title}\n onCancel={onCancel}\n onSend={onSend}\n imgSrc={imgSrc}\n />\n )\n}\n","import { goBackMessage } from 'services/router/router.restate'\nimport { useDispatchHook } from 'state/store'\n\nexport function useGoBack() {\n const dispatch = useDispatchHook()\n return function () {\n dispatch(goBackMessage())\n }\n}\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useAdminInviteState = createStateHook(\n AppStoreProvider,\n state => state.pages.adminInvite\n)\nexport const useNextAdminInviteState = createNextHook(\n AppStoreProvider,\n state => state.pages.adminInvite\n)\n","import { Invite } from 'components/Invite/Invite'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport React from 'react'\nimport { useGoBack } from 'services/router/useGoBack.hook'\nimport { useDispatchHook } from 'state/store'\nimport { Images } from 'theme/Images'\nimport {\n useAdminInviteState,\n useNextAdminInviteState,\n} from './AdminInvite.restate'\nimport { useIntl } from 'react-intl'\n\nimport messages from './AdminInvite.messages'\nimport { setInstitutePageTabIndex } from 'pages/Institute/Institute.page-service'\n\nexport const AdminInvite: React.FC<{}> = () => {\n const intl = useIntl()\n const inviteCardTitle = intl.formatMessage(messages.inviteCardTitle)\n\n const dispatch = useDispatchHook()\n const goBack = useGoBack()\n const send = useAdminInviteState(s => s.send)\n const next = useNextAdminInviteState(s => s)\n return (\n <AppPageLayout title={inviteCardTitle} showBackButton>\n <Invite\n title={inviteCardTitle}\n send={send}\n onCancel={() => {\n setInstitutePageTabIndex(1)\n goBack()\n next(s => {\n s.send = false\n })\n }}\n onOk={() => {\n setInstitutePageTabIndex(1)\n goBack()\n next(s => {\n s.send = false\n })\n }}\n onSend={payload => {\n dispatch({ type: 'Page/Service/AdminInvite/Invite', payload })\n }}\n imgSrc={Images.productTearDown}\n />\n </AppPageLayout>\n )\n}\n\nexport default AdminInvite\n","import React from 'react'\nimport { makeStyles } from '@material-ui/styles'\nimport { CircularProgress, Typography } from '@material-ui/core'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\n\nconst SIZE = 75\n\nconst useClasses = makeStyles({\n box: {\n position: 'relative',\n },\n circleBackground: {\n position: 'absolute',\n color: Colors.neutrals[8],\n },\n circleForeground: {\n position: 'absolute',\n },\n text: {\n textAlign: 'center',\n },\n\n label: {\n textAlign: 'center',\n marginTop: theme.spacing(1),\n },\n})\n\ninterface CircularTrainingProgressProps {\n value: number\n label?: string\n thickness?: number\n color?: string\n size?: number\n fontSize?: number\n styles?: React.CSSProperties\n className?: string\n showLabel?: boolean\n}\n\nexport const CircularTrainingProgress: React.FC<CircularTrainingProgressProps> = props => {\n const {\n value,\n size = SIZE,\n fontSize = 16,\n color = Colors.vivid[5],\n thickness = 3,\n label = '',\n styles = {},\n className = '',\n showLabel = true,\n } = props\n const classes = useClasses()\n\n const sizeStyle = {\n height: size,\n width: size,\n }\n\n const labelStyle = {\n textAlign: 'center' as any,\n fontWeight: 'bold' as any,\n lineHeight: size + 'px',\n fontSize: fontSize + 'px',\n color: Colors.neutrals[3],\n ...sizeStyle,\n }\n\n return (\n <div style={{ width: size, ...styles }} className={className}>\n <div className={classes.box} style={sizeStyle}>\n <CircularProgress\n variant='static'\n size={SIZE}\n value={100}\n color='inherit'\n thickness={thickness}\n style={sizeStyle}\n className={classes.circleBackground}\n />\n <CircularProgress\n variant='static'\n color='inherit'\n thickness={thickness}\n size={SIZE}\n value={value}\n style={{ ...sizeStyle, color }}\n className={classes.circleForeground}\n />\n <div className={classes.text} style={labelStyle}>\n <Typography style={labelStyle as any}>\n {value}\n {'%'}\n </Typography>\n </div>\n </div>\n {showLabel && (\n <Typography\n color='inherit'\n className={classes.label}\n style={{ color: Colors.neutrals[2] }}\n >\n {label}\n </Typography>\n )}\n </div>\n )\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageTitle: {\n id: 'cp.pages.course.title',\n defaultMessage: 'Course',\n },\n rowFlow: {\n id: 'cp.pages.course.rowFlow',\n defaultMessage: 'Flow',\n },\n rowDepth: {\n id: 'cp.pages.course.rowDepth',\n defaultMessage: 'Depth',\n },\n rowRecoil: {\n id: 'cp.pages.course.rowRecoil',\n defaultMessage: 'Recoil',\n },\n rowFrequency: {\n id: 'cp.pages.course.rowFrequency',\n defaultMessage: 'Frequency',\n },\n cellDate: {\n id: 'cp.pages.course.cellDate',\n defaultMessage: 'Date',\n },\n cellDuration: {\n id: 'cp.pages.course.cellDuration',\n defaultMessage: 'Duration',\n },\n cellFeedback: {\n id: 'cp.pages.course.cellFeedback',\n defaultMessage: 'Feedback',\n },\n cellName: {\n id: 'cp.pages.course.cellName',\n defaultMessage: 'Name',\n },\n trainees: {\n id: 'cp.pages.course.trainees',\n defaultMessage: 'Trainees',\n },\n})\n","import {\n Card,\n CardContent,\n IconButton,\n Table,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@material-ui/core'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport { makeStyles } from '@material-ui/styles'\nimport { CircularTrainingProgress } from 'components/CircularTrainingProgress/CircularTrainingProgress'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport React from 'react'\nimport { FormattedDate, FormattedTime } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState } from 'state/store'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Course.messages'\n\nconst useClasses = makeStyles({\n title: {\n fontSize: 14,\n },\n location: {\n fontSize: 22,\n },\n date: {\n fontSize: 14,\n },\n\n institute: {\n fontSize: 14,\n },\n\n card: {\n minWidth: '100%',\n marginBottom: theme.spacing(2),\n },\n\n circle: {\n margin: theme.spacing(1),\n },\n})\n\nconst CoursesLoading = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n\n return (\n <AppPageLayout\n title={pageTitle}\n loading={true}\n showBackButton\n ></AppPageLayout>\n )\n}\n\nexport const Course: React.FC<{}> = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n const rowFlow = intl.formatMessage(messages.rowFlow)\n const rowDepth = intl.formatMessage(messages.rowDepth)\n const rowRecoil = intl.formatMessage(messages.rowRecoil)\n const rowFrequency = intl.formatMessage(messages.rowFrequency)\n const cellDate = intl.formatMessage(messages.cellDate)\n const cellDuration = intl.formatMessage(messages.cellDuration)\n const cellFeedback = intl.formatMessage(messages.cellFeedback)\n const cellName = intl.formatMessage(messages.cellName)\n const trainees = intl.formatMessage(messages.trainees)\n\n const course = useAppState(s => s.pages.course.course)\n const classes = useClasses()\n const goTo = useGoToHook()\n\n const navigateToTrainingPage = (id: string, idx: number) =>\n goTo(AppRoutes.Trainings, { id, idx: '' + idx })\n\n if (!course) {\n return <CoursesLoading />\n }\n\n const instituteName = course.institute.name\n\n return (\n <AppPageLayout title={pageTitle} showBackButton={true}>\n <Card className={classes.card}>\n <CardContent>\n <Typography\n className={classes.title}\n color='textSecondary'\n gutterBottom\n >\n <FormattedDate\n value={new Date(course.date)}\n year='numeric'\n month='long'\n day='2-digit'\n />{' '}\n </Typography>\n\n <Typography className={classes.location} gutterBottom>\n {course?.location}\n </Typography>\n\n <Typography className={classes.institute}>\n {course.trainees.length} {trainees}\n </Typography>\n <Typography className={classes.institute}>{instituteName}</Typography>\n {/* <Typography className={classes.institute}>{institute.address.street}</Typography> */}\n {/* <Typography className={classes.institute}>{institute.address.city}</Typography> */}\n {/* <Typography className={classes.institute}>{institute.address.country}</Typography> */}\n\n <Typography className={classes.institute}>\n {course.comment}\n </Typography>\n </CardContent>\n </Card>\n <Card className={classes.card}>\n <CardContent>\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <CircularTrainingProgress\n size={150}\n thickness={4}\n value={course.result.flowPercent}\n label={rowFlow}\n color={Colors.primary[4]}\n className={classes.circle}\n />\n <CircularTrainingProgress\n size={150}\n thickness={4}\n className={classes.circle}\n value={course.result.cprCorrectDepthPercent}\n color={Colors.vivid[3]}\n label={rowDepth}\n />\n <CircularTrainingProgress\n size={150}\n thickness={4}\n className={classes.circle}\n value={course.result.cprCorrectRecoilPercent}\n color={Colors.supportingLime[3]}\n label={rowRecoil}\n />\n <CircularTrainingProgress\n size={150}\n thickness={4}\n className={classes.circle}\n value={course.result.cprCorrectFrequencyPercent}\n color={Colors.supportingCyan[2]}\n label={rowFrequency}\n />\n </div>\n </CardContent>\n </Card>\n\n {/* {course.trainees.length > 0 && (\n <Card className={classes.card}>\n <CardContent>\n <List component='nav'>\n {course.trainees.map((trainee, idx) => (\n <>\n <ListItem>\n <ListItemText\n key={trainee.email + '_' + idx}\n secondary={trainee.email}\n primary={'Trainee #' + trainee.trainee}\n />\n </ListItem>\n </>\n ))}\n </List>\n </CardContent>\n </Card>\n )} */}\n\n <Card className={classes.card}>\n <CardContent>\n <Table>\n <TableHead>\n <TableRow>\n <TableCell>{cellDate}</TableCell>\n <TableCell>{cellName}</TableCell>\n <TableCell>{cellDuration}</TableCell>\n <TableCell>{cellFeedback}</TableCell>\n <TableCell>{rowFlow}</TableCell>\n <TableCell>{rowDepth}</TableCell>\n <TableCell>{rowRecoil}</TableCell>\n <TableCell>{rowFrequency}</TableCell>\n <TableCell></TableCell>\n </TableRow>\n </TableHead>\n\n {course.trainings.map((training, idx) => (\n <TableRow key={idx}>\n <TableCell>\n <FormattedTime\n value={new Date(training.date)}\n hour='2-digit'\n minute='2-digit'\n />\n </TableCell>\n <TableCell>\n {!training.name || training.name === ''\n ? '---'\n : training.name}\n </TableCell>\n <TableCell>{training.sessionDuration}</TableCell>\n <TableCell>{training.feedbackMode}</TableCell>\n <TableCell>{training.result.flowPercent}%</TableCell>\n <TableCell>{training.result.cprCorrectDepthPercent}%</TableCell>\n <TableCell>\n {training.result.cprCorrectRecoilPercent}%\n </TableCell>\n <TableCell>\n {training.result.cprCorrectFrequencyPercent}%\n </TableCell>\n <TableCell align='right'>\n <IconButton\n onClick={() => navigateToTrainingPage(course._id, idx)}\n >\n <RightIcon />\n </IconButton>{' '}\n </TableCell>\n </TableRow>\n ))}\n </Table>\n </CardContent>\n </Card>\n </AppPageLayout>\n )\n}\n\nexport default Course\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n emptyMessage: {\n id: 'cp.components.genericTable.emptyMessage',\n defaultMessage: 'Empty',\n },\n previousPage: {\n id: 'cp.components.genericTable.previousPage',\n defaultMessage: 'previous page',\n },\n nextPage: {\n id: 'cp.components.genericTable.nextPage',\n defaultMessage: 'next page',\n },\n multiSelect: {\n id: 'cp.components.genericTable.multiSelect',\n defaultMessage: 'select all desserts',\n },\n searchPlaceholder: {\n id: 'cp.components.genericTable.searchPlaceholder',\n defaultMessage: 'Search',\n },\n rowsPerPageLabel: {\n id: 'cp.components.genericTable.rowsPerPageLabel',\n defaultMessage: 'Rows per page:',\n },\n})\n","import React from 'react'\nimport Checkbox from '@material-ui/core/Checkbox'\nimport { createStyles, makeStyles } from '@material-ui/core/styles'\nimport TableCell from '@material-ui/core/TableCell'\nimport TableHead from '@material-ui/core/TableHead'\nimport TableRow from '@material-ui/core/TableRow'\nimport TableSortLabel from '@material-ui/core/TableSortLabel'\nimport { GenericTableCellHeader, Order } from '../GenericTable'\nimport { useIntl } from 'react-intl'\n\nimport messages from '../GenericTable.messages'\n\ninterface EnhancedTableProps {\n cellHeaders: GenericTableCellHeader[]\n checkboxEnabled?: boolean\n checkboxVisible?: boolean\n singleSelect: boolean\n numSelected: number\n onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void\n onSelectAllClick: (\n event: React.ChangeEvent<HTMLInputElement>,\n checked: boolean\n ) => void\n order: Order\n orderBy: string\n rowCount: number\n}\n\nconst useStyles = makeStyles(() =>\n createStyles({\n visuallyHidden: {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: 1,\n margin: -1,\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n top: 20,\n width: 1,\n },\n })\n)\n\nexport const EnhancedTableHead: React.FC<EnhancedTableProps> = props => {\n const intl = useIntl()\n const multiSelect = intl.formatMessage(messages.multiSelect)\n\n const {\n checkboxEnabled = true,\n onSelectAllClick,\n order,\n orderBy,\n numSelected,\n rowCount,\n onRequestSort,\n singleSelect,\n } = props\n const classes = useStyles()\n const createSortHandler = (property: string) => (\n event: React.MouseEvent<unknown>\n ) => {\n onRequestSort(event, property)\n }\n\n const { cellHeaders } = props\n\n return (\n <TableHead>\n <TableRow>\n <TableCell padding='checkbox'>\n {!singleSelect && (\n <Checkbox\n indeterminate={numSelected > 0 && numSelected < rowCount}\n checked={rowCount > 0 && numSelected === rowCount}\n onChange={onSelectAllClick}\n disabled={rowCount === 0 || !checkboxEnabled}\n inputProps={{ 'aria-label': multiSelect }}\n />\n )}\n </TableCell>\n {cellHeaders.map(headCell => (\n <TableCell\n key={headCell.id}\n align={headCell.numeric ? 'right' : 'left'}\n padding={headCell.disablePadding ? 'none' : 'normal'}\n sortDirection={orderBy === headCell.id ? order : false}\n >\n <TableSortLabel\n active={orderBy === headCell.id}\n direction={order}\n onClick={createSortHandler(headCell.id)}\n >\n {headCell.label}\n {orderBy === headCell.id ? (\n <span className={classes.visuallyHidden}>\n {order === 'desc' ? 'sorted descending' : 'sorted ascending'}\n </span>\n ) : null}\n </TableSortLabel>\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n )\n}\n","import { useAppState } from 'state/store'\n\nexport function useRTL() {\n return useAppState(state => state.i18n.locale === 'ar-SA')\n}\n","import { Input, InputAdornment } from '@material-ui/core'\nimport IconButton from '@material-ui/core/IconButton'\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles'\nimport Toolbar from '@material-ui/core/Toolbar'\nimport Typography from '@material-ui/core/Typography'\nimport ClearIcon from '@material-ui/icons/Clear'\nimport SearchIcon from '@material-ui/icons/Search'\nimport React, { useState } from 'react'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport { useRTL } from 'utils/useRTL'\n\ninterface EnhancedTableToolbarProps {\n clearSearchTerm: () => void\n numSelected: number\n searchTerm: string\n selected: string[]\n setSelected: (ids: string[]) => any\n selectedItemsMessage: React.FC<{ count: number }>\n setSearchTerm: (nextSearchTerm: string) => void\n subTitle: string\n title: string\n searchPlaceholder: string\n tools?: React.FC<{ selected: string[]; setSelected: (ids: string[]) => any }>\n}\n\nconst useToolbarStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n minHeight: 76,\n paddingLeft: theme.spacing(2),\n paddingRight: theme.spacing(1),\n display: 'grid',\n gridTemplateColumns: '1fr auto',\n },\n highlight: {\n color: Colors.black,\n backgroundColor: theme.palette.secondary.main,\n },\n actions: {\n color: theme.palette.text.secondary,\n },\n title: {},\n selectedMessage: {},\n })\n)\n\nconst DefaultTools: React.FC = () => {\n return <></>\n}\n\nexport const EnhancedTableToolbar: React.FC<EnhancedTableToolbarProps> = props => {\n const classes = useToolbarStyles()\n const {\n numSelected,\n searchTerm,\n setSearchTerm,\n clearSearchTerm,\n setSelected,\n selectedItemsMessage,\n selected,\n tools = DefaultTools,\n title = '',\n subTitle = '',\n searchPlaceholder = '',\n } = props\n\n const [originalSearchString, setOriginalSearchString] = useState('')\n\n const SelectedItemsMessage = selectedItemsMessage\n const Tools = tools\n const escapeRegExp = (string: string) => {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n\n const isRTL = useRTL()\n\n return (\n <Toolbar\n className={[classes.root, numSelected > 0 ? classes.highlight : ''].join(\n ' '\n )}\n >\n <div className={classes.title}>\n {numSelected > 0 ? (\n <Typography color='inherit' variant='subtitle1'>\n <SelectedItemsMessage count={numSelected} />\n </Typography>\n ) : (\n <div style={{ marginTop: theme.spacing(2) }}>\n <Typography variant='h5'>{title}</Typography>\n <Typography variant='subtitle1'>{subTitle}</Typography>\n </div>\n )}\n </div>\n\n <div className={classes.actions}>\n {numSelected > 0 ? (\n <Tools selected={selected} setSelected={setSelected} />\n ) : (\n <>\n <Input\n style={{ minWidth: 200 }}\n value={originalSearchString}\n placeholder={searchPlaceholder}\n onChange={event => {\n let escapedString = escapeRegExp(event.target.value)\n setSearchTerm(escapedString)\n setOriginalSearchString(event.target.value)\n }}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n {searchTerm === '' ? (\n <IconButton>\n <SearchIcon />\n </IconButton>\n ) : (\n <IconButton onClick={clearSearchTerm}>\n <ClearIcon />\n </IconButton>\n )}\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n {searchTerm === '' ? (\n <IconButton>\n <SearchIcon />\n </IconButton>\n ) : (\n <IconButton onClick={clearSearchTerm}>\n <ClearIcon />\n </IconButton>\n )}\n </InputAdornment>\n )\n }\n />\n </>\n )}\n </div>\n </Toolbar>\n )\n}\n","import Checkbox from '@material-ui/core/Checkbox'\nimport Paper from '@material-ui/core/Paper'\nimport { makeStyles, Theme } from '@material-ui/core/styles'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableCell from '@material-ui/core/TableCell'\nimport TablePagination from '@material-ui/core/TablePagination'\nimport TableRow from '@material-ui/core/TableRow'\nimport React from 'react'\nimport { EnhancedTableHead } from './components/EnhancedTableHead'\nimport { EnhancedTableToolbar } from './components/EnhancedTableToolbar'\nimport { Typography } from '@material-ui/core'\nimport { useIntl } from 'react-intl'\n\nimport messages from './GenericTable.messages'\n\nexport interface GenericTableData {\n id: string\n selected: boolean\n isSelectionEnabled: boolean\n}\n\nexport interface GenericTableCellHeader {\n id: string\n disablePadding: boolean\n label: string\n numeric: boolean\n}\n\nexport interface GenericTableDataProps<Row extends GenericTableData> {\n checkboxEnabled?: boolean\n checkboxVisible?: boolean\n rows: Row[]\n headers: GenericTableCellHeader[]\n search: (searchTerm: string) => (entry: GenericTableData) => boolean\n rowRender: React.FC<{ row: any; idx: number }>\n selectedItemsMessage: React.FC<{ count: number }>\n tools?: React.FC<{ selected: string[]; setSelected: (ids: string[]) => any }>\n singleSelect?: boolean\n initialSortProperty?: string\n initialSortDirection?: Order\n title?: string\n subTitle?: string\n emptyMessage?: string\n isScrollable?: boolean\n}\n\nexport type Order = 'asc' | 'desc'\n\nconst ROWS_PER_PAGE_OPTIONS = [5, 10, 25, 50, 100, 200]\n\ntype StyleProps = {\n isScrollable: boolean\n}\n\nconst useStyles = makeStyles((theme: Theme) => ({\n root: {\n width: '100%',\n marginTop: theme.spacing(3),\n },\n paper: {\n width: '100%',\n marginBottom: theme.spacing(2),\n },\n table: {\n minWidth: 750,\n },\n tableWrapper: ({ isScrollable }: StyleProps) => ({\n overflowX: 'auto',\n maxHeight: isScrollable ? '60vh' : 'auto',\n }),\n visuallyHidden: {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: 1,\n margin: -1,\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n top: 20,\n width: 1,\n },\n srollableTableBody: {\n overflow: 'scroll',\n },\n}))\n\nfunction sort(data: GenericTableData[], order: Order, property: string) {\n const sorted = [...data].sort((a: any, b: any) => {\n const propertyA = a[property]\n const propertyB = b[property]\n\n if (typeof propertyA === 'number' && typeof propertyB === 'number') {\n return propertyA - propertyB\n } else if (typeof propertyA === 'string' && typeof propertyB === 'string') {\n return propertyA.localeCompare(propertyB)\n } else if (\n typeof propertyA === 'boolean' &&\n typeof propertyB === 'boolean'\n ) {\n return propertyA === true ? 1 : 0\n } else if (propertyA instanceof Date && propertyB instanceof Date) {\n return propertyA.valueOf() - propertyB.valueOf()\n } else {\n return 1\n }\n })\n if (order === 'asc') {\n return sorted.reverse()\n }\n return sorted\n}\n\nconst ROW_HEIGHT = 81\n\nexport function GenericTable<Row extends GenericTableData>(\n props: GenericTableDataProps<Row>\n) {\n const intl = useIntl()\n const empty = intl.formatMessage(messages.emptyMessage)\n const previousPage = intl.formatMessage(messages.previousPage)\n const nextPage = intl.formatMessage(messages.nextPage)\n const searchPlaceholder = intl.formatMessage(messages.searchPlaceholder)\n const rowsPerPageLabel = intl.formatMessage(messages.rowsPerPageLabel)\n\n const {\n rows: data,\n search,\n headers,\n selectedItemsMessage,\n tools,\n singleSelect = false,\n checkboxEnabled = true,\n checkboxVisible = true,\n title = '',\n subTitle = '',\n emptyMessage = empty,\n initialSortProperty = headers[0].id,\n initialSortDirection = 'desc',\n isScrollable = true,\n } = props\n const classes = useStyles({ isScrollable } as StyleProps)\n const [order, setOrder] = React.useState<Order>(initialSortDirection)\n const [searchTerm, setSearchTerm] = React.useState('')\n const [orderBy, setOrderBy] = React.useState(initialSortProperty)\n const [selected, setSelected] = React.useState<string[]>([])\n const [page, setPage] = React.useState(0)\n const [rowsPerPage, setRowsPerPage] = React.useState(ROWS_PER_PAGE_OPTIONS[2])\n\n const handleRequestSort = (\n _event: React.MouseEvent<unknown>,\n property: string\n ) => {\n const isDesc = orderBy === property && order === 'desc'\n setOrder(isDesc ? 'asc' : 'desc')\n setOrderBy(property)\n }\n\n const searchFn = search(searchTerm)\n\n const handleSelectAllClick = () => {\n if (selected.length === 0) {\n const newSelected = data.filter(searchFn).map(n => n.id)\n setSelected(newSelected)\n return\n }\n setSelected([])\n }\n\n const handleClick = (_event: React.MouseEvent<unknown>, id: string) => {\n const selectedIndex = selected.indexOf(id)\n let newSelected: string[] = []\n\n if (singleSelect) {\n newSelected = selectedIndex === -1 ? [id] : []\n } else {\n if (selectedIndex === -1) {\n newSelected = newSelected.concat(selected, id)\n } else if (selectedIndex === 0) {\n newSelected = newSelected.concat(selected.slice(1))\n } else if (selectedIndex === selected.length - 1) {\n newSelected = newSelected.concat(selected.slice(0, -1))\n } else if (selectedIndex > 0) {\n newSelected = newSelected.concat(\n selected.slice(0, selectedIndex),\n selected.slice(selectedIndex + 1)\n )\n }\n }\n\n setSelected(newSelected)\n }\n\n const handleChangePage = (_event: unknown, newPage: number) => {\n setPage(newPage)\n }\n\n const handleChangeRowsPerPage = (\n event: React.ChangeEvent<HTMLInputElement>\n ) => {\n setRowsPerPage(+event.target.value)\n setPage(0)\n }\n\n const setSearch = (term: string) => {\n setSearchTerm(term)\n setPage(0)\n }\n\n const isSelected = (id: string) => selected.indexOf(id) !== -1\n const filteredRows = sort(data, order, orderBy).filter(searchFn)\n const displayRows = filteredRows.slice(\n page * rowsPerPage,\n page * rowsPerPage + rowsPerPage\n )\n\n const RowComponent = props.rowRender\n\n return (\n <div className={classes.root}>\n <Paper className={classes.paper}>\n <EnhancedTableToolbar\n selected={selected}\n setSelected={setSelected}\n numSelected={selected.length}\n searchTerm={searchTerm}\n setSearchTerm={setSearch}\n clearSearchTerm={() => setSearchTerm('')}\n selectedItemsMessage={selectedItemsMessage}\n tools={tools}\n title={title}\n subTitle={subTitle}\n searchPlaceholder={searchPlaceholder}\n />\n <div className={classes.tableWrapper}>\n <Table\n className={classes.table}\n aria-labelledby='tableTitle'\n size={'medium'}\n aria-label='table'\n stickyHeader={isScrollable}\n >\n <EnhancedTableHead\n singleSelect={singleSelect}\n cellHeaders={headers}\n checkboxEnabled={checkboxEnabled}\n numSelected={selected.length}\n order={order}\n orderBy={orderBy}\n onSelectAllClick={handleSelectAllClick}\n onRequestSort={handleRequestSort}\n rowCount={data.length}\n />\n <TableBody\n className={isScrollable ? classes.srollableTableBody : ''}\n >\n {data.length === 0 && (\n <TableRow style={{ height: rowsPerPage * ROW_HEIGHT }}>\n <TableCell colSpan={headers.length + 1} align='center'>\n <Typography variant='subtitle2'>{emptyMessage}</Typography>\n </TableCell>\n </TableRow>\n )}\n\n {displayRows.map((row, idx) => {\n const isItemSelected = isSelected(row.id)\n\n return (\n <TableRow\n hover\n role='checkbox'\n aria-checked={isItemSelected}\n tabIndex={-1}\n key={row.id}\n selected={isItemSelected}\n >\n <TableCell\n padding='checkbox'\n onClick={event => {\n if (checkboxEnabled && row.isSelectionEnabled) {\n handleClick(event, row.id)\n }\n }}\n >\n <Checkbox\n checked={isItemSelected}\n disabled={!checkboxEnabled || !row.isSelectionEnabled}\n style={{ display: checkboxVisible ? undefined : 'none' }}\n />\n </TableCell>\n <RowComponent row={row} idx={idx} />\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </div>\n <TablePagination\n rowsPerPageOptions={ROWS_PER_PAGE_OPTIONS}\n component='div'\n count={filteredRows.length}\n rowsPerPage={rowsPerPage}\n labelRowsPerPage={rowsPerPageLabel}\n page={page}\n backIconButtonProps={{\n 'aria-label': previousPage,\n }}\n nextIconButtonProps={{\n 'aria-label': nextPage,\n }}\n onPageChange={handleChangePage}\n onRowsPerPageChange={handleChangeRowsPerPage}\n />\n </Paper>\n </div>\n )\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n tableRowAssociatedTrainer: {\n id: 'cp.components.courseTable.tableRowAssociatedTrainer',\n defaultMessage: 'Associated Trainer',\n },\n tableRowProvider: {\n id: 'cp.components.courseTable.tableRowProvider',\n defaultMessage: 'Provider',\n },\n tableRowIdentifier: {\n id: 'cp.components.courseTable.tableRowIdentifier',\n defaultMessage: 'Identifier',\n },\n tableRowDate: {\n id: 'cp.components.courseTable.tableRowDate',\n defaultMessage: 'Date',\n },\n tableRowLocation: {\n id: 'cp.components.courseTable.tableRowLocation',\n defaultMessage: 'Location',\n },\n tableRowTraineeCount: {\n id: 'cp.components.courseTable.tableRowTraineeCount',\n defaultMessage: 'Trainee Count',\n },\n tableRowValue: {\n id: 'cp.components.courseTable.tableRowValue',\n defaultMessage: 'Value',\n },\n selected: {\n id: 'cp.components.courseTable.selected',\n defaultMessage: 'selected',\n },\n downloadMessage: {\n id: 'cp.components.courseTable.downloadMessage',\n defaultMessage: 'Course selected for download',\n },\n downloadCSVTitle: {\n id: 'cp.components.courseTable.downloadCSVTitle',\n defaultMessage: 'Download CSV file',\n },\n deleteLabel: {\n id: 'cp.components.courseTable.deleteLabel',\n defaultMessage: 'delete',\n },\n})\n","import { IconButton, TableCell, Tooltip, Typography } from '@material-ui/core'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport {\n GenericTable,\n GenericTableCellHeader,\n GenericTableData,\n} from 'components/GenericTable/GenericTable'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport React from 'react'\nimport { FormattedDate, FormattedMessage, useIntl } from 'react-intl'\n\nimport tableMessages from './CourseTable.messages'\nimport { useDispatchHook, useAppState } from 'state/store'\nimport { USERROLES } from '../../model/UserRole'\n\nexport interface CourseTableData extends GenericTableData {\n date: Date\n trainer: string\n trainerEmail: string\n institute: string\n identifier: string\n location: string\n traineeCount: number\n}\n\ninterface CourseTableProps {\n data: CourseTableData[]\n onCourseClick: (id: string) => any\n showInstituteCol: boolean\n showAssociatedTrainerCol: boolean\n}\n\nexport const CourseTable: React.FC<CourseTableProps> = ({\n data,\n onCourseClick,\n showInstituteCol,\n showAssociatedTrainerCol = false,\n}) => {\n const intl = useIntl()\n const tableRowProvider = intl.formatMessage(tableMessages.tableRowProvider)\n const tableRowAssociatedTrainer = intl.formatMessage(\n tableMessages.tableRowAssociatedTrainer\n )\n const tableRowIdentifier = intl.formatMessage(\n tableMessages.tableRowIdentifier\n )\n const tableRowDate = intl.formatMessage(tableMessages.tableRowDate)\n const tableRowLocation = intl.formatMessage(tableMessages.tableRowLocation)\n\n const tableRowTraineeCount = intl.formatMessage(\n tableMessages.tableRowTraineeCount\n )\n const deleteLabel = intl.formatMessage(tableMessages.deleteLabel)\n\n const dispatch = useDispatchHook()\n const userRole = useAppState(s => s.session.user.role)\n\n const search = (searchTerm: string) => {\n const splits = searchTerm.split(/\\s+/).filter(s => s !== '')\n\n if (splits.length === 0) return () => true\n\n return (entry: CourseTableData & GenericTableData) =>\n splits.every(s => {\n const searchReg = RegExp(s, 'ig')\n // Matches columns for either I-Admin or Trainer/CP-Admin\n const conditionalSortMatch = showInstituteCol\n ? searchReg.test(entry.institute)\n : showAssociatedTrainerCol\n ? searchReg.test(entry.trainerEmail)\n : false\n\n return (\n searchReg.test(entry.identifier) ||\n conditionalSortMatch ||\n searchReg.test(entry.location) ||\n searchReg.test(entry.trainer) ||\n Number.parseInt(searchTerm) >= entry.traineeCount\n )\n })\n }\n\n const deleteCourses = (ids: string[]) => {\n dispatch({ type: 'Page/Courses/Delete', payload: ids[0] })\n }\n\n const CellHeaderInstitute: GenericTableCellHeader = {\n id: 'institute',\n numeric: false,\n disablePadding: false,\n label: tableRowProvider,\n }\n\n const CellHeaderAssociatedTrainer: GenericTableCellHeader = {\n id: 'associatedTrainer',\n numeric: false,\n disablePadding: false,\n label: tableRowAssociatedTrainer,\n }\n\n const CellHeaderIdentifier: GenericTableCellHeader = {\n id: 'identifier',\n numeric: false,\n disablePadding: false,\n label: tableRowIdentifier,\n }\n const CellHeaderDate: GenericTableCellHeader = {\n id: 'date',\n numeric: false,\n disablePadding: false,\n label: tableRowDate,\n }\n\n const CellHeaderLocation: GenericTableCellHeader = {\n id: 'location',\n numeric: false,\n disablePadding: false,\n label: tableRowLocation,\n }\n\n const CellHeaderTraineeCount: GenericTableCellHeader = {\n id: 'traineeCount',\n numeric: false,\n disablePadding: false,\n label: tableRowTraineeCount,\n }\n\n const CellHeaderActions: GenericTableCellHeader = {\n id: 'actions',\n numeric: true,\n disablePadding: false,\n label: '',\n }\n\n let headers = [\n CellHeaderIdentifier,\n CellHeaderDate,\n CellHeaderLocation,\n CellHeaderTraineeCount,\n CellHeaderActions,\n ]\n\n if (showInstituteCol) {\n headers = [CellHeaderInstitute, ...headers]\n } else if (showAssociatedTrainerCol) {\n headers = [CellHeaderAssociatedTrainer, ...headers]\n }\n\n return (\n <GenericTable\n rows={data}\n headers={headers}\n search={search as any}\n initialSortProperty='date'\n initialSortDirection='asc'\n singleSelect={true}\n checkboxEnabled={userRole === USERROLES.CorPatchAdmin ? true : false}\n selectedItemsMessage={({ count }) => (\n <FormattedMessage\n id='courseTable'\n defaultMessage={`{count, number} {count, plural, one { course } other { courses }} selected`}\n values={{ count }}\n />\n )}\n rowRender={({ row }: { row: CourseTableData }) => (\n <>\n {showInstituteCol ? (\n <TableCell>\n <Typography variant='body1'>{row.trainer}</Typography>\n <Typography variant='caption'>{row.institute}</Typography>\n </TableCell>\n ) : showAssociatedTrainerCol ? (\n <TableCell>\n <Typography variant='body1'>{row.trainer}</Typography>\n <Typography variant='caption'>{row.trainerEmail}</Typography>\n </TableCell>\n ) : null}\n\n <TableCell>{row.identifier}</TableCell>\n <TableCell>\n {\n <FormattedDate\n value={row.date}\n year='numeric'\n month='2-digit'\n day='2-digit'\n />\n }\n </TableCell>\n <TableCell>{row.location}</TableCell>\n <TableCell>{row.traineeCount}</TableCell>\n <TableCell align='right'>\n <IconButton onClick={() => onCourseClick(row.id)}>\n <RightIcon />\n </IconButton>\n </TableCell>\n </>\n )}\n tools={({ selected, setSelected }) => (\n <Tooltip title={deleteLabel}>\n <IconButton\n aria-label={deleteLabel}\n onClick={() => {\n deleteCourses(selected)\n setSelected([])\n }}\n >\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n )}\n ></GenericTable>\n )\n}\n\nexport default CourseTable\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useCoursesState = createStateHook(\n AppStoreProvider,\n state => state.pages.courses\n)\nexport const useNextCoursesState = () =>\n createNextHook(AppStoreProvider, state => state.pages.courses)\n","import CourseTable from 'components/CourseTable/CourseTable'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState } from 'state/store'\nimport { Images } from 'theme/Images'\nimport { USERROLES } from '../../model/UserRole'\nimport messages from './Courses.messages'\nimport { useCoursesState } from './Courses.restate'\n\n// const useClasses = makeStyles({})\n\nconst CoursesLoading = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n\n return <AppPageLayout title={pageTitle} loading={true}></AppPageLayout>\n}\n\nconst CoursesNotFound = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n\n return (\n <PageNotFound\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.empty}\n />\n )\n}\n\nexport const Courses: React.FC<{}> = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n\n const { loading, notFound } = useCoursesState(s => s.meta)\n const { data } = useCoursesState(s => s)\n const goTo = useGoToHook()\n\n const userRole = useAppState(s => s.session.user.role)\n\n const showInstituteCol =\n userRole === USERROLES.CorPatchAdmin || userRole === USERROLES.Trainer\n\n const showAssociatedTrainerCol = userRole === USERROLES.InstituteAdmin\n\n const navigateToCoursePage = (id: string) => goTo(AppRoutes.Course, { id })\n\n if (loading) return <CoursesLoading />\n\n if (notFound) return <CoursesNotFound />\n\n return (\n <AppPageLayout title={pageTitle}>\n <CourseTable\n data={data}\n onCourseClick={navigateToCoursePage}\n showInstituteCol={showInstituteCol}\n showAssociatedTrainerCol={showAssociatedTrainerCol}\n />\n </AppPageLayout>\n )\n}\n\nexport default Courses\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useExportState = createStateHook(\n AppStoreProvider,\n state => state.pages.export\n)\nexport const useNextExportState = () =>\n createNextHook(AppStoreProvider, state => state.pages.export)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageTitle: {\n id: 'cp.pages.export.pageTitle',\n defaultMessage: 'Export Course',\n },\n})\n","import { IconButton, TableCell, Tooltip } from '@material-ui/core'\nimport DownloadIcon from '@material-ui/icons/GetAppRounded'\nimport axios from 'axios'\nimport {\n GenericTable,\n GenericTableCellHeader,\n GenericTableData,\n} from 'components/GenericTable/GenericTable'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { config } from 'config/config'\nimport { routes } from 'model/ctrl/routes'\nimport React from 'react'\nimport { FormattedDate, FormattedMessage, useIntl } from 'react-intl'\nimport RouteParser from 'route-parser'\nimport { useNextAppState, useAppState } from 'state/store'\nimport { useExportState } from './Export.restate'\nimport { ExportTableData } from './Export.state'\n\nimport messages from './Export.messages'\nimport tableMessages from '../../components/CourseTable/CourseTable.messages'\nimport { USERROLES } from '../../model/UserRole'\n\nconst cellHeaders = (\n Provider: string,\n Date: string,\n Identifier: string,\n Location: string,\n TraineeCount: string\n): GenericTableCellHeader[] => {\n return [\n { id: 'institute', numeric: false, disablePadding: false, label: Provider },\n { id: 'date', numeric: false, disablePadding: false, label: Date },\n {\n id: 'identifier',\n numeric: false,\n disablePadding: false,\n label: Identifier,\n },\n { id: 'location', numeric: false, disablePadding: false, label: Location },\n {\n id: 'traineeCount',\n numeric: false,\n disablePadding: false,\n label: TraineeCount,\n },\n ]\n}\ninterface ExportTableProps {\n data: ExportTableData[]\n download: (selected: string[]) => any\n}\n\nexport const ExportTable: React.FC<ExportTableProps> = props => {\n const intl = useIntl()\n const tableRowProvider = intl.formatMessage(tableMessages.tableRowProvider)\n const tableRowDate = intl.formatMessage(tableMessages.tableRowDate)\n const tableRowIndetifier = intl.formatMessage(\n tableMessages.tableRowIdentifier\n )\n const tableRowLocation = intl.formatMessage(tableMessages.tableRowLocation)\n const tableRowTraineeCount = intl.formatMessage(\n tableMessages.tableRowTraineeCount\n )\n const downloadMessage = intl.formatMessage(tableMessages.downloadMessage)\n const downloadCSVTitle = intl.formatMessage(tableMessages.downloadCSVTitle)\n const deleteLabel = intl.formatMessage(tableMessages.deleteLabel)\n\n const userRole = useAppState(s => s.session.user.role)\n\n const { data, download } = props\n\n const search = (searchTerm: string) => {\n const searchReg = RegExp(searchTerm, 'i')\n return (entry: ExportTableData & GenericTableData) =>\n searchReg.test(entry.institute) ||\n searchReg.test(entry.location) ||\n searchReg.test(entry.identifier)\n }\n return (\n <GenericTable\n rows={data}\n initialSortDirection='asc'\n initialSortProperty='date'\n headers={cellHeaders(\n tableRowProvider,\n tableRowDate,\n tableRowIndetifier,\n tableRowLocation,\n tableRowTraineeCount\n )}\n search={search as any}\n singleSelect={true}\n checkboxEnabled={userRole === USERROLES.CorPatchAdmin ? true : false}\n selectedItemsMessage={() => (\n <FormattedMessage id='exportTable' defaultMessage={downloadMessage} />\n )}\n rowRender={({ row }: { row: ExportTableData }) => (\n <>\n <TableCell>{row.institute}</TableCell>\n <TableCell>\n {\n <FormattedDate\n value={row.date}\n year='numeric'\n month='2-digit'\n day='2-digit'\n />\n }\n </TableCell>\n <TableCell>{row.identifier}</TableCell>\n <TableCell>{row.location}</TableCell>\n <TableCell>{row.traineeCount}</TableCell>\n </>\n )}\n tools={({ selected }) =>\n userRole === USERROLES.CorPatchAdmin ? (\n <Tooltip title={downloadCSVTitle}>\n <IconButton\n aria-label={deleteLabel}\n onClick={() => download(selected)}\n >\n <DownloadIcon />\n </IconButton>\n </Tooltip>\n ) : null\n }\n />\n )\n}\n\nexport const Export: React.FC<{}> = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n\n const { loading } = useExportState(s => s.meta)\n const courses = useExportState(s => s.courses)\n const next = useNextAppState(s => s)\n\n const download = (selected: string[]) => {\n // alert('Download ' + selected[0])\n const id = selected[0]\n const course = courses.find(course => course.id === id)\n\n let fileName = 'data.zip'\n if (course) {\n fileName = (\n course.date.toISOString().slice(0, 19) +\n '-' +\n course.institute +\n '.zip'\n ).replace(/\\s/g, '_')\n }\n\n const parser = new RouteParser(routes.export.csv)\n const path = parser.reverse({ id })\n const url = config().api + path\n\n next(state => {\n state.pages.export.meta.loading = true\n })\n\n axios({\n url,\n method: 'GET',\n responseType: 'blob',\n onDownloadProgress: props => console.log(props),\n }).then((response: any) => {\n const url = window.URL.createObjectURL(new Blob([response.data]))\n const link = document.createElement('a')\n link.href = url\n link.setAttribute('download', fileName)\n document.body.appendChild(link)\n link.click()\n next(state => {\n state.pages.export.meta.loading = false\n })\n })\n }\n\n return (\n <AppPageLayout title={pageTitle} loading={loading}>\n <ExportTable data={courses} download={download} />\n </AppPageLayout>\n )\n}\n\nexport default Export\n","import { makeStyles } from '@material-ui/styles'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\n\nexport const useStyles = makeStyles({\n card: {\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n width: '100%',\n },\n\n field: {\n marginRight: theme.spacing(),\n marginTop: theme.spacing(),\n [theme.breakpoints.down('xs')]: {\n marginRight: 0,\n width: '100%',\n },\n },\n\n actions: {\n display: 'flex',\n flexDirection: 'row-reverse',\n flexWrap: 'wrap-reverse',\n [theme.breakpoints.down('xs')]: {\n flexDirection: 'column-reverse',\n },\n },\n\n button: {\n margin: theme.spacing(1),\n },\n\n secondaryButton: {\n margin: theme.spacing(1),\n color: Colors.neutrals[4],\n },\n\n cardHeader: {},\n})\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n adminsTableTitle: {\n id: 'cp.components.instituteAdminTable.adminsTableTitle',\n defaultMessage: 'Admins',\n },\n adminsTableSubtitle: {\n id: 'cp.components.instituteAdminTable.adminsTableSubtitle',\n defaultMessage: 'Users allowed to administrate the institute',\n },\n adminsTableInviteButton: {\n id: 'cp.components.instituteAdminTable.adminsTableInviteButton',\n defaultMessage: 'Invite Admin',\n },\n adminsTableEmail: {\n id: 'cp.components.instituteAdminTable.adminsTableEmail',\n defaultMessage: 'Email',\n },\n name: {\n id: 'cp.components.instituteAdminTable.name',\n defaultMessage: 'name',\n },\n selected: {\n id: 'cp.components.instituteAdminTable.selected',\n defaultMessage: 'selected',\n },\n deleteLabel: {\n id: 'cp.components.instituteAdminTable.deleteLabel',\n defaultMessage: 'delete',\n },\n deleteAdminMessage: {\n id: 'cp.components.instituteAdminTable.deleteAdminMessage',\n defaultMessage:\n 'Do you really want to delete the selected admin? This will be permanent.',\n },\n})\n","import {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\nimport React from 'react'\n\ninterface YesNoDialogProps {\n open: boolean\n dialogTitle: string\n yesButtonTitle: string\n noButtonTitle: string\n onYesButtonClick: () => void\n onNoButtonClick: () => void\n}\n\nexport const YesNoDialog = ({\n open,\n children,\n dialogTitle,\n yesButtonTitle,\n noButtonTitle,\n onYesButtonClick,\n onNoButtonClick,\n}: React.PropsWithChildren<YesNoDialogProps>) => {\n return (\n <Dialog open={open} onClose={onNoButtonClick}>\n <DialogTitle>{dialogTitle}</DialogTitle>\n\n {children && <DialogContent>{children}</DialogContent>}\n\n <DialogActions>\n <Button onClick={onNoButtonClick}>{noButtonTitle}</Button>\n <Button variant='contained' color='primary' onClick={onYesButtonClick}>\n {yesButtonTitle}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n confirmDeleteDialogTitle: {\n id: 'cp.components.dialog.confirmDeletion.title',\n defaultMessage: 'Delete selected account?',\n },\n confirmDeleteDialogContentDescription: {\n id: 'cp.components.dialog.confirmDeletion.contentDescription',\n defaultMessage:\n 'You are about to delete an account with the following role(s):',\n },\n confirmDeleteDialogContentConclusion: {\n id: 'cp.components.dialog.confirmDeletion.contentConclusion',\n defaultMessage:\n 'The deletion is permanent. This account will no longer be available.',\n },\n deleteDialogButtonPrimary: {\n id: 'cp.pages.trainee.deleteDialogButtonPrimary',\n defaultMessage: 'Delete',\n },\n deleteDialogButtonSecondary: {\n id: 'cp.pages.trainee.deleteDialogButtonSecondary',\n defaultMessage: 'Close',\n },\n})\n","import { List, ListItem, Typography } from '@material-ui/core'\nimport { UserRole } from 'model/UserRole'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { YesNoDialog } from '../YesNoDialog/GenericConfirmDeletionDialog'\nimport messages from './Dialog.messages'\n\ninterface ConfirmDeletionDialogProps {\n open: boolean\n userRoles: UserRole[]\n onPositiveButtonClick: () => void\n onNegativeButtonClick: () => void\n}\n\nexport const ConfirmDeletionDialog = ({\n open,\n userRoles,\n onPositiveButtonClick,\n onNegativeButtonClick,\n}: ConfirmDeletionDialogProps) => {\n const intl = useIntl()\n const deleteDialogTitle = intl.formatMessage(\n messages.confirmDeleteDialogTitle\n )\n const deleteDialogContentDescription = intl.formatMessage(\n messages.confirmDeleteDialogContentDescription\n )\n const deleteDialogContentConclusion = intl.formatMessage(\n messages.confirmDeleteDialogContentConclusion\n )\n const deleteDialogButtonPrimary = intl.formatMessage(\n messages.deleteDialogButtonPrimary\n )\n const deleteDialogButtonSecondary = intl.formatMessage(\n messages.deleteDialogButtonSecondary\n )\n\n return (\n <YesNoDialog\n open={open}\n onNoButtonClick={onNegativeButtonClick}\n onYesButtonClick={onPositiveButtonClick}\n dialogTitle={deleteDialogTitle}\n yesButtonTitle={deleteDialogButtonPrimary}\n noButtonTitle={deleteDialogButtonSecondary}\n >\n <Typography>{deleteDialogContentDescription}</Typography>\n\n <List>\n {userRoles.map((role, index) => (\n <ListItem key={index}>\n <Typography>• {role}</Typography>\n </ListItem>\n ))}\n </List>\n\n <Typography gutterBottom={true}>\n {deleteDialogContentConclusion}\n </Typography>\n </YesNoDialog>\n )\n}\n","import { Button, IconButton, TableCell, Tooltip } from '@material-ui/core'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport {\n GenericTable,\n GenericTableCellHeader,\n} from 'components/GenericTable/GenericTable'\nimport { InstituteUserDto } from 'model/ctrl/institute/GetInstituteRes.schema'\nimport React, { useState } from 'react'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState, useDispatchHook, useNextAppState } from 'state/store'\nimport { theme } from 'theme/theme'\nimport { useStyles } from './useStyles'\nimport { FormattedMessage, useIntl } from 'react-intl'\n\nimport messages from './InstituteAdminTable.messages'\nimport { SelectedUserIds } from 'pages/Institute/SelectedUserIds'\nimport { ConfirmDeletionDialog } from 'components/dialogs/ConfirmDeletionDialog'\n\nconst cellHeaders = (name: string, eMail: string): GenericTableCellHeader[] => {\n return [\n { id: 'firstName', numeric: false, disablePadding: false, label: name },\n { id: 'email', numeric: false, disablePadding: false, label: eMail },\n { id: 'actions', numeric: true, disablePadding: false, label: '' },\n ]\n}\n\nconst search = (searchTerm: string) => {\n const searchReg = RegExp(searchTerm, 'i')\n return (entry: InstituteUserDto) =>\n searchReg.test(entry.firstName) ||\n searchReg.test(entry.familyName) ||\n searchReg.test(entry.email)\n}\n\nexport const InstituteAdminTable: React.FC = () => {\n const intl = useIntl()\n const tableTitle = intl.formatMessage(messages.adminsTableTitle)\n const tableSubtitle = intl.formatMessage(messages.adminsTableSubtitle)\n const name = intl.formatMessage(messages.name)\n const email = intl.formatMessage(messages.adminsTableEmail)\n const inviteButton = intl.formatMessage(messages.adminsTableInviteButton)\n const selected = intl.formatMessage(messages.selected)\n const deleteLabel = intl.formatMessage(messages.deleteLabel)\n // const deleteAdminMessage = intl.formatMessage(messages.deleteAdminMessage)\n\n const classes = useStyles()\n const goTo = useGoToHook()\n const dispatch = useDispatchHook()\n\n const instituteId = useAppState(state => state.pages.institute.id)\n const [selectedIdsToDelete, setSelectedIdsToDelete] = useState<\n SelectedUserIds\n >(null)\n const goToInvitePage = () => goTo(AppRoutes.AdminInvite, { id: instituteId })\n const next = useNextAppState(s => s.pages.institute)\n\n const admins = useAppState(state => state.pages.institute.admins).map(\n admin => ({\n id: admin._id,\n selected: false,\n isSelectionEnabled: true,\n ...admin,\n })\n )\n\n const getAdminRoles = (id: string) => {\n return admins.find(a => a._id === id)?.roles ?? []\n }\n\n const deleteAdmins = (ids: string[]) => {\n ids.forEach(id =>\n next(s => {\n s.admins = s.admins.filter(admin => admin._id !== id)\n s.trainers = s.trainers.filter(trainer => trainer._id !== id)\n })\n )\n\n dispatch({ type: 'Pages/Trainers/Delete', payload: ids })\n }\n\n const navigateToUserDetailsPage = (id: string) =>\n goTo(AppRoutes.UserDetails, { id })\n\n return (\n <>\n <div style={{ width: '100%', marginTop: theme.spacing(2) }}>\n <GenericTable\n singleSelect={true}\n title={tableTitle}\n subTitle={tableSubtitle}\n rows={admins}\n headers={cellHeaders(name, email)}\n search={search as any}\n selectedItemsMessage={({ count }) => (\n <FormattedMessage\n id='institutesTable'\n defaultMessage={`{count, number} {count, plural, one { admin } other { admins }} ${selected}`}\n // defaultMessage={deleteAdminMessage}\n values={{ count }}\n />\n )}\n rowRender={({ row }) => (\n <>\n <TableCell>\n {row.firstName} {row.familyName}\n </TableCell>\n <TableCell>{row.email}</TableCell>\n <TableCell align='right'>\n <IconButton onClick={() => navigateToUserDetailsPage(row.id)}>\n <RightIcon />\n </IconButton>\n </TableCell>\n </>\n )}\n tools={({ selected, setSelected }) => (\n <Tooltip title={deleteLabel}>\n <IconButton\n aria-label={deleteLabel}\n onClick={() => {\n setSelectedIdsToDelete({\n selectedIds: selected,\n clearSelection: () => setSelected([]),\n })\n }}\n >\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n )}\n />\n\n <ConfirmDeletionDialog\n open={\n !!selectedIdsToDelete &&\n selectedIdsToDelete?.selectedIds.length === 1\n }\n userRoles={getAdminRoles(selectedIdsToDelete?.selectedIds[0] ?? '')}\n onPositiveButtonClick={() => {\n deleteAdmins(selectedIdsToDelete?.selectedIds ?? [])\n selectedIdsToDelete?.clearSelection()\n setSelectedIdsToDelete(null)\n }}\n onNegativeButtonClick={() => {\n selectedIdsToDelete?.clearSelection()\n setSelectedIdsToDelete(null)\n }}\n />\n\n <div style={{ display: 'flex', flexDirection: 'row-reverse' }}>\n <Button\n variant='contained'\n color='secondary'\n size='small'\n className={classes.button}\n onClick={goToInvitePage}\n >\n {inviteButton}\n </Button>\n </div>\n </div>\n </>\n )\n}\n","import { AppStoreProvider } from '../../state/store'\nimport {\n ActionFactoryProps,\n createActionsHook,\n createStateHook,\n createNextHook,\n} from '@restate/core'\nimport { InstituteState } from './Institute.state'\nimport { AppMessages } from 'state/appMessages'\nimport { Locale } from '../../model/Locale'\n\nexport const useInstituteState = createStateHook(\n AppStoreProvider,\n state => state.pages.institute\n)\n\nexport const useInstituteResultConfigState = createStateHook(\n AppStoreProvider,\n state => state.pages.instituteResultConfig\n)\n\nexport const useNextInstituteState = createNextHook(\n AppStoreProvider,\n state => state.pages.institute\n)\n\nexport const useNextInstituteResultConfigState = createNextHook(\n AppStoreProvider,\n state => state.pages.instituteResultConfig\n)\n\nconst InstituteActions = ({\n next,\n}: ActionFactoryProps<InstituteState, AppMessages>) => ({\n setName(nextName: string) {\n next(state => (state.name = nextName))\n },\n setCity(nextCity: string) {\n next(state => (state.address.city = nextCity))\n },\n setPlz(nextPlz: string) {\n next(state => (state.address.zip = nextPlz))\n },\n setStreet1(nextStreet1: string) {\n next(state => (state.address.street = nextStreet1))\n },\n setCo1(nextCo1: string) {\n next(state => (state.address.co1 = nextCo1))\n },\n setState(nextState: string) {\n next(state => (state.address.state = nextState))\n },\n setCountry(nextCountry: string) {\n next(state => (state.address.country = nextCountry))\n },\n setLocale(nextLocale: Locale) {\n next(state => (state.settings.locale = nextLocale))\n },\n})\n\nexport const useInstituteActions = createActionsHook(\n AppStoreProvider,\n state => state.pages.institute,\n InstituteActions\n)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n institute: {\n id: 'cp.components.instituteForm.institute',\n defaultMessage: 'Institute',\n },\n instituteAddress: {\n id: 'cp.components.instituteForm.instituteAddress',\n defaultMessage: 'Institute Address',\n },\n instituteName: {\n id: 'cp.components.instituteForm.instituteName',\n defaultMessage: 'Name of the institute',\n },\n instituteStreet: {\n id: 'cp.components.instituteForm.instituteStreet',\n defaultMessage: 'Street and house number',\n },\n instituteStreetAdditional: {\n id: 'cp.components.instituteForm.instituteStreetAdditional',\n defaultMessage: 'Addition to address',\n },\n instituteState: {\n id: 'cp.components.instituteForm.instituteState',\n defaultMessage: 'State',\n },\n instituteZIP: {\n id: 'cp.components.instituteForm.instituteZIP',\n defaultMessage: 'Zip code',\n },\n instituteCity: {\n id: 'cp.components.instituteForm.instituteCity',\n defaultMessage: 'City',\n },\n instituteCountry: {\n id: 'cp.components.instituteForm.instituteCountry',\n defaultMessage: 'Country',\n },\n instituteSaveButton: {\n id: 'cp.components.instituteForm.instituteSaveButton',\n defaultMessage: 'Save',\n },\n instituteResultConfigBtn: {\n id: 'cp.components.instituteResultConfig.button',\n defaultMessage: 'configure result feedback',\n },\n instituteResultConfigLabelGood: {\n id: 'cp.components.instituteResultConfig.thresholdGood',\n defaultMessage: 'Threshold Good',\n },\n instituteResultConfigLabelGreat: {\n id: 'cp.components.instituteResultConfig.thresholdGreat',\n defaultMessage: 'Threshold Great',\n },\n instituteResultConfigSave: {\n id: 'cp.components.instituteResultConfig.save',\n defaultMessage: 'Save Configuration',\n },\n instituteResultConfigInfo: {\n id: 'cp.components.instituteResultConfig.info',\n defaultMessage:\n 'Be advised that changes are made on an institute-wide level.',\n },\n localeLabel: {\n id: 'cp.components.instituteForm.localeLabel',\n defaultMessage: 'Language',\n },\n localeEnglish: {\n id: 'cp.components.instituteForm.localeEnglish',\n defaultMessage: 'English',\n },\n localeGerman: {\n id: 'cp.components.instituteForm.localeGerman',\n defaultMessage: 'German',\n },\n localeDanish: {\n id: 'cp.components.instituteForm.localeDanish',\n defaultMessage: 'Danish',\n },\n localeFinish: {\n id: 'cp.components.instituteForm.localeFinish',\n defaultMessage: 'Finish',\n },\n localeItalian: {\n id: 'cp.components.instituteForm.localeItalian',\n defaultMessage: 'Italian',\n },\n localeFrench: {\n id: 'cp.components.instituteForm.localeFrench',\n defaultMessage: 'French',\n },\n localeSpanish: {\n id: 'cp.components.instituteForm.localeSpanish',\n defaultMessage: 'Spanish',\n },\n})\n","import {\n Button,\n CardContent,\n CardHeader,\n FormGroup,\n TextField,\n} from '@material-ui/core'\nimport Card from '@material-ui/core/Card'\nimport { makeStyles } from '@material-ui/styles'\nimport React, { useState } from 'react'\nimport { useDispatchHook } from 'state/store'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport {\n useInstituteActions,\n useInstituteState,\n useInstituteResultConfigState,\n useNextInstituteResultConfigState,\n} from '../Institute.restate'\nimport { useIntl } from 'react-intl'\nimport messages from './InstituteForm.messages'\nimport Modal from '@material-ui/core/Modal'\nimport InputLabel from '@material-ui/core/InputLabel'\nimport Select from '@material-ui/core/Select'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport { Locale } from '../../../model/Locale'\nimport FormControl from '@material-ui/core/FormControl'\n\nconst useStyles = makeStyles({\n card: {\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n width: '100%',\n },\n\n field: {\n marginRight: theme.spacing(),\n marginTop: theme.spacing(),\n [theme.breakpoints.down('xs')]: {\n marginRight: 0,\n width: '100%',\n },\n },\n\n button: {\n margin: theme.spacing(1),\n },\n\n secondaryButton: {\n margin: theme.spacing(1),\n color: Colors.neutrals[4],\n },\n\n modal: {\n position: 'absolute',\n height: '250',\n width: '250',\n top: '40%',\n left: '40%',\n padding: '20px',\n },\n\n cardHeader: {},\n})\n\nexport const InstituteForm = () => {\n const intl = useIntl()\n\n const institute = intl.formatMessage(messages.institute)\n const instituteAddress = intl.formatMessage(messages.instituteAddress)\n const instituteName = intl.formatMessage(messages.instituteName)\n const instituteStreet = intl.formatMessage(messages.instituteStreet)\n const instituteStreetAdditional = intl.formatMessage(\n messages.instituteStreetAdditional\n )\n const instituteState = intl.formatMessage(messages.instituteState)\n const instituteZIP = intl.formatMessage(messages.instituteZIP)\n const instituteCity = intl.formatMessage(messages.instituteCity)\n const instituteCountry = intl.formatMessage(messages.instituteCountry)\n const instituteSaveButton = intl.formatMessage(messages.instituteSaveButton)\n const instituteResultConfigLabelGood = intl.formatMessage(\n messages.instituteResultConfigLabelGood\n )\n const instituteResultConfigLabelGreat = intl.formatMessage(\n messages.instituteResultConfigLabelGreat\n )\n const instituteResultConfigSave = intl.formatMessage(\n messages.instituteResultConfigSave\n )\n const instituteResultConfigInfo = intl.formatMessage(\n messages.instituteResultConfigInfo\n )\n const instituteResultConfigBtn = intl.formatMessage(\n messages.instituteResultConfigBtn\n )\n const localeLabel = intl.formatMessage(messages.localeLabel)\n const localeEnglish = intl.formatMessage(messages.localeEnglish)\n const localeGerman = intl.formatMessage(messages.localeGerman)\n const localeDanish = intl.formatMessage(messages.localeDanish)\n const localeFinish = intl.formatMessage(messages.localeFinish)\n const localeItalian = intl.formatMessage(messages.localeItalian)\n const localeFrench = intl.formatMessage(messages.localeFrench)\n const localeSpanish = intl.formatMessage(messages.localeSpanish)\n\n const { card, field, button, modal } = useStyles()\n const state = useInstituteState(s => s)\n const instituteResultConfig = useInstituteResultConfigState(s => s)\n const instituteActions = useInstituteActions()\n const dispatch = useDispatchHook()\n\n const nextResultConfig = useNextInstituteResultConfigState(s => s)\n const [isResultConfigOpen, setResultConfigOpen] = useState(false)\n const [thresholdGood, setThresholdGood] = useState(\n instituteResultConfig.simple.thresholdGood\n )\n const [thresholdGreat, setThresholdGreat] = useState(\n instituteResultConfig.simple.thresholdGreat\n )\n const [touched, setTouched] = useState(false)\n\n const onSave = () => dispatch({ type: 'Pages/Institute/Service/Save' })\n const dispatchResultConfig = () => {\n nextResultConfig(s => {\n s.simple.thresholdGood = thresholdGood\n s.simple.thresholdGreat = thresholdGreat\n })\n dispatch({ type: 'Pages/Institute/CorPatchAdmin/ResultConfig/Save' })\n setTouched(false)\n setResultConfigOpen(false)\n }\n return (\n <div style={{ width: '100%' }}>\n <Card className={card}>\n <CardHeader title={institute} subheader={instituteAddress} />\n <CardContent>\n <FormGroup row>\n <TextField\n label={instituteName}\n required\n className={field}\n style={{ width: '100%' }}\n value={state.name}\n onChange={e => instituteActions.setName(e.target.value)}\n />\n </FormGroup>\n <FormGroup row>\n <TextField\n label={instituteStreet}\n required\n style={{ width: '100%' }}\n className={field}\n value={state.address.street}\n onChange={e => instituteActions.setStreet1(e.target.value)}\n />\n <TextField\n label={instituteStreetAdditional}\n style={{ width: '100%' }}\n className={field}\n value={state.address.co1}\n onChange={e => instituteActions.setCo1(e.target.value)}\n />\n </FormGroup>\n <FormGroup row>\n <TextField\n label={instituteCountry}\n required\n className={field}\n style={{ width: '48%' }}\n value={state.address.country}\n onChange={e => instituteActions.setCountry(e.target.value)}\n />\n <TextField\n label={instituteState}\n className={field}\n style={{ width: '48%' }}\n value={state.address.state}\n onChange={e => instituteActions.setState(e.target.value)}\n />\n </FormGroup>\n <FormGroup row>\n <TextField\n label={instituteZIP}\n required\n className={field}\n style={{ width: '34%' }}\n value={state.address.zip}\n onChange={e => instituteActions.setPlz(e.target.value)}\n />\n <TextField\n label={instituteCity}\n required\n className={field}\n style={{ width: '34%' }}\n value={state.address.city}\n onChange={e => {\n instituteActions.setCity(e.target.value)\n }}\n />\n <FormControl className={field} style={{ width: '27%' }}>\n <InputLabel id='locale-select'>{localeLabel}</InputLabel>\n <Select\n value={\n state.settings?.locale ? state.settings.locale : Locale.en\n }\n onChange={e =>\n instituteActions.setLocale(e.target.value as Locale)\n }\n labelId='locale-select'\n >\n <MenuItem value={Locale.en}>{localeEnglish}</MenuItem>\n <MenuItem value={Locale.de}>{localeGerman}</MenuItem>\n <MenuItem value={Locale.da}>{localeDanish}</MenuItem>\n <MenuItem value={Locale.fi}>{localeFinish}</MenuItem>\n <MenuItem value={Locale.it}>{localeItalian}</MenuItem>\n <MenuItem value={Locale.fr}>{localeFrench}</MenuItem>\n <MenuItem value={Locale.es}>{localeSpanish}</MenuItem>\n </Select>\n </FormControl>\n </FormGroup>\n </CardContent>\n </Card>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row-reverse',\n justifyContent: 'space-between',\n marginTop: theme.spacing(2),\n }}\n >\n <Button\n variant='contained'\n color='secondary'\n size='small'\n className={button}\n onClick={onSave}\n >\n {instituteSaveButton}\n </Button>\n <Button\n variant='contained'\n color='primary'\n size='small'\n className={button}\n onClick={() => {\n setResultConfigOpen(true)\n setThresholdGood(instituteResultConfig.simple.thresholdGood)\n setThresholdGreat(instituteResultConfig.simple.thresholdGreat)\n }}\n >\n {instituteResultConfigBtn}\n </Button>\n </div>\n\n <Modal\n open={isResultConfigOpen}\n onClose={() => setResultConfigOpen(false)}\n >\n <Card className={modal}>\n <FormGroup row>\n <TextField\n label={instituteResultConfigLabelGood}\n style={{ width: '100%' }}\n required\n type='number'\n className={field}\n value={thresholdGood}\n onChange={e => {\n if (\n Number.parseInt(e.target.value) >= 1 &&\n Number.parseInt(e.target.value) <= 100\n ) {\n setTouched(true)\n setThresholdGood(Number.parseInt(e.target.value))\n }\n }}\n />\n </FormGroup>\n <FormGroup row>\n <TextField\n label={instituteResultConfigLabelGreat}\n style={{ width: '100%' }}\n required\n type='number'\n className={field}\n value={thresholdGreat}\n onChange={e => {\n if (\n Number.parseInt(e.target.value) >= 1 &&\n Number.parseInt(e.target.value) <= 100\n ) {\n setTouched(true)\n setThresholdGreat(Number.parseInt(e.target.value))\n }\n }}\n />\n </FormGroup>\n <Button\n variant='contained'\n color='primary'\n size='small'\n style={{ margin: '10px auto', display: 'block' }}\n onClick={dispatchResultConfig}\n disabled={!touched}\n >\n {instituteResultConfigSave}\n </Button>\n <FormGroup row>\n <div\n style={{\n maxWidth: '220px',\n fontSize: '10px',\n textAlign: 'center',\n }}\n >\n {instituteResultConfigInfo}\n </div>\n </FormGroup>\n </Card>\n </Modal>\n </div>\n )\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n trainerTableName: {\n id: 'cp.components.instituteTrainerTable.name',\n defaultMessage: 'Name',\n },\n trainerTableTitle: {\n id: 'cp.components.instituteTrainerTable.title',\n defaultMessage: 'Trainers',\n },\n trainerTableSubtitle: {\n id: 'cp.components.instituteTrainerTable.subtitle',\n defaultMessage: 'All trainer of that institute',\n },\n trainerTableButton: {\n id: 'cp.components.instituteTrainerTable.button',\n defaultMessage: 'Invite Trainer',\n },\n tableRowsStreet: {\n id: 'cp.components.instituteTrainerTable.tableRowsStreet',\n defaultMessage: 'Street',\n },\n trainerEmptyMessage: {\n id: 'cp.components.instituteTrainerTable.trainerEmptyMessage',\n defaultMessage: 'No trainers yet',\n },\n selected: {\n id: 'cp.components.instituteTrainerTable.selected',\n defaultMessage: 'selected',\n },\n deleteLabel: {\n id: 'cp.components.instituteTrainerTable.deleteLabel',\n defaultMessage: 'delete',\n },\n deleteTrainerMessage: {\n id: 'cp.components.instituteAdminTable.deleteTrainerMessage',\n defaultMessage:\n 'Do you really want to delete the selected trainer? This will be permanent.',\n },\n})\n","import { Button, IconButton, TableCell, Tooltip } from '@material-ui/core'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport {\n GenericTable,\n GenericTableCellHeader,\n} from 'components/GenericTable/GenericTable'\nimport { InstituteUserDto } from 'model/ctrl/institute/GetInstituteRes.schema'\nimport React, { useState } from 'react'\nimport { FormattedMessage, useIntl } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState, useDispatchHook, useNextAppState } from 'state/store'\nimport { theme } from 'theme/theme'\nimport { useStyles } from './useStyles'\nimport DeleteIcon from '@material-ui/icons/Delete'\n\nimport messages from './InstituteTrainerTable.messages'\nimport { SelectedUserIds } from 'pages/Institute/SelectedUserIds'\nimport { ConfirmDeletionDialog } from 'components/dialogs/ConfirmDeletionDialog'\n\nconst cellHeaders = (\n Street: string,\n Name: string\n): GenericTableCellHeader[] => {\n return [\n { id: 'firstName', numeric: false, disablePadding: false, label: Name },\n { id: 'email', numeric: false, disablePadding: false, label: Street },\n { id: 'actions', numeric: true, disablePadding: false, label: '' },\n ]\n}\n\nconst search = (searchTerm: string) => {\n const searchReg = RegExp(searchTerm, 'i')\n return (entry: InstituteUserDto) =>\n searchReg.test(entry.firstName) ||\n searchReg.test(entry.familyName) ||\n searchReg.test(entry.email)\n}\n\nexport const InstituteTrainerTable: React.FC = () => {\n const intl = useIntl()\n const trainerTableTitle = intl.formatMessage(messages.trainerTableTitle)\n const trainerTableSubtitle = intl.formatMessage(messages.trainerTableSubtitle)\n const trainerTableButton = intl.formatMessage(messages.trainerTableButton)\n const tableRowsStreet = intl.formatMessage(messages.tableRowsStreet)\n const name = intl.formatMessage(messages.trainerTableName)\n const trainerEmptyMessage = intl.formatMessage(messages.trainerEmptyMessage)\n const selected = intl.formatMessage(messages.selected)\n const deleteLabel = intl.formatMessage(messages.deleteLabel)\n // const deleteTrainerMessage = intl.formatMessage(messages.deleteTrainerMessage)\n\n const classes = useStyles()\n const goTo = useGoToHook()\n const dispatch = useDispatchHook()\n const instituteId = useAppState(state => state.pages.institute.id)\n const [selectedIdsToDelete, setSelectedIdsToDelete] = useState<\n SelectedUserIds\n >(null)\n const goToTrainerInvitePage = () =>\n goTo(AppRoutes.TrainerInvite, { id: instituteId })\n const next = useNextAppState(s => s.pages.institute)\n\n const navigateToUserDetailsPage = (id: string) =>\n goTo(AppRoutes.UserDetails, { id })\n\n const trainers = useAppState(state => state.pages.institute.trainers).map(\n trainer => ({\n id: trainer._id,\n selected: false,\n isSelectionEnabled: true,\n ...trainer,\n })\n )\n\n const getTrainerRoles = (id: string) => {\n return trainers.find(t => t._id === id)?.roles ?? []\n }\n\n const deleteTrainers = (ids: string[]) => {\n ids.forEach(id => {\n next(s => {\n s.admins = s.admins.filter(admin => admin._id !== id)\n s.trainers = s.trainers.filter(trainer => trainer._id !== id)\n })\n })\n\n dispatch({ type: 'Pages/Trainers/Delete', payload: ids })\n }\n return (\n <>\n <div style={{ width: '100%', marginTop: theme.spacing(2) }}>\n <GenericTable\n title={trainerTableTitle}\n subTitle={trainerTableSubtitle}\n rows={trainers}\n headers={cellHeaders(tableRowsStreet, name)}\n singleSelect={true}\n search={search as any}\n emptyMessage={trainerEmptyMessage}\n selectedItemsMessage={({ count }) => (\n <FormattedMessage\n id='institutesTable'\n defaultMessage={`{count, number} {count, plural, one { trainer } other { trainers }} ${selected}`}\n // defaultMessage={deleteTrainerMessage}\n values={{ count }}\n />\n )}\n rowRender={({ row }) => (\n <>\n <TableCell>\n {row.firstName} {row.familyName}\n </TableCell>\n <TableCell>{row.email}</TableCell>\n <TableCell align='right'>\n <IconButton onClick={() => navigateToUserDetailsPage(row.id)}>\n <RightIcon />\n </IconButton>\n </TableCell>\n </>\n )}\n tools={({ selected, setSelected }) => (\n <Tooltip title={deleteLabel}>\n <IconButton\n aria-label={deleteLabel}\n onClick={() => {\n setSelectedIdsToDelete({\n selectedIds: selected,\n clearSelection: () => setSelected([]),\n })\n }}\n >\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n )}\n />\n\n <ConfirmDeletionDialog\n open={\n !!selectedIdsToDelete &&\n selectedIdsToDelete?.selectedIds.length === 1\n }\n userRoles={getTrainerRoles(selectedIdsToDelete?.selectedIds[0] ?? '')}\n onPositiveButtonClick={() => {\n deleteTrainers(selectedIdsToDelete?.selectedIds ?? [])\n selectedIdsToDelete?.clearSelection()\n setSelectedIdsToDelete(null)\n }}\n onNegativeButtonClick={() => {\n selectedIdsToDelete?.clearSelection()\n setSelectedIdsToDelete(null)\n }}\n />\n\n <div style={{ display: 'flex', flexDirection: 'row-reverse' }}>\n <Button\n variant='contained'\n color='secondary'\n size='small'\n className={classes.button}\n onClick={goToTrainerInvitePage}\n >\n {trainerTableButton}\n </Button>\n </div>\n </div>\n </>\n )\n}\n","import { makeStyles } from '@material-ui/styles'\nimport AppDrawer from 'components/AppDrawer/AppDrawer'\nimport Footer from 'components/Footer/Footer'\nimport { NavBar } from 'components/NavBar/NavBar'\nimport { Spinner } from 'components/Spinner/Spinner'\nimport React from 'react'\nimport { theme } from 'theme/theme'\nimport { MainPageLayout } from './MainPageLayout'\nimport { Tabs, Tab } from '@material-ui/core'\n\nconst useStyles = makeStyles({\n scroller: {\n height: '100%',\n width: '100%',\n overflow: 'auto',\n display: 'flex',\n flexDirection: 'column',\n },\n\n container: {\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n flexGrow: 1,\n },\n\n content: {\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(2),\n marginRight: theme.spacing(2),\n\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n maxWidth: 800,\n flexGrow: 1,\n\n [theme.breakpoints.down('xs')]: {\n marginTop: 0,\n marginLeft: 0,\n marginRight: 0,\n maxWidth: 'auto',\n width: '100%',\n },\n },\n})\n\ninterface TabsPageLayoutProps {\n title: string\n loading?: boolean\n showBackButton?: boolean\n tabs: string[]\n tabIdx: number\n onTabChange: (idx: number) => any\n}\n\nexport const TabsPageLayout: React.FunctionComponent<TabsPageLayoutProps> = props => {\n const classes = useStyles()\n const {\n loading = false,\n title,\n showBackButton = false,\n tabs,\n tabIdx,\n onTabChange,\n } = props\n\n const handleChange = (_event: React.ChangeEvent<{}>, newTabIndex: number) => {\n onTabChange(newTabIndex)\n }\n\n return (\n <MainPageLayout title={title}>\n <NavBar title={title} showBackButton={showBackButton} />\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <Tabs\n value={tabIdx}\n onChange={handleChange}\n indicatorColor='primary'\n textColor='primary'\n >\n {tabs.map((tab, index) => (\n <Tab key={index} label={tab} />\n ))}\n </Tabs>\n </div>\n\n <AppDrawer />\n\n <div className={classes.scroller}>\n <div className={classes.container}>\n <div className={classes.content}>\n <Spinner visible={loading || false} />\n {props.children}\n </div>\n </div>\n <div style={{ flexGrow: 1 }} />\n <Footer />\n </div>\n </MainPageLayout>\n )\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n active: {\n id: 'cp.pages.instituteAdminShares.active',\n defaultMessage: 'Active',\n },\n deleted: {\n id: 'cp.pages.instituteAdminShares.deleted',\n defaultMessage: 'Deleted',\n },\n pageTitle: {\n id: 'cp.pages.instituteAdminShares.pageTitle',\n defaultMessage: 'Shares',\n },\n pageTitleNotFound: {\n id: 'cp.pages.instituteAdminShares.pageTitleNotFound',\n defaultMessage: 'Not found',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.instituteAdminShares.pageNotFoundMessage',\n defaultMessage: 'The shares you are looking for do not exists.',\n },\n noActiveSharingObjectsMessage: {\n id: 'cp.pages.instituteAdminShares.noActiveSharingObjectsMessage',\n defaultMessage: 'Currently, you have not active sharing objects.',\n },\n noDeletedSharingObjectsMessage: {\n id: 'cp.pages.instituteAdminShares.noDeletedSharingObjectsMessage',\n defaultMessage: 'No deleted sharing objects.',\n },\n startDate: {\n id: 'cp.pages.instituteAdminShares.startDate',\n defaultMessage: 'Start: ',\n },\n endDate: {\n id: 'cp.pages.instituteAdminShares.endDate',\n defaultMessage: 'End: ',\n },\n})\n","import {\n Card,\n CardContent,\n CardHeader,\n Fab,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableRow,\n Typography,\n makeStyles,\n} from '@material-ui/core'\nimport AddIcon from '@material-ui/icons/Add'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useDispatchHook } from 'state/store'\nimport { useInstituteState } from '../Institute.restate'\nimport messages from '../../InstituteAdminShares/InstituteAdminShares.messages'\n\nconst useClasses = makeStyles(theme => ({\n table: {\n [theme.breakpoints.up('md')]: {\n minWidth: 600,\n },\n },\n fab: {\n margin: theme.spacing(1),\n position: 'fixed',\n bottom: 10,\n right: 10,\n },\n startDate: {\n fontSize: '0.8rem',\n color: theme.palette.grey[500],\n },\n}))\n\nexport function InstituteSharingObjects() {\n const sharingObjects = useInstituteState(s => s.sharingObjects)\n const classes = useClasses()\n const intl = useIntl()\n\n const activeSharingObjects = sharingObjects.filter(\n sharingObject => sharingObject.meta.deletedAt === null\n )\n\n const deactivatedSharingObjects = sharingObjects.filter(\n sharingObject => sharingObject.meta.deletedAt !== null\n )\n\n const hasActiveSharingObjects = activeSharingObjects.length > 0\n const hasDeactivatedSharingObjects = deactivatedSharingObjects.length > 0\n\n return (\n <>\n <Card>\n <CardHeader title={'Active'} />\n <CardContent>\n <Table size={'small'} className={classes.table}>\n <TableBody>\n {!hasActiveSharingObjects && (\n <Typography>{intl.formatMessage(messages.noActiveSharingObjectsMessage)}</Typography>\n )}\n {hasActiveSharingObjects &&\n activeSharingObjects.map(sharingObject => (\n <SharingObjectRow sharingObject={sharingObject} />\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n\n <Card style={{ marginTop: 20 }}>\n <CardHeader title={'Deleted'} />\n <CardContent>\n <Table size={'small'} className={classes.table}>\n <TableBody>\n {!hasDeactivatedSharingObjects && (\n <Typography>{intl.formatMessage(messages.noDeletedSharingObjectsMessage)}</Typography>\n )}\n {hasDeactivatedSharingObjects &&\n deactivatedSharingObjects.map(sharingObject => (\n <SharingObjectRow sharingObject={sharingObject} disabled />\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n <AddButton />\n </>\n )\n}\n\nfunction SharingObjectRow(props: {\n sharingObject: SharingObjectDocument\n disabled?: boolean\n}) {\n const { sharingObject, disabled = false } = props\n const classes = useClasses()\n const intl = useIntl()\n\n const goTo = useGoToHook()\n const navigateToSharingObject = () =>\n goTo(AppRoutes.SharingObject, { id: sharingObject._id })\n\n return (\n <TableRow>\n <TableCell style={{ height: 60 }}>\n <div>{sharingObject.name}</div>\n <div className={classes.startDate}>\n Start: {intl.formatDate(sharingObject.meta.createdAt)}\n </div>\n {sharingObject.meta.deletedAt && (\n <div className={classes.startDate}>\n End: {intl.formatDate(sharingObject.meta.deletedAt)}\n </div>\n )}\n </TableCell>\n <TableCell align='right'>\n {!disabled && (\n <IconButton onClick={navigateToSharingObject}>\n <RightIcon />\n </IconButton>\n )}\n </TableCell>\n </TableRow>\n )\n}\n\nfunction AddButton() {\n const { fab } = useClasses()\n const dispatch = useDispatchHook()\n\n function onClick() {\n dispatch({ type: 'Pages/Institute/CorPatchAdmin/Sharing/Create' })\n }\n\n return (\n <Fab\n className={fab}\n color='secondary'\n aria-label='Add institute'\n onClick={onClick}\n >\n <AddIcon />\n </Fab>\n )\n}\n","import { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React, { useState } from 'react'\nimport { InstituteAdminTable } from './components/InstituteAdminTable'\nimport { InstituteForm } from './components/InstituteForm'\nimport { InstituteTrainerTable } from './components/InstituteTrainerTable'\nimport { useInstituteState } from './Institute.restate'\nimport { Typography } from '@material-ui/core'\nimport { TabsPageLayout } from 'components/layouts/TabsPageLayout'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Institute.messages'\nimport { institutePageTabIndex } from './Institute.page-service'\nimport { InstituteSharingObjects } from './components/InstituteSharingObject'\n\ninterface TabPanelProps {\n index: number\n value: number\n}\n\nconst TabPanel: React.FC<TabPanelProps> = props => {\n const { value, index, children } = props\n return (\n <Typography\n component='div'\n role='tabpanel'\n hidden={value !== index}\n id={`wrapped-tabpanel-${index}`}\n aria-labelledby={`wrapped-tab-${index}`}\n >\n {value === index && <>{children}</>}\n </Typography>\n )\n}\n\nexport const Institute = () => {\n const intl = useIntl()\n const Base = intl.formatMessage(messages.tabsBase)\n const Admins = intl.formatMessage(messages.tabsAdmins)\n const Trainers = intl.formatMessage(messages.tabsTrainers)\n const institutePageNotFoundTitle = intl.formatMessage(\n messages.institutePageNotFoundTitle\n )\n const institutePageNotFoundMessage = intl.formatMessage(\n messages.institutePageNotFoundMessage\n )\n const institute = intl.formatMessage(messages.institute)\n const tabs = [Base, Admins, Trainers, 'Sharing']\n\n const state = useInstituteState(s => s)\n const [tabIndex, setTabIndex] = useState(institutePageTabIndex)\n\n if (state.meta.loading) {\n return (\n <TabsPageLayout\n title={institute}\n showBackButton={true}\n tabIdx={tabIndex}\n tabs={tabs}\n onTabChange={idx => setTabIndex(idx)}\n loading={true}\n />\n )\n }\n\n if (state.meta.notFound) {\n return (\n <PageNotFound\n title={institutePageNotFoundTitle}\n message={institutePageNotFoundMessage}\n />\n )\n }\n\n return (\n <TabsPageLayout\n title={institute}\n showBackButton={true}\n tabIdx={tabIndex}\n tabs={tabs}\n onTabChange={idx => setTabIndex(idx)}\n >\n <TabPanel value={tabIndex} index={0}>\n <InstituteForm />\n </TabPanel>\n\n <TabPanel value={tabIndex} index={1}>\n <InstituteAdminTable />\n </TabPanel>\n\n <TabPanel value={tabIndex} index={2}>\n <InstituteTrainerTable />\n </TabPanel>\n\n <TabPanel value={tabIndex} index={3}>\n <InstituteSharingObjects />\n </TabPanel>\n </TabsPageLayout>\n )\n}\n\nexport default Institute\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n tableRowName: {\n id: 'cp.pages.institutesTable.tableRowName',\n defaultMessage: 'Name',\n },\n tableRowStreet: {\n id: 'cp.pages.institutesTable.tableRowStreet',\n defaultMessage: 'Street',\n },\n tableRowCity: {\n id: 'cp.pages.institutesTable.tableRowCity',\n defaultMessage: 'City',\n },\n tableRowZIP: {\n id: 'cp.pages.institutesTable.tableRowZIP',\n defaultMessage: 'ZIP',\n },\n tableRowCountry: {\n id: 'cp.pages.institutesTable.tableRowCountry',\n defaultMessage: 'Country',\n },\n institutesLowercase: {\n id: 'cp.pages.institutesTable.institutesLowercase',\n defaultMessage: 'institutes',\n },\n instituteLowercase: {\n id: 'cp.pages.institutesTable.instituteLowercase',\n defaultMessage: 'institute',\n },\n deleteWarning: {\n id: 'cp.pages.institutesTable.deleteWarning',\n defaultMessage:\n 'Do you want to delete the selected institute? All associated accounts and data will be lost!',\n },\n})\n","import { ActionFactoryProps, createActionsHook } from '@restate/core'\nimport {\n AppStoreProvider,\n useAppState,\n useNextAppState,\n} from '../../state/store'\nimport { InstitutesState } from './Institutes.state'\nimport { AppMessages } from 'state/appMessages'\n\nexport const useInstitutesState = () =>\n useAppState(state => state.pages.institutes)\nexport const useNextInstituteState = () =>\n useNextAppState(state => state.pages.institutes)\n\nconst InstitutesActions = (\n _props: ActionFactoryProps<InstitutesState, AppMessages>\n) => {\n // const { dispatch } = props\n\n return {\n newInstitute() {\n // dispatch()\n },\n }\n}\n\nexport const useInstitutesAction = createActionsHook(\n AppStoreProvider,\n state => state.pages.institutes,\n InstitutesActions\n)\n\n// export const InstitutePageService = (store:AppStore) {\n","import { Button, Fab, IconButton, TableCell, Tooltip } from '@material-ui/core'\nimport AddIcon from '@material-ui/icons/Add'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n GenericTable,\n GenericTableCellHeader,\n GenericTableData,\n} from 'components/GenericTable/GenericTable'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { InstituteServiceMessageType } from 'services/institutes/institutes.service'\nimport { useDispatchHook, useNextAppState } from 'state/store'\nimport { Colors } from 'theme/colors'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { useInstitutesState } from './Institutes.restate'\nimport { InstituteEntry } from './Institutes.state'\nimport { FormattedMessage, useIntl } from 'react-intl'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { AppRoutes } from 'routes'\n\nimport messages from './Institutes.messages'\nimport tableMessages from './InstitutesTable.messages'\n\nconst useClasses = makeStyles({\n institutes: {\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: 'center',\n marginBottom: 100,\n },\n\n instituteCard: {\n width: '30vw',\n margin: theme.spacing(1),\n [theme.breakpoints.down('xs')]: {\n width: '100%',\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n marginLeft: 0,\n marginRight: 0,\n },\n },\n instituteEntryActions: {\n display: 'flex',\n flexDirection: 'row-reverse',\n padding: theme.spacing(1),\n },\n fab: {\n margin: theme.spacing(1),\n position: 'fixed',\n bottom: 10,\n right: 10,\n },\n subheader: {\n color: Colors.neutrals[3],\n fontWeight: 'bold',\n fontSize: '1.1rem',\n },\n})\n\nconst CreateInstituteActions: React.FC<{}> = () => {\n const intl = useIntl()\n const addInstituteButton = intl.formatMessage(messages.addInstituteButton)\n\n const dispatch = useDispatchHook()\n const onClick = () => dispatch({ type: InstituteServiceMessageType.Create })\n return (\n <Button variant='contained' color='secondary' onClick={onClick}>\n {addInstituteButton}\n </Button>\n )\n}\n\nconst AddButton = () => {\n const classes = useClasses()\n const dispatch = useDispatchHook()\n const onClick = () => dispatch({ type: InstituteServiceMessageType.Create })\n\n return (\n <Fab\n color='secondary'\n aria-label='Add institute'\n className={classes.fab}\n onClick={onClick}\n >\n <AddIcon />\n </Fab>\n )\n}\n\nconst cellHeaders = (\n Name: string,\n Street: string,\n City: string,\n ZIP: string,\n Country: string\n): GenericTableCellHeader[] => {\n const cellHeaders: GenericTableCellHeader[] = [\n { id: 'institute', numeric: false, disablePadding: false, label: Name },\n { id: 'street', numeric: false, disablePadding: false, label: Street },\n { id: 'city', numeric: false, disablePadding: false, label: City },\n { id: 'zip', numeric: false, disablePadding: false, label: ZIP },\n { id: 'country', numeric: false, disablePadding: false, label: Country },\n { id: 'actions', numeric: true, disablePadding: false, label: '' },\n ]\n return cellHeaders\n}\n\ntype InstitutesTableData = InstituteEntry & GenericTableData\n\nexport const Institutes: React.FC<{}> = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n const pageTitle = intl.formatMessage(messages.pageTitle)\n const tableRowName = intl.formatMessage(tableMessages.tableRowName)\n const tableRowStreet = intl.formatMessage(tableMessages.tableRowStreet)\n const tableRowCity = intl.formatMessage(tableMessages.tableRowCity)\n const tableRowZIP = intl.formatMessage(tableMessages.tableRowZIP)\n const tableRowCountry = intl.formatMessage(tableMessages.tableRowCountry)\n const deleteWarning = intl.formatMessage(tableMessages.deleteWarning)\n const deleteLabel = intl.formatMessage(messages.deleteLabel)\n\n const goTo = useGoToHook()\n const next = useNextAppState(s => s.pages.institutes)\n const dispatch = useDispatchHook()\n\n const { entries, meta } = useInstitutesState()\n const rows: InstitutesTableData[] = entries\n .map(entry => ({ \n id: entry._id,\n selected: false, \n isSelectionEnabled: true,\n ...entry, \n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n\n const empty = entries.length === 0\n const { loading } = meta\n\n const search = (searchTerm: string) => {\n const searchReg = RegExp(searchTerm, 'i')\n return (entry: InstitutesTableData) =>\n searchReg.test(entry.name) ||\n searchReg.test(entry.city) ||\n searchReg.test(entry.country) ||\n searchReg.test(entry.zip) ||\n searchReg.test(entry.street)\n }\n\n if (loading) {\n return <AppPageLayout title={pageTitle} loading={true} />\n } else if (empty) {\n return (\n <PageNotFound\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.teacher}\n action={() => <CreateInstituteActions />}\n />\n )\n }\n\n const goToInstitutePage = (id: string) => goTo(AppRoutes.Institute, { id })\n const deleteInstitute = (ids: string[]) => {\n const id = ids[0]\n next(s => {\n s.entries = s.entries.filter(institute => institute._id !== id)\n })\n\n dispatch({ type: InstituteServiceMessageType.Delete, payload: id })\n }\n\n return (\n <>\n <AppPageLayout title={pageTitle}>\n <GenericTable\n rows={rows}\n headers={cellHeaders(\n tableRowName,\n tableRowStreet,\n tableRowCity,\n tableRowZIP,\n tableRowCountry\n )}\n search={search as any}\n selectedItemsMessage={({ count }) => (\n <FormattedMessage\n id='institutesTable'\n defaultMessage={deleteWarning}\n values={{ count }}\n />\n )}\n rowRender={({ row }) => (\n <>\n <TableCell>{row.name}</TableCell>\n <TableCell>{row.street}</TableCell>\n <TableCell>{row.city}</TableCell>\n <TableCell>{row.zip}</TableCell>\n <TableCell>{row.country}</TableCell>\n <TableCell align='right'>\n <IconButton onClick={() => goToInstitutePage(row.id)}>\n <RightIcon />\n </IconButton>\n </TableCell>\n </>\n )}\n singleSelect={true}\n tools={({ selected, setSelected }) => (\n <Tooltip title={deleteLabel}>\n <IconButton\n aria-label={deleteLabel}\n onClick={() => {\n deleteInstitute(selected)\n setSelected([])\n }}\n >\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n )}\n />\n <AddButton />\n </AppPageLayout>\n </>\n )\n}\n\nexport default Institutes\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n serverErrorTitle: {\n id: 'cp.pages.internalServerError.title',\n defaultMessage: 'Oh no! Something went wrong!',\n },\n serverErrorMessage: {\n id: 'cp.pages.internalServerError.message',\n defaultMessage:\n 'The server was not able to complete the request. This is on us. Please try again later. ',\n },\n serverErrorButton: {\n id: 'cp.pages.internalServerError.button',\n defaultMessage: 'Try again',\n },\n})\n","import { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { Images } from 'theme/Images'\nimport { Button } from '@material-ui/core'\nimport { useGoBack } from 'services/router/useGoBack.hook'\nimport { useIntl } from 'react-intl'\n\nimport messages from './InternalServerError.messages'\n\nexport const InternalServerError: React.FC<{}> = () => {\n const intl = useIntl()\n const serverErrorTitle = intl.formatMessage(messages.serverErrorTitle)\n const serverErrorMessage = intl.formatMessage(messages.serverErrorTitle)\n const serverErrorButton = intl.formatMessage(messages.serverErrorButton)\n\n const goBack = useGoBack()\n return (\n <PageNotFound\n variant='public'\n title={serverErrorTitle}\n message={serverErrorMessage}\n img={Images.bugFix}\n action={() => (\n <Button color='secondary' variant='contained' onClick={goBack}>\n {serverErrorButton}\n </Button>\n )}\n />\n )\n}\n\nexport default InternalServerError\n","import { ActionFactoryProps, createActionsHook } from '@restate/core'\nimport { FormEvent } from 'react'\nimport { LoginMessage, LoginService } from 'services/login/login.service'\nimport { AppMessages } from 'state/appMessages'\nimport {\n AppStoreProvider,\n useAppState,\n useNextAppState,\n} from '../../state/store'\nimport { isEmail } from '../../utils/isEmail'\nimport { LoginState } from './Login.state'\n\nexport const useLoginState = () => useAppState(state => state.pages.login)\nexport const useNextLoginState = () =>\n useNextAppState(state => state.pages.login)\n\nconst LoginActions = ({\n next,\n dispatch,\n state,\n}: ActionFactoryProps<LoginState, AppMessages>) => ({\n setPassword(password: string) {\n next(loginState => (loginState.password = password))\n },\n setEmail(email: string) {\n next(loginState => (loginState.email = email))\n },\n\n signIn(event: FormEvent<HTMLFormElement>) {\n event.preventDefault()\n const { email, password } = state()\n\n const isValid = isEmail(email) && password !== ''\n\n if (!isValid) {\n return\n }\n\n const loginMessage: LoginMessage = {\n type: LoginService.Login,\n payload: {\n email,\n password,\n },\n }\n dispatch(loginMessage)\n },\n})\n\nexport const useLoginActions = createActionsHook(\n AppStoreProvider,\n state => state.pages.login,\n LoginActions\n)\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n email: {\n id: 'cp.pages.passwordForgot.eMail',\n defaultMessage: 'E-Mail',\n },\n passwordForgotConfirmationMessage: {\n id: 'cp.pages.passwordForgot.confirmationMessage',\n defaultMessage: 'The verification e-mail wil be send to your account.',\n },\n passwordForgotConfirmationMessage2: {\n id: 'cp.pages.passwordForgot.confirmationMessage2',\n defaultMessage: 'Please check it.',\n },\n passwordForgotConfirmationTitle: {\n id: 'cp.pages.passwordForgot.confirmationTitle',\n defaultMessage: 'Reset your Password',\n },\n passwordForgotConfirmationSent: {\n id: 'cp.pages.passwordForgot.confirmationSent',\n defaultMessage: 'Send E-Mail',\n },\n passwordForgotBackToLogin: {\n id: 'cp.pages.passwordForgot.passwordForgotBackToLogin',\n defaultMessage: 'Back to login',\n },\n passwordForgotConfirmationSendMessage: {\n id: 'cp.pages.passwordForgot.confirmationSendMessage',\n defaultMessage: 'We send you an email with an approval link to',\n },\n passwordForgotTitle: {\n id: 'cp.pages.passwordForgot.passwordForgotTitle',\n defaultMessage: 'Password forgot',\n },\n})\n","import { makeStyles } from '@material-ui/styles'\nimport React, { FormEvent } from 'react'\nimport { theme } from 'theme/theme'\nimport { useLoginState, useLoginActions } from 'pages/Login/Login.restate'\nimport {\n Grid,\n FormControl,\n InputLabel,\n Input,\n InputAdornment,\n Card,\n CardContent,\n CardActions,\n Button,\n Typography,\n CircularProgress,\n} from '@material-ui/core'\nimport { FormattedMessage } from 'react-intl'\nimport EmailIcon from '@material-ui/icons/Email'\nimport { Colors } from 'theme/colors'\nimport CheckCircleIcon from '@material-ui/icons/CheckCircle'\nimport { PublicPageLayout } from 'components/layouts/PublicPageLayout'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useDispatchHook, useAppState } from 'state/store'\nimport { useIntl } from 'react-intl'\n\nimport messages from './LoginPasswordForrgot.messages'\nimport { isEmail } from 'utils/isEmail'\nimport { useRTL } from 'utils/useRTL'\n\nconst useClasses = makeStyles({\n submitButton: {\n marginTop: 40,\n },\n\n innerContainer: {\n marginTop: theme.spacing(3),\n marginBottom: theme.spacing(5),\n height: 'auto',\n [theme.breakpoints.down('xs')]: {\n height: 'auto',\n },\n },\n\n error: {\n ...theme.typography.h6,\n color: theme.palette.error.dark,\n padding: theme.spacing(),\n fontSize: '1rem',\n backgroundColor: theme.palette.grey[50],\n border: '1px solid ' + theme.palette.primary.dark,\n },\n\n center: {\n display: 'grid',\n placeItems: 'center',\n marginTop: '15vh',\n [theme.breakpoints.down('xs')]: {\n marginTop: 0,\n },\n flexGrow: 1,\n backgroundColor: Colors.background[0],\n },\n\n card: {\n // minWidth: '400px',\n // borderTop: `4px solid ${Colors.primary[3]}`,\n [theme.breakpoints.down('xs')]: {\n width: '90%',\n borderRadius: 0,\n },\n borderRadius: 8,\n },\n\n cardContent: {\n '& h5': {\n marginTop: theme.spacing(),\n marginBottom: theme.spacing(5),\n },\n },\n\n actions: {\n display: 'flex',\n flexDirection: 'row-reverse',\n '& button': {\n marginLeft: theme.spacing(),\n },\n },\n\n send: {\n display: 'flex',\n minWidth: 400,\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n },\n\n checkCircleIcon: {\n width: 80,\n height: 80,\n [theme.breakpoints.down('xs')]: {\n width: 60,\n height: 60,\n margin: theme.spacing(2),\n },\n margin: theme.spacing(3),\n color: Colors.supportingCyan[3],\n },\n})\n\nconst EmailForm: React.FC = () => {\n const intl = useIntl()\n const ConfirmationMessage = intl.formatMessage(\n messages.passwordForgotConfirmationMessage\n )\n const ConfirmationMessage2 = intl.formatMessage(\n messages.passwordForgotConfirmationMessage2\n )\n const ConfirmationTitle = intl.formatMessage(\n messages.passwordForgotConfirmationTitle\n )\n const ConfirmationSent = intl.formatMessage(\n messages.passwordForgotConfirmationSent\n )\n const passwordForgotBackToLogin = intl.formatMessage(\n messages.passwordForgotBackToLogin\n )\n\n const classes = useClasses()\n const { email } = useLoginState()\n const { setEmail } = useLoginActions()\n const isRTL = useRTL()\n const goTo = useGoToHook()\n const dispatch = useDispatchHook()\n\n const backToLogin = () => goTo(AppRoutes.Login)\n const sendEmail = (event?: FormEvent<HTMLFormElement>) => {\n event?.preventDefault()\n dispatch({ type: 'Pages/Login/PasswordForgot/SendEmail' })\n }\n\n const disabled = !isEmail(email)\n\n return (\n <div className={classes.center}>\n <Card className={classes.card} elevation={3}>\n <CardContent className={classes.cardContent}>\n <Typography variant='h5'>{ConfirmationTitle}</Typography>\n <Typography>{ConfirmationMessage}</Typography>\n <Typography>{ConfirmationMessage2}</Typography>\n <form onSubmit={e => sendEmail(e)}>\n <Grid\n direction='column'\n container={true}\n className={classes.innerContainer}\n >\n <FormControl>\n <InputLabel htmlFor='email'>\n <FormattedMessage {...messages.email} />\n </InputLabel>\n <Input\n id='email'\n type='email'\n value={email}\n onChange={e => setEmail(e.target.value)}\n autoComplete='email'\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <EmailIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <EmailIcon color='action' />\n </InputAdornment>\n )\n }\n />\n </FormControl>\n </Grid>\n </form>\n </CardContent>\n <CardActions className={classes.actions}>\n <Button\n variant='contained'\n color='secondary'\n onClick={() => sendEmail()}\n disabled={disabled}\n >\n {ConfirmationSent}\n </Button>\n <Button onClick={backToLogin}>{passwordForgotBackToLogin}</Button>\n </CardActions>\n </Card>\n </div>\n )\n}\n\nconst Send = () => {\n const intl = useIntl()\n const ConfirmationSent = intl.formatMessage(\n messages.passwordForgotConfirmationSent\n )\n const ConfirmationSendMessage = intl.formatMessage(\n messages.passwordForgotConfirmationSendMessage\n )\n const passwordForgotBackToLogin = intl.formatMessage(\n messages.passwordForgotBackToLogin\n )\n\n const goTo = useGoToHook()\n const backToLogin = () => goTo(AppRoutes.Login)\n\n const classes = useClasses()\n const { email } = useLoginState()\n return (\n <div className={classes.center}>\n <Card className={classes.card} elevation={3}>\n <CardContent className={classes.send}>\n <CheckCircleIcon\n color='inherit'\n className={classes.checkCircleIcon}\n />\n <Typography variant='h6' style={{ marginBottom: 20 }}>\n {ConfirmationSent}\n </Typography>\n <Typography>{ConfirmationSendMessage}</Typography>\n <Typography>{email}.</Typography>\n </CardContent>\n <CardActions\n className={classes.actions}\n style={{ marginTop: theme.spacing(3) }}\n >\n <Button onClick={backToLogin}>{passwordForgotBackToLogin}</Button>\n </CardActions>\n </Card>\n </div>\n )\n}\n\nconst Sending = () => (\n <div\n style={{\n display: 'flex',\n height: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <CircularProgress />\n </div>\n)\n\nexport const LoginPasswordForgot: React.FC = () => {\n const intl = useIntl()\n const passwordForgotTitle = intl.formatMessage(messages.passwordForgotTitle)\n const state = useAppState(s => s.pages.loginPasswordForgot.send)\n\n const isSend = state === 'send'\n const isSending = state === 'sending'\n const isInput = state === 'input'\n const isError = state === 'error'\n\n return (\n <PublicPageLayout title={passwordForgotTitle} showTranslationSwitch>\n {isInput && <EmailForm />}\n {isSending && <Sending />}\n {isSend && <Send />}\n {isError && <EmailForm />}\n </PublicPageLayout>\n )\n}\n\nexport default LoginPasswordForgot\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageNotFoundTitle: {\n id: 'cp.pages.passwordForgotSetPassword.pageNotFound.title',\n defaultMessage: 'Not valid anymore',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.passwordForgotSetPassword.pageNotFound.message',\n defaultMessage: 'This code is not valid anymore.',\n },\n successTitle: {\n id: 'cp.pages.passwordForgotSetPassword.title',\n defaultMessage: 'Password changed!',\n },\n successMessage: {\n id: 'cp.pages.passwordForgotSetPassword.message',\n defaultMessage: 'All set up and you are good to go!',\n },\n loginButton: {\n id: 'cp.pages.passwordForgotSetPassword.button',\n defaultMessage: 'To the login page',\n },\n welcome: {\n id: 'cp.pages.passwordForgotSetPassword.welcome',\n defaultMessage: 'Welcome',\n },\n newPasswordRequired: {\n id: 'cp.components.passwordForgotSetPassword.newRequiredError',\n defaultMessage: 'A new password is required',\n },\n newToShortError: {\n id: 'cp.components.passwordForgotSetPassword.newToShortError',\n defaultMessage: 'The provided passwort is to short.',\n },\n passwordDontMatch: {\n id: 'cp.components.passwordForgotSetPassword.matchError',\n defaultMessage: \"New passwords don't match\",\n },\n newPassword: {\n id: 'cp.components.passwordForgotSetPassword.newPassword',\n defaultMessage: 'New Password',\n },\n newPasswordRepeat: {\n id: 'cp.components.passwordForgotSetPassword.newPasswordRepeat',\n defaultMessage: 'New Password (repeat)',\n },\n changePasswordButton: {\n id: 'cp.components.passwordForgotSetPassword.changePasswordButton',\n defaultMessage: 'Change Password',\n },\n})\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useLoginPasswordForgotSetPasswordState = createStateHook(\n AppStoreProvider,\n state => state.pages.loginPasswordForgotSetPassword\n)\n\nexport const useNextLoginPasswordForgotSetPasswordState = () =>\n createNextHook(\n AppStoreProvider,\n state => state.pages.loginPasswordForgotSetPassword\n )\n","import { Button, TextField } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport { PublicPageLayout } from 'components/layouts/PublicPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport { Spinner } from 'components/Spinner/Spinner'\nimport React, { ChangeEvent, useState } from 'react'\nimport { useIntl } from 'react-intl'\nimport FormattedMessage from 'react-intl/dist/components/message'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useDispatchHook } from 'state/store'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport messages from './LoginPasswordForgotSetPassword.messages'\nimport { useLoginPasswordForgotSetPasswordState } from './LoginPasswordForgotSetPassword.restate'\n\nconst useStyles = makeStyles({\n container: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n flexGrow: 1,\n [theme.breakpoints.down('xs')]: {\n margin: '1rem',\n },\n },\n inputField1: {\n marginTop: theme.spacing(5),\n minHeight: 70,\n [theme.breakpoints.down('xs')]: {\n marginTop: 0,\n width: '100%',\n },\n },\n inputField: {\n marginBottom: theme.spacing(2),\n minHeight: 70,\n },\n welcome: {\n marginBottom: theme.spacing(3),\n },\n})\n\ninterface ChangePasswordProps {\n onSend: (props: { newPassword: string }) => any\n}\n\nexport const ChangePassword: React.FC<ChangePasswordProps> = props => {\n const intl = useIntl()\n\n const newRequiredError = intl.formatMessage(messages.newPasswordRequired)\n const newToShortError = intl.formatMessage(messages.newToShortError)\n const matchError = intl.formatMessage(messages.passwordDontMatch)\n const newPassword = intl.formatMessage(messages.newPassword)\n const newPasswordRepeat = intl.formatMessage(messages.newPasswordRepeat)\n const changePasswordButton = intl.formatMessage(messages.changePasswordButton)\n\n const { onSend } = props\n const classes = useStyles()\n\n const [newPassword0, setNewPassword0] = useState('')\n const [errorNewPassword0, setErrorNewPassword0] = useState(false)\n const [errorNewPasswordMessage0, setErrorNewPasswordMessage0] = useState('')\n\n const [newPassword1, setNewPassword1] = useState('')\n const [errorNewPassword1, setErrorNewPassword1] = useState(false)\n const [errorNewPasswordMessage1, setErrorNewPasswordMessage1] = useState('')\n\n //\n // NewPassword0\n //\n function resetNewPassword0Validation() {\n setErrorNewPassword0(false)\n setErrorNewPasswordMessage0('')\n }\n\n function validateNewPassword0() {\n resetNewPassword0Validation()\n\n if (newPassword0 === '') {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newRequiredError)\n }\n if (newPassword0.length < 8) {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newToShortError)\n }\n }\n\n //\n // NewPassword1\n //\n function resetNewPassword1Validation() {\n setErrorNewPassword1(false)\n setErrorNewPasswordMessage1('')\n }\n\n function validateNewPassword1() {\n resetNewPassword1Validation()\n\n if (newPassword0 !== newPassword1) {\n setErrorNewPassword1(true)\n setErrorNewPasswordMessage1(matchError)\n }\n if (newPassword1.length < 8) {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newToShortError)\n }\n }\n\n function validate() {\n validateNewPassword0()\n validateNewPassword1()\n\n const errorNewPasswordMatch = newPassword0 !== newPassword1\n\n return !errorNewPasswordMatch && !errorNewPassword0\n }\n\n function handleSetNewPassword0(e: ChangeEvent<HTMLInputElement>) {\n resetNewPassword0Validation()\n setNewPassword0(e.target.value)\n }\n\n function handleSetNewPassword1(e: ChangeEvent<HTMLInputElement>) {\n resetNewPassword1Validation()\n setNewPassword1(e.target.value)\n }\n\n function sendChangePasswordRequest() {\n const valid = validate()\n if (valid) {\n onSend({ newPassword: newPassword0 })\n }\n }\n\n const buttonDisabled =\n errorNewPassword0 || errorNewPassword1 || newPassword0.length === 0\n\n return (\n <div className={classes.container}>\n <ImageCard imgUrl={Images.forgotPassword}>\n <ImageCardContent>\n <TextField\n value={newPassword0}\n label={newPassword}\n onChange={handleSetNewPassword0}\n className={classes.inputField}\n onBlur={validateNewPassword0}\n error={errorNewPassword0}\n helperText={errorNewPasswordMessage0}\n type='password'\n placeholder={newPassword}\n />\n <TextField\n value={newPassword1}\n label={newPasswordRepeat}\n onChange={handleSetNewPassword1}\n onBlur={validateNewPassword1}\n className={classes.inputField}\n error={errorNewPassword1}\n helperText={errorNewPasswordMessage1}\n type='password'\n placeholder={newPasswordRepeat}\n />\n </ImageCardContent>\n <ImageCardActions>\n <Button\n color='secondary'\n variant='contained'\n onClick={sendChangePasswordRequest}\n disabled={buttonDisabled}\n >\n {changePasswordButton}\n </Button>\n </ImageCardActions>\n </ImageCard>\n </div>\n )\n}\n\nconst LoadingPage = () => {\n const classes = useStyles()\n\n return (\n <PublicPageLayout title=''>\n <div className={classes.container}>\n <Spinner visible={true} />\n </div>\n </PublicPageLayout>\n )\n}\n\nconst NotFoundPage = () => {\n const intl = useIntl()\n const goTo = useGoToHook()\n const goToLogin = () => goTo(AppRoutes.Login)\n\n const message = intl.formatMessage(messages.pageNotFoundMessage)\n const title = intl.formatMessage(messages.pageNotFoundTitle)\n return (\n <PageNotFound\n variant='public'\n message={message}\n title={title}\n img={Images.empty}\n action={() => (\n <Button color='secondary' variant='contained' onClick={goToLogin}>\n <FormattedMessage {...messages.loginButton} />\n </Button>\n )}\n />\n )\n}\n\nconst SetPasswordPage = () => {\n const intl = useIntl()\n const title = intl.formatMessage(messages.successTitle)\n const dispatch = useDispatchHook()\n\n const onSend = ({ newPassword }: { newPassword: string }) => {\n dispatch({\n type: 'Pages/LoginPasswordForgotSetPassword/Set',\n payload: newPassword,\n })\n }\n\n return (\n <PublicPageLayout title={title} showTranslationSwitch>\n <ChangePassword onSend={onSend} />\n </PublicPageLayout>\n )\n}\n\nconst SuccessPage = () => {\n const intl = useIntl()\n const message = intl.formatMessage(messages.successMessage)\n const title = intl.formatMessage(messages.successTitle)\n const loginButton = intl.formatMessage(messages.loginButton)\n\n const goTo = useGoToHook()\n\n const goToLogin = () => goTo(AppRoutes.Login)\n\n return (\n <PageNotFound\n variant='public'\n message={message}\n title={title}\n img={Images.confirmation}\n action={() => (\n <Button color='secondary' variant='contained' onClick={goToLogin}>\n {loginButton}\n </Button>\n )}\n />\n )\n}\n\nexport const LoginPasswordForgotSetPassword: React.FC<{}> = () => {\n const { loading, notFound } = useLoginPasswordForgotSetPasswordState(\n s => s.meta\n )\n const success = useLoginPasswordForgotSetPasswordState(s => s.success)\n\n if (loading) return <LoadingPage />\n if (notFound) return <NotFoundPage />\n if (success) return <SuccessPage />\n\n return <SetPasswordPage />\n}\n\nexport default LoginPasswordForgotSetPassword\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n logoutTitle: {\n id: 'cp.pages.logout.title',\n defaultMessage: 'Goodbye!',\n },\n logoutMessage: {\n id: 'cp.pages.logout.message',\n defaultMessage: 'See you next time',\n },\n loginButton: {\n id: 'cp.pages.logout.loginButton',\n defaultMessage: 'LOGIN',\n },\n})\n","import { Button } from '@material-ui/core'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { Images } from 'theme/Images'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Logout.messages'\n\nexport const Logout: React.FC<{}> = () => {\n const intl = useIntl()\n const logoutTitle = intl.formatMessage(messages.logoutTitle)\n const logoutMessage = intl.formatMessage(messages.logoutMessage)\n const loginButton = intl.formatMessage(messages.loginButton)\n\n const go = useGoToHook()\n return (\n <PageNotFound\n variant='public'\n title={logoutTitle}\n message={logoutMessage}\n img={Images.logout}\n action={() => (\n <Button\n color='secondary'\n variant='contained'\n onClick={() => go(AppRoutes.Login)}\n >\n {loginButton}\n </Button>\n )}\n />\n )\n}\n\nexport default Logout\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useMeState = createStateHook(\n AppStoreProvider,\n state => state.pages.me\n)\nexport const useNextMeState = () =>\n createNextHook(AppStoreProvider, state => state.pages.me)\n","import {\n Button,\n Grid,\n InputLabel,\n MenuItem,\n Select,\n TextField,\n Modal,\n Card,\n Typography,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { Gender } from 'model/Gender'\nimport React, { useState } from 'react'\nimport { useIntl } from 'react-intl'\nimport { useDispatchHook, useNextAppState } from 'state/store'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { Colors } from '../../theme/colors'\nimport messages from './Me.messages'\nimport { useMeState } from './Me.restate'\n\nconst useClasses = makeStyles({\n input: {\n marginTop: theme.spacing(2),\n },\n\n deleteButton: {\n marginTop: theme.spacing(2),\n width: '100%',\n maxWidth: 700,\n backgroundColor: Colors.vivid[3],\n },\n\n modal: {\n position: 'absolute',\n height: '250',\n width: '400px',\n top: '40%',\n left: '40%',\n padding: '20px',\n },\n\n warning: {\n textAlign: 'center',\n },\n})\n\nexport const Me: React.FC<{}> = () => {\n const next = useNextAppState(s => s.pages.me)\n const { firstName, familyName, gender } = useMeState(s => s)\n const loading = useMeState(s => s.meta.loading)\n const ready = useMeState(s => s.meta.ready)\n\n const classes = useClasses()\n const dispatch = useDispatchHook()\n\n const intl = useIntl()\n const title = intl.formatMessage(messages.title)\n const genderLabel = intl.formatMessage(messages.gender)\n const genderFemaleLabel = intl.formatMessage(messages.genderFemale)\n const genderMaleLabel = intl.formatMessage(messages.genderMale)\n const genderOtherLabel = intl.formatMessage(messages.genderOther)\n const saveLabel = intl.formatMessage(messages.save)\n const firstNameLabel = intl.formatMessage(messages.firstName)\n const familyNameLabel = intl.formatMessage(messages.familyName)\n const deleteOwnButtonRequest = intl.formatMessage(\n messages.deleteOwnButtonRequest\n )\n const deleteOwnContent = intl.formatMessage(messages.deleteOwnContent)\n const deleteOwnButtonConfirm = intl.formatMessage(\n messages.deleteOwnButtonConfirm\n )\n\n const [modalIsOpen, setModalisOpen] = useState(false)\n\n const setFirstName = (e: React.ChangeEvent<{ value: string }>) =>\n next(s => {\n s.firstName = e.target.value\n })\n\n const setFamilyName = (e: React.ChangeEvent<{ value: string }>) =>\n next(s => {\n s.familyName = e.target.value\n })\n\n const setGender = (e: React.ChangeEvent<{ value: unknown }>) =>\n next(s => {\n s.gender = e.target.value as Gender\n })\n\n const imgUrl = () => {\n if (gender === 'female') return Images.femaleAvatar\n if (gender === 'male') return Images.maleAvatar\n return Images.otherAvatar\n }\n\n const save = () => dispatch({ type: 'Page/Me/Save' })\n\n const deleteUserAccount = () => {\n setModalisOpen(false)\n dispatch({ type: 'Page/Me/Delete' })\n }\n\n if (!ready)\n return <AppPageLayout title={title} loading={loading}></AppPageLayout>\n\n return (\n <AppPageLayout title={title} loading={loading}>\n <ImageCard imgUrl={imgUrl()}>\n <ImageCardContent>\n <Grid direction='column' container={true}>\n <TextField\n label={firstNameLabel}\n value={firstName}\n onChange={setFirstName}\n className={classes.input}\n />\n <TextField\n label={familyNameLabel}\n value={familyName}\n onChange={setFamilyName}\n className={classes.input}\n />\n <InputLabel id='gender-label' className={classes.input}>\n {genderLabel}\n </InputLabel>\n <Select labelId='gender-label' value={gender} onChange={setGender}>\n <MenuItem value={'female'}>{genderFemaleLabel}</MenuItem>\n <MenuItem value={'male'}>{genderMaleLabel}</MenuItem>\n <MenuItem value={'other'}>{genderOtherLabel}</MenuItem>\n </Select>\n </Grid>\n </ImageCardContent>\n <ImageCardActions>\n <Button\n type='submit'\n variant='contained'\n color='secondary'\n onClick={save}\n disabled={loading}\n >\n {saveLabel}\n </Button>\n </ImageCardActions>\n </ImageCard>\n <Button\n onClick={() => setModalisOpen(true)}\n variant='contained'\n size='large'\n className={classes.deleteButton}\n >\n {deleteOwnButtonRequest}\n </Button>\n\n <Modal open={modalIsOpen} onClose={() => setModalisOpen(false)}>\n <Card className={classes.modal}>\n <div className={classes.warning}>\n <Typography variant='h6'>{deleteOwnContent}</Typography>\n </div>\n <Button\n variant='contained'\n size='large'\n onClick={deleteUserAccount}\n className={classes.deleteButton}\n >\n {deleteOwnButtonConfirm}\n </Button>\n </Card>\n </Modal>\n </AppPageLayout>\n )\n}\n\nexport default Me\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageNotFoundTitle: {\n id: 'cp.pages.networkError.pageNotFound.title',\n defaultMessage: 'Oh no! The server seems do be down!',\n },\n pageNotFoundMessage: {\n id: 'cp.pages.networkError.pageNotFound.message',\n defaultMessage:\n 'The server was not able to complete the request. Are you connected to the Internet? ',\n },\n pageNotFoundButton: {\n id: 'cp.pages.networkError.pageNotFound.button',\n defaultMessage: 'Try again',\n },\n})\n","import { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { Images } from 'theme/Images'\nimport { Button } from '@material-ui/core'\nimport { useGoBack } from 'services/router/useGoBack.hook'\nimport { useIntl } from 'react-intl'\n\nimport messages from './NetworkError.messages'\n\nexport const NetworkError: React.FC<{}> = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n const pageNotFoundButton = intl.formatMessage(messages.pageNotFoundButton)\n\n const goBack = useGoBack()\n return (\n <PageNotFound\n variant='public'\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.questions}\n action={() => (\n <Button color='secondary' variant='contained' onClick={goBack}>\n {pageNotFoundButton}\n </Button>\n )}\n />\n )\n}\n\nexport default NetworkError\n","export function range(value: number) {\n let x = []\n for (let i = 0; i < value; i++) {\n x.push(i)\n }\n return x\n}\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n SettingsPageTitle: {\n id: 'cp.pages.settings.title',\n defaultMessage: 'Settings',\n },\n TableRowProperty: {\n id: 'cp.pages.settings.tableRowProperty',\n defaultMessage: 'Property',\n },\n TableRowValue: {\n id: 'cp.pages.settings.tableRowValue',\n defaultMessage: 'Value',\n },\n TableRowLocked: {\n id: 'cp.pages.settings.tableRowLocked',\n defaultMessage: 'Locked',\n },\n TableRowTrainees: {\n id: 'cp.pages.settings.tableRowTrainees',\n defaultMessage: 'Default number of trainees',\n },\n TableRowDuration: {\n id: 'cp.pages.settings.tableRowDuration',\n defaultMessage: 'Session Duration',\n },\n TableRowFeedback: {\n id: 'cp.pages.settings.tableRowFeedback',\n defaultMessage: 'Feedback Mode',\n },\n TableRowType: {\n id: 'cp.pages.settings.tableRowType',\n defaultMessage: 'Session Type',\n },\n TableRowCompression: {\n id: 'cp.pages.settings.tableRowCompression',\n defaultMessage: 'Compression only',\n },\n\n TableRowFrequency: {\n id: 'cp.pages.settings.tableRowFrequency',\n defaultMessage: 'Target Frequency',\n },\n TableRowResult: {\n id: 'cp.pages.settings.tableRowResult',\n defaultMessage: 'Result Type',\n },\n TableRowERC: {\n id: 'cp.pages.settings.tableRowERC',\n defaultMessage: 'Check for vital signs',\n },\n TableRowSaveButton: {\n id: 'cp.pages.settings.tableRowSaveButton',\n defaultMessage: 'Save',\n },\n FeedbackModeMenuItemNone: {\n id: 'cp.pages.settings.feedbackMode.menuItemNone',\n defaultMessage: 'none',\n },\n FeedbackModeMenuItemExpert: {\n id: 'cp.pages.settings.feedbackMode.menuItemExpert',\n defaultMessage: 'expert',\n },\n FeedbackModeMenuItemSimple: {\n id: 'cp.pages.settings.feedbackMode.menuItemSimple',\n defaultMessage: 'simple',\n },\n ResultTypeMenuItemNone: {\n id: 'cp.pages.settings.resultType.menuItemNone',\n defaultMessage: 'none',\n },\n ResultTypeMenuItemSimple: {\n id: 'cp.pages.settings.resultType.menuItemSimple',\n defaultMessage: 'simple',\n },\n ResultTypeMenuItemStandard: {\n id: 'cp.pages.settings.resultType.menuItemStandard',\n defaultMessage: 'standard',\n },\n ResultTypeMenuItemExpert: {\n id: 'cp.pages.settings.resultType.menuItemExpert',\n defaultMessage: 'expert',\n },\n MenuItemThresholdGood: {\n id: 'cp.pages.settings.menuItemThresholdGood',\n defaultMessage: 'Threshold Feedback \"Good\"',\n },\n MenuItemThresholdGreat: {\n id: 'cp.pages.settings.menuItemThresholdGreat',\n defaultMessage: 'Threshold Feedback \"Great\"',\n },\n TableRowResultConfigSaveButton: {\n id: 'cp.pages.settings.tableRowResultConfigSaveButton',\n defaultMessage: 'Save result configuration',\n },\n})\n","import { createNextHook, createStateHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useSettingsState = createStateHook(\n AppStoreProvider,\n state => state.pages.settings\n)\nexport const useNextSettingsState = () =>\n createNextHook(AppStoreProvider, state => state.pages.settings)\n","import {\n Button,\n Card,\n CardContent,\n Checkbox,\n MenuItem,\n Select,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n} from '@material-ui/core'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { FeedbackMode } from 'model/FeedbackMode'\nimport { SessionType } from 'model/SessionType'\nimport React, { useState } from 'react'\nimport { useIntl } from 'react-intl'\nimport { useDispatchHook, useNextAppState } from 'state/store'\nimport { range } from 'utils/range'\nimport messages from './Settings.messages'\nimport { useSettingsState } from './Settings.restate'\nimport { ResultType } from 'model/ResultType'\nimport {\n useNextInstituteResultConfigState,\n useInstituteResultConfigState,\n} from 'pages/Institute/Institute.restate'\nimport { ResultConfig } from 'model/CptConfig'\n\nconst SettingsLoading = () => {\n const intl = useIntl()\n const settingsTitle = intl.formatMessage(messages.SettingsPageTitle)\n\n return <AppPageLayout title={settingsTitle} loading={true}></AppPageLayout>\n}\n\nexport const Settings: React.FC<{}> = () => {\n const intl = useIntl()\n const settingsTitle = intl.formatMessage(messages.SettingsPageTitle)\n const Property = intl.formatMessage(messages.TableRowProperty)\n const Value = intl.formatMessage(messages.TableRowValue)\n const Locked = intl.formatMessage(messages.TableRowLocked)\n const Trainees = intl.formatMessage(messages.TableRowTrainees)\n const Duration = intl.formatMessage(messages.TableRowDuration)\n const Feedback = intl.formatMessage(messages.TableRowFeedback)\n const Type = intl.formatMessage(messages.TableRowType)\n const Compression = intl.formatMessage(messages.TableRowCompression)\n const Frequency = intl.formatMessage(messages.TableRowFrequency)\n const Result = intl.formatMessage(messages.TableRowResult)\n const ERC = intl.formatMessage(messages.TableRowERC)\n const SaveButton = intl.formatMessage(messages.TableRowSaveButton)\n const FeedbackModeMenuItemNone = intl.formatMessage(\n messages.FeedbackModeMenuItemNone\n )\n const FeedbackModeMenuItemExpert = intl.formatMessage(\n messages.FeedbackModeMenuItemExpert\n )\n const FeedbackModeMenuItemSimple = intl.formatMessage(\n messages.FeedbackModeMenuItemSimple\n )\n const ResultTypeMenuItemNone = intl.formatMessage(\n messages.ResultTypeMenuItemNone\n )\n const ResultTypeMenuItemSimple = intl.formatMessage(\n messages.ResultTypeMenuItemSimple\n )\n const ResultTypeMenuItemStandard = intl.formatMessage(\n messages.ResultTypeMenuItemStandard\n )\n const ResultTypeMenuItemExpert = intl.formatMessage(\n messages.ResultTypeMenuItemExpert\n )\n const MenuItemThresholdGood = intl.formatMessage(\n messages.MenuItemThresholdGood\n )\n const MenuItemThresholdGreat = intl.formatMessage(\n messages.MenuItemThresholdGreat\n )\n const TableRowResultConfigSaveButton = intl.formatMessage(\n messages.TableRowResultConfigSaveButton\n )\n\n const appConfig = useSettingsState(s => s.appConfig)\n const instituteResultConfig = useInstituteResultConfigState(s => s)\n const next = useNextAppState(s => s.pages.settings.appConfig!.sessionConfig)\n const nextInstituteResultConfig = useNextInstituteResultConfigState(s => s)\n const dispatch = useDispatchHook()\n const [touched, setTouched] = useState(false)\n\n if (!appConfig) return <SettingsLoading />\n\n const sessionConfig = appConfig.sessionConfig\n\n const setNumberOfTrainees = (e: React.ChangeEvent<{ value: unknown }>) =>\n next(s => {\n s.numberOfTrainees.value = Number.parseInt(e.target.value as string)\n })\n\n const setSessionDuration = (e: React.ChangeEvent<{ value: unknown }>) =>\n next(s => {\n s.sessionDuration.value = Number.parseInt(e.target.value as string)\n })\n\n const setFeedbackMode = (e: React.ChangeEvent<{ value: unknown }>) =>\n next(s => {\n s.feedbackMode.value = (e.target.value as unknown) as FeedbackMode\n })\n\n const setSessionType = (e: React.ChangeEvent<{ value: unknown }>) =>\n next(s => {\n s.sessionType.value = e.target.value as SessionType\n })\n\n const setResultType = (e: React.ChangeEvent<{ value: unknown }>) =>\n next(s => {\n s.resultType.value = e.target.value as ResultType\n })\n\n const setExecRoutine = () =>\n next(s => {\n s.showErcRoutine.value = !s.showErcRoutine.value\n })\n\n const setThresholdGood = (e: React.ChangeEvent<{ value: string }>) =>\n nextInstituteResultConfig((s: ResultConfig) => {\n s.simple.thresholdGood = Number.parseInt(e.target.value) as number\n })\n\n const setThresholdGreat = (e: React.ChangeEvent<{ value: string }>) =>\n nextInstituteResultConfig((s: ResultConfig) => {\n s.simple.thresholdGreat = Number.parseInt(e.target.value) as number\n })\n\n const save = () => dispatch({ type: 'Page/Settings/Save' })\n const saveResultConfig = () => {\n dispatch({ type: 'Pages/Institute/InstituteAdmin/ResultConfig/Save' })\n setTouched(false)\n }\n\n return (\n <AppPageLayout title={settingsTitle}>\n <Card id='settings-card'>\n <CardContent>\n <Table>\n <TableHead>\n <TableRow>\n <TableCell>{Property}</TableCell>\n <TableCell>{Value}</TableCell>\n <TableCell>{Locked}</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n <TableRow>\n <TableCell>{Trainees}</TableCell>\n <TableCell>\n <Select\n value={sessionConfig.numberOfTrainees.value}\n onChange={setNumberOfTrainees}\n >\n {range(20).map(i => (\n <MenuItem\n key={i + 1}\n value={i + 1}\n style={{ padding: 20 }}\n >\n {i + 1}\n </MenuItem>\n ))}\n </Select>\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.numberOfTrainees.locked}\n onChange={() =>\n next(s => {\n s.numberOfTrainees.locked = !s.numberOfTrainees.locked\n })\n }\n ></Checkbox>\n </TableCell>\n </TableRow>\n\n <TableRow>\n <TableCell>{Duration}</TableCell>\n <TableCell>\n <Select\n value={sessionConfig.sessionDuration.value}\n onChange={setSessionDuration}\n >\n {range(20)\n .map(i => (i + 1) * 30)\n .map(sec => (\n <MenuItem key={sec} value={sec} style={{ padding: 20 }}>\n {formatSessionDuration(sec)}\n </MenuItem>\n ))}\n </Select>\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.sessionDuration.locked}\n onChange={() =>\n next(s => {\n s.sessionDuration.locked = !s.sessionDuration.locked\n })\n }\n ></Checkbox>\n </TableCell>\n </TableRow>\n\n <TableRow>\n <TableCell>{Feedback}</TableCell>\n <TableCell>\n <Select\n value={sessionConfig.feedbackMode.value}\n onChange={setFeedbackMode}\n >\n <MenuItem value={'none'}>\n {FeedbackModeMenuItemNone}\n </MenuItem>\n <MenuItem value={'simple'}>\n {FeedbackModeMenuItemSimple}\n </MenuItem>\n <MenuItem value={'expert'}>\n {FeedbackModeMenuItemExpert}\n </MenuItem>\n </Select>\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.feedbackMode.locked}\n onChange={() =>\n next(s => {\n s.feedbackMode.locked = !s.feedbackMode.locked\n })\n }\n ></Checkbox>\n </TableCell>\n </TableRow>\n\n <TableRow>\n <TableCell>{Type}</TableCell>\n <TableCell>\n <Select\n value={sessionConfig.sessionType.value}\n onChange={setSessionType}\n >\n <MenuItem value={'compressionOnly'}>{Compression}</MenuItem>\n <MenuItem value={'30:2'}>30:2</MenuItem>\n </Select>\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.sessionType.locked}\n onChange={() =>\n next(s => {\n s.sessionType.locked = !s.sessionType.locked\n })\n }\n />\n </TableCell>\n </TableRow>\n\n <TableRow>\n <TableCell>{Frequency}</TableCell>\n <TableCell style={{ minWidth: 200 }}>\n <Select\n value={sessionConfig.targetFrequency.value}\n disabled={true}\n >\n <MenuItem value={sessionConfig.targetFrequency.value}>\n {sessionConfig.targetFrequency.value}\n </MenuItem>\n </Select>\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.targetFrequency.locked}\n disabled={true}\n />\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>{Result}</TableCell>\n <TableCell>\n <Select\n value={sessionConfig.resultType.value}\n onChange={setResultType}\n >\n <MenuItem value={'none'}>{ResultTypeMenuItemNone}</MenuItem>\n <MenuItem value={'simple'}>\n {ResultTypeMenuItemSimple}\n </MenuItem>\n <MenuItem value={'standard'}>\n {ResultTypeMenuItemStandard}\n </MenuItem>\n <MenuItem value={'expert'}>\n {ResultTypeMenuItemExpert}\n </MenuItem>\n </Select>\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.resultType.locked}\n onChange={() =>\n next(s => {\n s.resultType.locked = !s.resultType.locked\n })\n }\n />\n </TableCell>\n </TableRow>\n\n <TableRow>\n <TableCell>{ERC}</TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.showErcRoutine.value}\n onChange={setExecRoutine}\n />\n </TableCell>\n <TableCell>\n <Checkbox\n checked={sessionConfig.showErcRoutine.locked}\n onChange={() =>\n next(s => {\n s.showErcRoutine.locked = !s.showErcRoutine.locked\n })\n }\n />\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n\n <CardContent>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row-reverse',\n width: '100%',\n }}\n >\n <Button variant='contained' color='secondary' onClick={save}>\n {SaveButton}\n </Button>\n </div>\n </CardContent>\n </Card>\n\n <Card style={{ width: '78%', marginTop: '20px' }}>\n <CardContent>\n <Table>\n <TableHead>\n <TableRow>\n <TableCell>{Property}</TableCell>\n <TableCell>{Value}</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n <TableRow>\n <TableCell>{MenuItemThresholdGood}</TableCell>\n <TableCell>\n <TextField\n type='number'\n value={instituteResultConfig.simple.thresholdGood}\n onChange={e => {\n if (\n Number.parseInt(e.target.value) >= 1 &&\n Number.parseInt(e.target.value) <= 100\n ) {\n setTouched(true)\n setThresholdGood(e)\n }\n }}\n />\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>{MenuItemThresholdGreat}</TableCell>\n <TableCell>\n <TextField\n type='number'\n value={instituteResultConfig.simple.thresholdGreat}\n onChange={e => {\n if (\n Number.parseInt(e.target.value) >= 1 &&\n Number.parseInt(e.target.value) <= 100\n ) {\n setTouched(true)\n setThresholdGreat(e)\n }\n }}\n />\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n\n <CardContent>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row-reverse',\n width: '100%',\n }}\n >\n <Button\n variant='contained'\n color='secondary'\n onClick={saveResultConfig}\n disabled={!touched}\n >\n {TableRowResultConfigSaveButton}\n </Button>\n </div>\n </CardContent>\n </Card>\n </AppPageLayout>\n )\n}\n\nfunction formatSessionDuration(sec: number) {\n const minutes = Math.floor(sec / 60)\n const seconds = sec % 60\n\n const minFormated = minutes < 10 ? '0' + minutes : '' + minutes\n const secFormated = seconds < 10 ? '0' + seconds : '' + seconds\n\n return `${minFormated}:${secFormated}`\n}\n\nexport default Settings\n","import { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport React from 'react'\nimport { useAppState } from 'state/store'\n\nfunction renderShop() {\n ;(window as any)?.xProductBrowser?.(\n 'categoriesPerRow=3',\n 'views=grid(20,3) list(60) table(60)',\n 'categoryView=grid',\n 'searchView=list',\n 'id=my-store-20335351'\n )\n}\n\nconst ToggleShop: React.FC = props => {\n const pathname = useAppState(state => state.location.pathname)\n const showShop = pathname === '/shop'\n const styles = {\n display: showShop ? 'initial' : 'none',\n }\n return (\n <div>\n <div style={styles}>{props.children}</div>\n </div>\n )\n}\n\nconst ShopPageLayout = () => {\n const hash = useAppState(state => state.location.hash)\n const showBackButton = hash.length > 0\n return (\n <ToggleShop>\n <AppPageLayout title='Shop' showBackButton={showBackButton}>\n <div id='my-store-20335351' style={{ minWidth: '90vw' }}></div>\n </AppPageLayout>\n </ToggleShop>\n )\n}\n\nexport class Shop extends React.Component<{}> {\n componentDidMount() {\n setTimeout(renderShop, 500)\n }\n\n render() {\n return (\n <>\n <ShopPageLayout />\n </>\n )\n }\n}\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useTrainerInviteState = createStateHook(\n AppStoreProvider,\n state => state.pages.trainerInvite\n)\nexport const useNextTrainerInviteState = createNextHook(\n AppStoreProvider,\n state => state.pages.trainerInvite\n)\n","import { Invite } from 'components/Invite/Invite'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport React from 'react'\nimport { useDispatchHook } from 'state/store'\nimport { useGoBack } from 'services/router/useGoBack.hook'\nimport { useIntl } from 'react-intl'\n\nimport messages from './TrainerInvite.messages'\nimport { setInstitutePageTabIndex } from 'pages/Institute/Institute.page-service'\nimport { useTrainerInviteState, useNextTrainerInviteState } from './TrainerInvite.restate'\n\nexport const TrainerInvite: React.FC<{}> = () => {\n const intl = useIntl()\n const trainerInviteTitle = intl.formatMessage(messages.trainerInviteTitle)\n\n const dispatch = useDispatchHook()\n const goBack = useGoBack()\n const send = useTrainerInviteState(s => s.send)\n const next = useNextTrainerInviteState(s => s)\n return (\n <AppPageLayout title={trainerInviteTitle} showBackButton>\n <Invite\n title={trainerInviteTitle}\n send={send}\n onCancel={() => {\n setInstitutePageTabIndex(2)\n goBack()\n next((s) => {\n s.send = false\n })\n }}\n onOk={() => {\n setInstitutePageTabIndex(2)\n goBack()\n next((s) => {\n s.send = false\n })\n }}\n onSend={payload => {\n dispatch({ type: 'Page/Service/TrainerInvite/Invite', payload })\n }}\n />\n </AppPageLayout>\n )\n}\n\nexport default TrainerInvite\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useTrainersState = createStateHook(\n AppStoreProvider,\n state => state.pages.trainers\n)\nexport const useNextTrainersState = () =>\n createNextHook(AppStoreProvider, state => state.pages.trainers)\n","import { Button, IconButton, TableCell, Tooltip } from '@material-ui/core'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport {\n GenericTable,\n GenericTableCellHeader,\n} from 'components/GenericTable/GenericTable'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { FormattedMessage } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useAppState, useDispatchHook } from 'state/store'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { useTrainersState } from './Trainers.restate'\nimport { TrainersTableData } from './Trainers.state'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Trainers.messages'\nimport { USERROLES } from 'model/UserRole'\n\nconst TrainersLoading = () => {\n const intl = useIntl()\n const trainersTitle = intl.formatMessage(messages.trainersTitle)\n\n return <AppPageLayout title={trainersTitle} loading={true}></AppPageLayout>\n}\n\nconst TrainersNotFound = () => {\n const intl = useIntl()\n const trainersNotFoundTitle = intl.formatMessage(\n messages.trainersNotFoundTitle\n )\n const trainersNotFoundMessage = intl.formatMessage(\n messages.trainersNotFoundMessage\n )\n\n return (\n <PageNotFound\n title={trainersNotFoundTitle}\n message={trainersNotFoundMessage}\n img={Images.detailedExamination}\n />\n )\n}\n\nconst TrainersTableEmpty = () => {\n const intl = useIntl()\n const trainersNotAvailableTitle = intl.formatMessage(\n messages.trainersNotAvailableTitle\n )\n const trainersNotAvailableMessage = intl.formatMessage(\n messages.trainersNotAvailableMessage\n )\n const trainersNotAvailableButton = intl.formatMessage(\n messages.trainersNotAvailableButton\n )\n\n const goTo = useGoToHook()\n const id = useAppState(state => (state.session.user.institute as any)._id)\n const goToTrainerInvitePage = () => goTo(AppRoutes.TrainerInvite, { id })\n\n return (\n <PageNotFound\n title={trainersNotAvailableTitle}\n message={trainersNotAvailableMessage}\n img={Images.medicine}\n action={() => (\n <Button\n variant='contained'\n color='secondary'\n onClick={goToTrainerInvitePage}\n >\n {trainersNotAvailableButton}\n </Button>\n )}\n />\n )\n}\n\nconst TrainersTable = () => {\n const intl = useIntl()\n const trainersTitle = intl.formatMessage(messages.trainersTitle)\n const selected = intl.formatMessage(messages.selected)\n const deleteLabel = intl.formatMessage(messages.deleteLabel)\n const tableRowName = intl.formatMessage(messages.tableRowName)\n const tableRowEmail = intl.formatMessage(messages.tableRowEmail)\n const inviteTrainer = intl.formatMessage(messages.inviteTrainer)\n\n const goTo = useGoToHook()\n const trainers: TrainersTableData[] = useTrainersState(trainerPage => \n trainerPage.data.map(trainer => {\n return {\n ...trainer,\n isSelectionEnabled: trainer.roles.filter(role => ![USERROLES.Trainer, USERROLES.Trainee].includes(role)).length === 0\n }\n })\n )\n const id = useAppState(state => (state.session.user.institute as any)._id)\n const goToTrainerInvitePage = () => goTo(AppRoutes.TrainerInvite, { id })\n const dispatch = useDispatchHook()\n\n const cellHeaders: GenericTableCellHeader[] = [\n {\n id: 'displayName',\n numeric: false,\n disablePadding: false,\n label: tableRowName,\n },\n {\n id: 'email',\n numeric: false,\n disablePadding: false,\n label: tableRowEmail,\n },\n { id: 'actions', numeric: true, disablePadding: false, label: '' },\n ]\n\n const search = (searchTerm: string) => {\n const searchExp = RegExp(searchTerm, 'i')\n return (entry: TrainersTableData) => {\n return searchExp.test(entry.displayName) || searchExp.test(entry.email)\n }\n }\n\n const navigateToUserDetailsPage = (id: string) =>\n goTo(AppRoutes.UserDetails, { id })\n\n const deleteTrainer = (ids: string[]) => {\n dispatch({ type: 'Pages/Trainers/Delete', payload: ids })\n }\n\n return (\n <AppPageLayout title={trainersTitle}>\n <div style={{ width: '100%', marginTop: theme.spacing(2) }}>\n <GenericTable\n rows={trainers}\n singleSelect={true}\n headers={cellHeaders}\n search={search as any}\n selectedItemsMessage={({ count }: { count: number }) => (\n <FormattedMessage\n id='admins_count'\n defaultMessage={`{count, number} {count, plural, one { trainer } other { trainers }} ${selected}`}\n values={{ count }}\n />\n )}\n rowRender={({ row }: { row: TrainersTableData }) => (\n <>\n <TableCell>{row.displayName}</TableCell>\n <TableCell>{row.email}</TableCell>\n <TableCell align='right'>\n <IconButton onClick={() => navigateToUserDetailsPage(row.id)}>\n <RightIcon />\n </IconButton>\n </TableCell>\n </>\n )}\n tools={({ selected, setSelected }) => (\n <Tooltip title={deleteLabel}>\n <IconButton\n aria-label={deleteLabel}\n onClick={() => {\n deleteTrainer(selected)\n setSelected([])\n }}\n >\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n )}\n />\n\n <div style={{ display: 'flex', flexDirection: 'row-reverse' }}>\n <Button\n variant='contained'\n color='secondary'\n size='small'\n onClick={goToTrainerInvitePage}\n >\n {inviteTrainer}\n </Button>\n </div>\n </div>\n </AppPageLayout>\n )\n}\n\nexport const Trainers: React.FC<{}> = () => {\n const { loading, notFound } = useTrainersState(s => s.meta)\n const empty = useTrainersState(s => s.data.length === 0)\n\n if (loading) return <TrainersLoading />\n if (notFound) return <TrainersNotFound />\n if (empty) return <TrainersTableEmpty />\n\n return <TrainersTable />\n}\n\nexport default Trainers\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n loadingTitle: {\n id: 'cp.pages.trainings.title',\n defaultMessage: 'Trainings',\n },\n trainingsNotFoundTitle: {\n id: 'cp.pages.trainings.notFound.title',\n defaultMessage: 'Nicht gefunden.',\n },\n trainingsNotFoundMessage: {\n id: 'cp.pages.trainings.notFound.message',\n defaultMessage: 'Wurde gelöscht. Sorry :(',\n },\n trainingsTrainee: {\n id: 'cp.pages.trainings.trainee',\n defaultMessage: 'Trainee',\n },\n trainingsFlow: {\n id: 'cp.pages.trainings.flow',\n defaultMessage: 'Flow',\n },\n trainingsDepth: {\n id: 'cp.pages.trainings.depth',\n defaultMessage: 'Depth',\n },\n trainingsRecoil: {\n id: 'cp.pages.trainings.recoil',\n defaultMessage: 'Recoil',\n },\n trainingsFrequency: {\n id: 'cp.pages.trainings.frequency',\n defaultMessage: 'Frequency',\n },\n trainingNumber: {\n id: 'cp.pages.trainings.trainingNumber',\n defaultMessage: 'Training #',\n },\n})\n","import {\n Card,\n CardContent,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport { CircularTrainingProgress } from 'components/CircularTrainingProgress/CircularTrainingProgress'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { FormattedDate, FormattedTime, useIntl } from 'react-intl'\nimport { useAppState } from 'state/store'\nimport { Colors } from 'theme/colors'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\n\nimport message from './Trainings.messages'\n\nconst useClasses = makeStyles({\n title: {\n fontSize: 26,\n marginLeft: theme.spacing(2),\n marginBottom: theme.spacing(2),\n },\n location: {\n fontSize: 22,\n },\n date: {\n fontSize: 12,\n },\n time: {\n fontSize: 22,\n },\n dateTime: {\n marginLeft: theme.spacing(2),\n marginBottom: theme.spacing(2),\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n },\n\n duration: {\n fontSize: 16,\n },\n\n card: {\n minWidth: '100%',\n marginBottom: theme.spacing(2),\n },\n\n circle: {\n margin: theme.spacing(1),\n },\n\n header: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n})\n\nconst TrainingsLoading = () => {\n const intl = useIntl()\n const loadingTitle = intl.formatMessage(message.loadingTitle)\n\n return <AppPageLayout title={loadingTitle} loading={true}></AppPageLayout>\n}\n\nconst TrainingsNotFound = () => {\n const intl = useIntl()\n const trainingsNotFoundTitle = intl.formatMessage(\n message.trainingsNotFoundTitle\n )\n const trainingsNotFoundMessage = intl.formatMessage(\n message.trainingsNotFoundMessage\n )\n\n return (\n <PageNotFound\n title={trainingsNotFoundTitle}\n message={trainingsNotFoundMessage}\n img={Images.detailedExamination}\n />\n )\n}\n\nexport const Trainings: React.FC<{}> = () => {\n const intl = useIntl()\n const trainingTitle = intl.formatMessage(message.loadingTitle)\n const trainingsTrainee = intl.formatMessage(message.trainingsTrainee)\n const trainingsFlow = intl.formatMessage(message.trainingsFlow)\n const trainingsDepth = intl.formatMessage(message.trainingsDepth)\n const trainingsRecoil = intl.formatMessage(message.trainingsRecoil)\n const trainingsFrequency = intl.formatMessage(message.trainingsFrequency)\n const trainingNumber = intl.formatMessage(message.trainingNumber)\n\n const { loading, notFound } = useAppState(s => s.pages.course.meta)\n const course = useAppState(s => s.pages.course.course)\n const trainingsPage = useAppState(s => s.pages.trainings)\n\n const classes = useClasses()\n\n const training = course?.trainings[trainingsPage.idx]\n\n if (loading) {\n return <TrainingsLoading />\n }\n\n if (notFound || training == null) {\n return <TrainingsNotFound />\n }\n\n return (\n <AppPageLayout title={trainingTitle} showBackButton={true}>\n <>\n <Card className={classes.card}>\n <CardContent>\n <div className={classes.header}>\n <div>\n <Typography className={classes.title}>\n {trainingNumber}\n {Number(trainingsPage.idx) + 1}\n </Typography>\n </div>\n <div className={classes.dateTime}>\n <Typography className={classes.time}>\n <FormattedTime value={training.date} />\n </Typography>\n\n <Typography className={classes.date}>\n <FormattedDate\n value={training.date}\n year='numeric'\n month='long'\n day='2-digit'\n />\n </Typography>\n </div>\n </div>\n\n <Table>\n <TableHead>\n <TableCell>{trainingsTrainee}</TableCell>\n <TableCell>{trainingsFlow}</TableCell>\n <TableCell>{trainingsDepth}</TableCell>\n <TableCell>{trainingsRecoil}</TableCell>\n <TableCell>{trainingsFrequency}</TableCell>\n </TableHead>\n <TableBody>\n {training.sessions.map(session => (\n <TableRow>\n <TableCell>{session.trainee}</TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n className={classes.circle}\n value={session.result.flowPercent}\n color={Colors.primary[3]}\n />\n </TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n className={classes.circle}\n value={session.result.cprCorrectDepthPercent}\n color={Colors.vivid[3]}\n />\n </TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n className={classes.circle}\n value={session.result.cprCorrectRecoilPercent}\n color={Colors.supportingLime[3]}\n />\n </TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n className={classes.circle}\n value={session.result.cprCorrectFrequencyPercent}\n color={Colors.supportingCyan[3]}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </>\n </AppPageLayout>\n )\n}\n\nexport default Trainings\n","import {\n createStateHook,\n createNextHook,\n createActionsHook,\n ActionFactoryProps,\n} from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\nimport { UserChangeEmailState } from './UserChangeEmail.state'\nimport { AppMessages } from 'state/appMessages'\nimport { isEmail } from 'utils/isEmail'\n\nexport const useUserChangeEmailState = createStateHook(\n AppStoreProvider,\n state => state.pages.userChangeEmail\n)\nexport const useNextUserChangeEmailState = () =>\n createNextHook(AppStoreProvider, state => state.pages.userChangeEmail)\n\nconst UserChangeEmailActions = ({\n next,\n state,\n dispatch,\n}: ActionFactoryProps<UserChangeEmailState, AppMessages>) => {\n function validateEmail() {\n const { nextEmail } = state()\n if (nextEmail === '') {\n next(s => {\n s.errorNextEmail = true\n s.errorNextEmailMessage = 'eMail is empty'\n })\n return false\n }\n\n if (!isEmail(nextEmail)) {\n next(s => {\n s.errorNextEmail = true\n s.errorNextEmailMessage = 'This is not a valid eMail address'\n })\n return false\n }\n\n next(s => {\n s.errorNextEmail = false\n })\n\n return true\n }\n\n function setNextEmail(nextEmail: string) {\n next(s => {\n s.errorNextEmail = false\n s.errorNextEmailMessage = ''\n s.nextEmail = nextEmail\n })\n }\n\n function sendChangeEmailRequest() {\n const ok = validateEmail()\n if (ok) {\n dispatch({ type: 'USER/CHANGE_EMAIL/SEND' })\n }\n }\n\n return {\n validateEmail,\n setNextEmail,\n sendChangeEmailRequest,\n }\n}\n\nexport const useUserChangeEmailActions = createActionsHook(\n AppStoreProvider,\n state => state.pages.userChangeEmail,\n UserChangeEmailActions\n)\n","import {\n Button,\n Card,\n CardActions,\n CardContent,\n TextField,\n Typography,\n} from '@material-ui/core'\nimport CheckCircleIcon from '@material-ui/icons/CheckCircle'\nimport { makeStyles } from '@material-ui/styles'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { Colors } from 'theme/colors'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport {\n useUserChangeEmailActions,\n useUserChangeEmailState,\n} from './UserChangeEmail.restate'\nimport {\n ImageCard,\n ImageCardContent,\n ImageCardActions,\n} from 'components/ImageCard/ImageCard'\nimport { useIntl } from 'react-intl'\nimport messages from './UserChangeEmail.messages'\nimport { useGoBack } from 'services/router/useGoBack.hook'\nimport {\n useAppState,\n useDispatchHook,\n useNextAppState,\n} from '../../state/store'\n\nconst useClasses = makeStyles({\n title: {\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2),\n },\n\n send: {\n display: 'flex',\n minWidth: 400,\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n },\n\n checkCircleIcon: {\n width: 80,\n height: 80,\n [theme.breakpoints.down('xs')]: {\n width: 60,\n height: 60,\n margin: theme.spacing(2),\n },\n margin: theme.spacing(3),\n color: Colors.supportingCyan[3],\n },\n})\n\nconst UserChangeEmailLoading = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.email)\n\n return <AppPageLayout title={pageTitle} loading={true}></AppPageLayout>\n}\n\nconst UserChangeEmailNotFound = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n\n return (\n <PageNotFound\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.empty}\n />\n )\n}\n\nconst EMailForm = () => {\n const intl = useIntl()\n const verifyEmailTitle = intl.formatMessage(messages.verifyEmailTitle)\n const verifyEmailContent = intl.formatMessage(messages.verifyEmailContent)\n const verifyEmailButton = intl.formatMessage(messages.verifyEmailButton)\n const changeEmail = intl.formatMessage(messages.changeEmail)\n const newEmail = intl.formatMessage(messages.newEmail)\n const cancelButton = intl.formatMessage(messages.cancelButton)\n const pageTitle = intl.formatMessage(messages.email)\n\n const onboardingState = useAppState(s => s.pages.onboarding)\n\n const classes = useClasses()\n const goBack = useGoBack()\n const dispatch = useDispatchHook()\n\n const sendVerificationEmailRequest = () => {\n dispatch({ type: 'Pages/Service/Reminder/Email/Verify' })\n }\n\n const {\n nextEmail,\n errorNextEmail,\n errorNextEmailMessage,\n } = useUserChangeEmailState(s => s)\n const {\n setNextEmail,\n sendChangeEmailRequest,\n validateEmail,\n } = useUserChangeEmailActions()\n\n return (\n <AppPageLayout title={pageTitle}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>\n {onboardingState.onboarding.emailAddressVerified === false && (\n <ImageCard imgUrl={Images.emailValidation}>\n <ImageCardContent>\n <Typography className={classes.title} variant='h5'>\n {verifyEmailTitle}\n </Typography>\n\n <Typography variant='body1'>{verifyEmailContent}</Typography>\n </ImageCardContent>\n <ImageCardActions>\n <Button\n color='secondary'\n variant='contained'\n onClick={sendVerificationEmailRequest}\n >\n {verifyEmailButton}\n </Button>\n </ImageCardActions>\n </ImageCard>\n )}\n\n <ImageCard imgUrl={Images.mail}>\n <ImageCardContent>\n <Typography className={classes.title} variant='h5'>\n {changeEmail}\n </Typography>\n <TextField\n value={nextEmail}\n label={newEmail}\n onBlur={validateEmail}\n onChange={e => setNextEmail(e.target.value)}\n error={errorNextEmail}\n helperText={errorNextEmailMessage}\n type='email'\n placeholder='hello@corpatch.de'\n />\n </ImageCardContent>\n <ImageCardActions>\n <Button\n color='secondary'\n variant='contained'\n onClick={sendChangeEmailRequest}\n >\n {changeEmail}\n </Button>\n <Button onClick={goBack}>{cancelButton}</Button>\n </ImageCardActions>\n </ImageCard>\n </div>\n </AppPageLayout>\n )\n}\n\nconst EMailSend = () => {\n const intl = useIntl()\n const sendEmail = intl.formatMessage(messages.sendEmail)\n const OK = intl.formatMessage(messages.ok)\n const classes = useClasses()\n const pageTitle = intl.formatMessage(messages.email)\n\n const next = useNextAppState(s => s.pages.userChangeEmail)\n\n return (\n <AppPageLayout title={pageTitle}>\n <Card>\n <CardContent>\n <div className={classes.send}>\n <CheckCircleIcon\n color='inherit'\n className={classes.checkCircleIcon}\n />\n <Typography variant='h6' style={{ marginBottom: 20 }}>\n {sendEmail}\n </Typography>\n </div>\n </CardContent>\n\n <CardActions style={{ flexDirection: 'row-reverse' }}>\n <Button\n type='button'\n onClick={() => next(s => (s.send = false))}\n variant='contained'\n color='secondary'\n >\n {OK}\n </Button>\n </CardActions>\n </Card>\n </AppPageLayout>\n )\n}\n\nexport const UserChangeEmail: React.FC<{}> = () => {\n const { loading, notFound } = useUserChangeEmailState(s => s.meta)\n const send = useUserChangeEmailState(s => s.send)\n\n if (loading) return <UserChangeEmailLoading />\n else if (notFound) return <UserChangeEmailNotFound />\n else if (send) return <EMailSend />\n else return <EMailForm />\n}\n\nexport default UserChangeEmail\n","import { Button, TextField } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport React, { ChangeEvent, useState } from 'react'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { useIntl } from 'react-intl'\n\nimport messages from './ChangePassword.messages'\nimport { config } from 'config/config'\n\nconst useClasses = makeStyles({\n inputField1: {\n marginTop: theme.spacing(5),\n minHeight: 70,\n [theme.breakpoints.down('xs')]: {\n marginTop: 0,\n width: '100%',\n },\n },\n inputField: {\n marginBottom: theme.spacing(2),\n minHeight: 70,\n },\n})\n\ninterface ChangePasswordProps {\n onSend: (props: { oldPassword: string; newPassword: string }) => any\n}\n\nexport const ChangePassword: React.FC<ChangePasswordProps> = props => {\n const intl = useIntl()\n const requiredError = intl.formatMessage(messages.passwordRequired)\n const equalError = intl.formatMessage(messages.passwordEqual)\n const newRequiredError = intl.formatMessage(messages.newPasswordRequired)\n const matchError = intl.formatMessage(messages.passwordDontMatch)\n const currentPassword = intl.formatMessage(messages.currentPassword)\n const newPassword = intl.formatMessage(messages.newPassword)\n const newPasswordRepeat = intl.formatMessage(messages.newPasswordRepeat)\n const changePasswordButton = intl.formatMessage(messages.changePasswordButton)\n const newToShortError = intl.formatMessage(messages.newToShortError)\n\n const { onSend } = props\n const classes = useClasses()\n\n const [oldPassword, setOldPassword] = useState('')\n const [errorOldPassword, setErrorOldPassword] = useState(false)\n const [errorOldPasswordMessage, setErrorOldPasswordMessage] = useState('')\n\n const [newPassword0, setNewPassword0] = useState('')\n const [errorNewPassword0, setErrorNewPassword0] = useState(false)\n const [errorNewPasswordMessage0, setErrorNewPasswordMessage0] = useState('')\n\n const [newPassword1, setNewPassword1] = useState('')\n const [errorNewPassword1, setErrorNewPassword1] = useState(false)\n const [errorNewPasswordMessage1, setErrorNewPasswordMessage1] = useState('')\n\n const PASSWORD_MIN_LEN = config().passwordMinLen\n\n //\n // Old password\n //\n function resetOldPasswordValidation() {\n setErrorOldPassword(false)\n setErrorOldPasswordMessage('')\n }\n\n function validateOldPassword() {\n resetOldPasswordValidation()\n\n if (oldPassword === '') {\n setErrorOldPassword(true)\n setErrorOldPasswordMessage(requiredError)\n }\n }\n\n //\n // NewPassword0\n //\n function resetNewPassword0Validation() {\n setErrorNewPassword0(false)\n setErrorNewPasswordMessage0('')\n }\n\n function validateNewPassword0() {\n resetNewPassword0Validation()\n\n if (newPassword0 === oldPassword) {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(equalError)\n }\n\n if (newPassword0 === '') {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newRequiredError)\n }\n if (newPassword0.length < PASSWORD_MIN_LEN) {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newToShortError)\n }\n }\n\n //\n // NewPassword1\n //\n function resetNewPassword1Validation() {\n setErrorNewPassword1(false)\n setErrorNewPasswordMessage1('')\n }\n\n function validateNewPassword1() {\n resetNewPassword1Validation()\n\n if (newPassword0 !== newPassword1) {\n setErrorNewPassword1(true)\n setErrorNewPasswordMessage1(matchError)\n }\n\n if (newPassword0.length < PASSWORD_MIN_LEN) {\n setErrorNewPassword0(true)\n setErrorNewPasswordMessage0(newToShortError)\n }\n }\n\n function validate() {\n validateOldPassword()\n validateNewPassword0()\n validateNewPassword1()\n\n const errorNewPasswordMatch = newPassword0 !== newPassword1\n\n return !errorNewPasswordMatch && !errorOldPassword && !errorNewPassword0\n }\n\n function handleSetOldPassword(e: ChangeEvent<HTMLInputElement>) {\n resetOldPasswordValidation()\n setOldPassword(e.target.value)\n }\n\n function handleSetNewPassword0(e: ChangeEvent<HTMLInputElement>) {\n resetNewPassword0Validation()\n setNewPassword0(e.target.value)\n }\n\n function handleSetNewPassword1(e: ChangeEvent<HTMLInputElement>) {\n resetNewPassword1Validation()\n setNewPassword1(e.target.value)\n }\n\n function sendChangePasswordRequest() {\n const valid = validate()\n if (valid) {\n onSend({ oldPassword, newPassword: newPassword0 })\n }\n }\n\n return (\n <ImageCard imgUrl={Images.securityOn}>\n <ImageCardContent>\n <TextField\n value={oldPassword}\n autoFocus\n label={currentPassword}\n onChange={handleSetOldPassword}\n className={classes.inputField1}\n onBlur={validateOldPassword}\n error={errorOldPassword}\n helperText={errorOldPasswordMessage}\n type='password'\n placeholder={currentPassword}\n />\n <TextField\n value={newPassword0}\n label={newPassword}\n onChange={handleSetNewPassword0}\n className={classes.inputField}\n onBlur={validateNewPassword0}\n error={errorNewPassword0}\n helperText={errorNewPasswordMessage0}\n type='password'\n placeholder={newPassword}\n />\n <TextField\n value={newPassword1}\n label={newPasswordRepeat}\n onChange={handleSetNewPassword1}\n onBlur={validateNewPassword1}\n className={classes.inputField}\n error={errorNewPassword1}\n helperText={errorNewPasswordMessage1}\n type='password'\n placeholder={newPasswordRepeat}\n />\n </ImageCardContent>\n <ImageCardActions>\n <Button\n color='secondary'\n variant='contained'\n onClick={sendChangePasswordRequest}\n >\n {changePasswordButton}\n </Button>\n </ImageCardActions>\n </ImageCard>\n )\n}\n\nexport default ChangePassword\n","import { createNextHook, createStateHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useUserChangePasswordState = createStateHook(\n AppStoreProvider,\n state => state.pages.userChangePassword\n)\nexport const useNextUserChangePasswordState = () =>\n createNextHook(AppStoreProvider, state => state.pages.userChangePassword)\n","import ChangePassword from 'components/ChangePassword/ChangePassword'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { useDispatchHook } from 'state/store'\nimport { Images } from 'theme/Images'\nimport { useUserChangePasswordState } from './UserChangePassword.restate'\nimport { useIntl } from 'react-intl'\n\nimport messages from './UserChangePassword.messages'\n\nconst UserChangePasswordLoading = () => {\n const intl = useIntl()\n const loadingTitle = intl.formatMessage(messages.loadingTitle)\n\n return <AppPageLayout title={loadingTitle} loading={true}></AppPageLayout>\n}\n\nconst UserChangePasswordNotFound = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n\n return (\n <PageNotFound\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.empty}\n />\n )\n}\n\nexport const UserChangePassword: React.FC<{}> = () => {\n const intl = useIntl()\n const dispatch = useDispatchHook()\n const loadingTitle = intl.formatMessage(messages.loadingTitle)\n const { loading, notFound } = useUserChangePasswordState(s => s.meta)\n\n function onSend({\n oldPassword,\n newPassword,\n }: {\n oldPassword: string\n newPassword: string\n }) {\n dispatch({\n type: 'Page/ChangePassword/Send',\n payload: {\n oldPassword,\n newPassword,\n },\n })\n }\n\n if (loading) return <UserChangePasswordLoading />\n if (notFound) return <UserChangePasswordNotFound />\n\n return (\n <AppPageLayout title={loadingTitle}>\n <ChangePassword onSend={onSend} />\n </AppPageLayout>\n )\n}\n\nexport default UserChangePassword\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useUserDetailsState = createStateHook(\n AppStoreProvider,\n state => state.pages.userDetails\n)\nexport const useNextUserDetailsState = () =>\n createNextHook(AppStoreProvider, state => state.pages.userDetails)\n","import { Button, Grid, Typography } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { useDispatchHook } from 'state/store'\nimport { CARD_DEFAULTS } from 'styles/styles'\nimport { Colors } from 'theme/colors'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport generalMessages from '../../I18N/general.messages'\nimport messages from './UserDetails.messages'\nimport { useUserDetailsState } from './UserDetails.restate'\n\nconst useClasses = makeStyles({\n submitButton: {\n marginTop: 40,\n },\n\n form: {\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n },\n\n innerContainer: {\n marginTop: theme.spacing(3),\n marginBottom: theme.spacing(5),\n height: 'auto',\n [theme.breakpoints.down('xs')]: {\n height: 'auto',\n },\n },\n\n error: {\n ...theme.typography.h6,\n color: theme.palette.error.dark,\n padding: theme.spacing(),\n fontSize: '1rem',\n backgroundColor: theme.palette.grey[50],\n border: '1px solid ' + theme.palette.primary.dark,\n },\n\n center: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n flexGrow: 1,\n backgroundColor: Colors.neutrals[9],\n },\n\n card: {\n ...CARD_DEFAULTS,\n },\n\n cardContent: {\n height: '100%',\n },\n\n cardContainer: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n height: '100%',\n },\n\n cardImg: {\n display: 'flex',\n marginLeft: theme.spacing(3),\n marginRight: theme.spacing(3),\n marginTop: theme.spacing() + 5,\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n '& img': {\n width: 220,\n // height: 100,\n },\n [theme.breakpoints.down('xs')]: {\n display: 'none',\n },\n },\n\n cardForm: {},\n\n actions: {\n display: 'flex',\n flexDirection: 'row-reverse',\n alignItems: 'center',\n '& button': {\n marginLeft: theme.spacing(),\n },\n },\n\n send: {\n display: 'flex',\n height: 215,\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n },\n\n checkCircleIcon: {\n width: 80,\n height: 80,\n [theme.breakpoints.down('xs')]: {\n width: 60,\n height: 60,\n margin: theme.spacing(2),\n },\n margin: theme.spacing(3),\n color: Colors.supportingLime[5],\n },\n})\n\nconst UserDetailsLoading = () => (\n <AppPageLayout showBackButton={true} title='' loading={true}></AppPageLayout>\n)\n\nconst UserDetailsNotFound = () => {\n const intl = useIntl()\n const pageNotFoundTitle = intl.formatMessage(messages.pageNotFoundTitle)\n const pageNotFoundMessage = intl.formatMessage(messages.pageNotFoundMessage)\n\n return (\n <PageNotFound\n title={pageNotFoundTitle}\n message={pageNotFoundMessage}\n img={Images.missingUrl}\n />\n )\n}\n\nexport const UserDetails: React.FC<{}> = () => {\n const intl = useIntl()\n const tableRowName = intl.formatMessage(generalMessages.tableRowName)\n const invitation = intl.formatMessage(messages.invitation)\n const sendInvitation = intl.formatMessage(messages.sendInvitation)\n const signUpAccepted = intl.formatMessage(messages.signUpAccepted)\n const signUpPending = intl.formatMessage(messages.signUpPending)\n const userDetailsEmail = intl.formatMessage(messages.userDetailsEmail)\n\n const { loading, notFound } = useUserDetailsState(s => s.meta)\n const userDetails = useUserDetailsState(s => s.userDetails)\n const classes = useClasses()\n const dispatch = useDispatchHook()\n\n if (loading) return <UserDetailsLoading />\n if (notFound) return <UserDetailsNotFound />\n if (!userDetails) return <UserDetailsNotFound />\n\n const sendInvite = () => dispatch({ type: 'Page/UserDetails/SendInvite' })\n\n const title = userDetails.firstName + ' ' + userDetails.familyName\n\n return (\n <AppPageLayout title={title} showBackButton={true}>\n <ImageCard\n imgUrl={\n userDetails.gender === 'male'\n ? Images.maleAvatar\n : Images.femaleAvatar\n }\n >\n <ImageCardContent>\n <Grid\n direction='column'\n container={true}\n className={classes.innerContainer}\n >\n <Typography variant='caption'>{tableRowName}</Typography>\n <Typography variant='body1'>\n {userDetails.firstName} {userDetails.familyName}\n </Typography>\n\n <Typography\n variant='caption'\n style={{ marginTop: theme.spacing(2) }}\n >\n {userDetailsEmail}\n </Typography>\n <Typography variant='body1'>{userDetails.email} </Typography>\n\n <Typography\n variant='caption'\n style={{ marginTop: theme.spacing(2) }}\n >\n {invitation}\n </Typography>\n <Typography variant='body1'>\n {userDetails.signUpStatus === 'valid'\n ? signUpAccepted\n : signUpPending}\n </Typography>\n </Grid>\n </ImageCardContent>\n <ImageCardActions>\n <Button\n type='submit'\n variant='contained'\n color='secondary'\n disabled={false}\n onClick={sendInvite}\n >\n {sendInvitation}\n </Button>\n </ImageCardActions>\n </ImageCard>\n </AppPageLayout>\n )\n}\n\nexport default UserDetails\n","import React from 'react'\nimport { Card } from '@material-ui/core'\nimport CardContent from '@material-ui/core/CardContent'\nimport Typography from '@material-ui/core/Typography'\nimport CardActions from '@material-ui/core/CardActions'\nimport Button from '@material-ui/core/Button'\nimport { makeStyles } from '@material-ui/styles'\nimport AndroidIcon from '@material-ui/icons/Android'\nimport AppleIcon from '@material-ui/icons/Apple'\n\nconst useStyles = makeStyles({\n card: {\n width: '100%',\n margin: '5% 0',\n },\n cancelCardButton: {\n display: 'block',\n float: 'right',\n cursor: 'pointer',\n },\n cardTitle: {\n width: '100%',\n fontWeight: 'bold',\n textAlign: 'center',\n },\n cardImage: {\n width: '25%',\n },\n cardContent: {\n width: '70%',\n textAlign: 'center',\n },\n cardButton: {\n margin: 'auto',\n },\n})\n\ninterface ReminderTileProps {\n images: { src: string; }[]\n title: string\n message: string\n buttonText: string\n secondaryButtonText?: string\n clickHandlerPrimary: () => void\n clickHandlerSecondary?: () => void\n}\n\nexport const ReminderTile = ({\n images,\n message,\n title,\n buttonText,\n secondaryButtonText,\n clickHandlerPrimary,\n clickHandlerSecondary,\n}: ReminderTileProps) => {\n const classes = useStyles()\n\n return (\n <Card className={classes.card}>\n <CardContent>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n alignItems: 'center',\n }}\n >\n <Typography className={classes.cardTitle} variant='h4'>\n {title}\n </Typography>\n\n <div\n style={{\n width: '100%',\n display: 'flex',\n gap: '1rem',\n justifyContent: 'space-around',\n }}\n >\n {images.map(({ src }, index) => (\n <img\n key={index}\n src={src}\n className={classes.cardImage}\n alt=''\n />\n ))}\n </div>\n\n <Typography className={classes.cardContent} variant='body1'>\n {message}\n </Typography>\n </div>\n </CardContent>\n <CardActions>\n <Button\n className={classes.cardButton}\n onClick={clickHandlerPrimary}\n size='medium'\n >\n <AndroidIcon style={{ margin: '0 5px' }} fontSize='small' />\n\n {buttonText}\n </Button>\n\n {secondaryButtonText && (\n <Button\n className={classes.cardButton}\n onClick={clickHandlerSecondary}\n size='medium'\n >\n <AppleIcon style={{ margin: '0 5px' }} fontSize='small' />\n\n {secondaryButtonText}\n </Button>\n )}\n </CardActions>\n </Card>\n )\n}\n\nexport default ReminderTile\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n title: {\n id: 'cp.components.reminder.title',\n defaultMessage: 'Home',\n },\n welcome: {\n id: 'cp.components.reminder.welcome',\n defaultMessage: 'Welcome',\n },\n appTitle: {\n id: 'cp.components.reminder.app.title',\n defaultMessage: 'Want to start? Download the App!',\n },\n appContent: {\n id: 'cp.components.reminder.app.content',\n defaultMessage:\n 'In order to unlock the full potential of CorPatch please download our App from the Google-Playstore and get your training started today. You are able to chose from multiple different training simulations and you`ll get feedback for every training you finish. In browser and the app you will see all your results and how you get better every time you practice.',\n },\n appPlayStoreButton: {\n id: 'cp.components.reminder.app.appPlayStoreButton',\n defaultMessage: 'Get the App',\n },\n appAppStoreButton: {\n id: 'cp.components.reminder.app.appAppStoreButton',\n defaultMessage: 'Get the App',\n },\n})\n","import React from 'react'\nimport { makeStyles } from '@material-ui/styles'\nimport { AppPageLayout } from '../layouts/AppPageLayout'\nimport { useAppState } from '../../state/store'\nimport Typography from '@material-ui/core/Typography'\nimport { useIntl } from 'react-intl'\nimport ReminderTile from './ReminderTile'\nimport { Images } from 'theme/Images'\nimport { config } from '../../config/config'\n\nimport messages from './Reminder.messages'\n\nconst {\n APPLE_APP_STORE_CPS_URL,\n GOOGLE_PLAY_STORE_CPS_URL\n} = config()\n\nconst useStyles = makeStyles({\n title: { textAlign: 'center' },\n reminderContainer: {\n display: 'flex',\n flexWrap: 'wrap',\n width: '100%',\n },\n})\n\nconst Loading = () => {\n const intl = useIntl()\n const title = intl.formatMessage(messages.title)\n\n return <AppPageLayout title={title} loading={true}></AppPageLayout>\n}\n\nexport const Reminder = () => {\n const intl = useIntl()\n const title = intl.formatMessage(messages.title)\n const welcome = intl.formatMessage(messages.welcome)\n\n const appTitle = intl.formatMessage(messages.appTitle)\n const appContent = intl.formatMessage(messages.appContent)\n const appPlayStoreButton = intl.formatMessage(messages.appPlayStoreButton)\n const appAppStoreButton = intl.formatMessage(messages.appAppStoreButton)\n\n const classes = useStyles()\n\n const onboardingState = useAppState(s => s.pages.onboarding)\n const user = useAppState(s => s.session.user)\n\n if (onboardingState.meta.loading || !onboardingState.onboarding) {\n return <Loading />\n }\n\n return (\n <AppPageLayout title={title}>\n <Typography className={classes.title} variant='h2' color='textPrimary'>\n {`${welcome} ${user.firstName} ${user.familyName}`}\n </Typography>\n <div className={classes.reminderContainer}>\n <ReminderTile\n images={[\n { src: Images.qrCodePlayStoreCPS },\n { src: Images.qrCodeAppStoreCPS },\n ]}\n title={appTitle}\n message={appContent}\n buttonText={appPlayStoreButton}\n secondaryButtonText={appAppStoreButton}\n clickHandlerPrimary={() => window.open(GOOGLE_PLAY_STORE_CPS_URL)}\n clickHandlerSecondary={() => window.open(APPLE_APP_STORE_CPS_URL)}\n />\n </div>\n </AppPageLayout>\n )\n}\n\nexport default Reminder\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n userOrPasswordNotFound: {\n id: 'cp.pages.login.userOrPasswordNotFound',\n defaultMessage: 'User or password not found',\n },\n userNewlyRegisteredLabel1: {\n id: 'cp.pages.login.userNewlyRegisteredLabel1',\n defaultMessage: 'You have been registered successfully.',\n },\n userNewlyRegisteredLabel2: {\n id: 'cp.pages.login.userNewlyRegisteredLabel2',\n defaultMessage:\n 'Dont forget to confirm your E-Mail address and login righ away.',\n },\n email: {\n id: 'cp.pages.login.email',\n defaultMessage: 'EMail',\n },\n password: {\n id: 'cp.pages.login.password',\n defaultMessage: 'Password',\n },\n passwordForgot: {\n id: 'cp.pages.login.passwordForgot',\n defaultMessage: 'Forgot password?',\n },\n loginButton: {\n id: 'cp.pages.login.loginButton',\n defaultMessage: 'Login',\n },\n registerButton: {\n id: 'cp.pages.login.registerButton',\n defaultMessage: 'Register',\n },\n loginInstitutesTitle: {\n id: 'cp.pages.login.loginInstitutesTitle',\n defaultMessage: 'Institutes',\n },\n termsOfUseButton: {\n id: 'cp.pages.login.termsOfUseButton',\n defaultMessage: 'terms of use',\n },\n})\n","import { CircularProgress } from '@material-ui/core'\nimport Button from '@material-ui/core/Button'\nimport FormControl from '@material-ui/core/FormControl'\nimport Grid from '@material-ui/core/Grid'\nimport Input from '@material-ui/core/Input'\nimport InputAdornment from '@material-ui/core/InputAdornment'\nimport InputLabel from '@material-ui/core/InputLabel'\nimport EmailIcon from '@material-ui/icons/Email'\nimport LockIcon from '@material-ui/icons/Lock'\nimport { makeStyles } from '@material-ui/styles'\nimport React from 'react'\nimport { FormattedMessage, useIntl } from 'react-intl'\nimport { theme } from 'theme/theme'\nimport { useLoginActions, useLoginState } from './Login.restate'\nimport { Colors } from 'theme/colors'\n\nimport messages from './Login.messages'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { AppRoutes } from 'routes'\nimport { useAppState } from 'state/store'\nimport { useRTL } from 'utils/useRTL'\n\nconst useClasses = makeStyles({\n formItem: {\n marginTop: '10px',\n marginLeft: '10px',\n marginRight: '10px',\n },\n\n submitButton: {\n marginTop: 20,\n },\n\n innerContainer: {\n height: 'auto',\n [theme.breakpoints.down('xs')]: {\n height: 'auto',\n },\n },\n\n forgotPassword: {\n marginLeft: 10,\n marginTop: 10,\n marginBottom: theme.spacing() * 2,\n color: theme.palette.primary.main,\n cursor: 'pointer',\n },\n\n error: {\n ...theme.typography.h6,\n color: theme.palette.error.dark,\n padding: theme.spacing(),\n fontSize: '1rem',\n backgroundColor: theme.palette.grey[50],\n border: '1px solid ' + theme.palette.primary.dark,\n },\n})\n\nconst EmailAndPasswordForm: React.FC = () => {\n const classes = useClasses()\n\n const intl = useIntl()\n const userOrPasswordNotFoundLabel = intl.formatMessage(\n messages.userOrPasswordNotFound\n )\n const userNewlyRegisteredLabel1 = intl.formatMessage(\n messages.userNewlyRegisteredLabel1\n )\n const userNewlyRegisteredLabel2 = intl.formatMessage(\n messages.userNewlyRegisteredLabel2\n )\n const termsOfUseButton = intl.formatMessage(messages.termsOfUseButton)\n\n const { error, email, password } = useLoginState()\n const { setPassword, setEmail, signIn } = useLoginActions()\n const registerSuccess = useAppState(state => state.pages.register.success)\n const embeddedMode = useAppState(state => state.routerExtension.embeddedMode)\n\n const goTo = useGoToHook()\n const showResetDialog = () => goTo(AppRoutes.LoginPasswordForgot)\n const isRTL = useRTL()\n\n return (\n <form onSubmit={signIn}>\n {error ? (\n <div className={classes.error}>{userOrPasswordNotFoundLabel}</div>\n ) : registerSuccess ? (\n <div\n className={classes.error}\n style={{ color: theme.palette.success.light }}\n >\n {userNewlyRegisteredLabel1}\n <br></br>\n {userNewlyRegisteredLabel2}\n </div>\n ) : null}\n <Grid\n direction='column'\n container={true}\n className={classes.innerContainer}\n >\n <FormControl className={classes.formItem}>\n <InputLabel htmlFor='email'>\n <FormattedMessage {...messages.email} />\n </InputLabel>\n <Input\n id='email'\n type='email'\n value={email}\n autoComplete='email'\n onChange={event => setEmail(event.target.value)}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <EmailIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <EmailIcon color='action' />\n </InputAdornment>\n )\n }\n />\n </FormControl>\n <FormControl className={classes.formItem}>\n <InputLabel htmlFor='adornment-password'>\n <FormattedMessage id={messages.password.id} />\n </InputLabel>\n <Input\n id='adornment-password'\n type='password'\n autoComplete='password'\n value={password}\n onChange={event => setPassword(event.target.value)}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <LockIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <LockIcon color='action' />\n </InputAdornment>\n )\n }\n />\n </FormControl>\n\n <div className={classes.forgotPassword}>\n <Button\n color='inherit'\n style={{ color: Colors.neutrals[6] }}\n size='small'\n onClick={showResetDialog}\n >\n <FormattedMessage id={messages.passwordForgot.id} />\n </Button>\n </div>\n\n <div\n style={{\n flexDirection: 'column',\n display: 'flex',\n marginBottom: theme.spacing() * 3,\n }}\n >\n <Button\n variant='contained'\n size='large'\n color='primary'\n className={classes.formItem + ' ' + classes.submitButton}\n type='submit'\n >\n <FormattedMessage {...messages.loginButton} />\n </Button>\n <Button\n variant='contained'\n size='large'\n color='secondary'\n className={classes.formItem + ' ' + classes.submitButton}\n onClick={() => goTo(AppRoutes.Register)}\n >\n <FormattedMessage {...messages.registerButton} />\n </Button>\n </div>\n </Grid>\n {!embeddedMode && (\n <Button\n color='primary'\n style={{ fontSize: '75%' }}\n onClick={() => goTo(AppRoutes.LoginTermsOfUse)}\n >\n {termsOfUseButton}\n </Button>\n )}\n </form>\n )\n}\n\nexport const Busy = () => {\n return (\n <div\n style={{\n minHeight: 130,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <CircularProgress />\n </div>\n )\n}\n\nexport const SignInForm: React.FC = () => {\n const { showProgress } = useLoginState()\n if (showProgress) {\n return <Busy />\n } else {\n return <EmailAndPasswordForm />\n }\n}\n","import { CardContent } from '@material-ui/core'\nimport Card from '@material-ui/core/Card'\nimport { makeStyles } from '@material-ui/styles'\nimport { MainPageLayout } from 'components/layouts/MainPageLayout'\nimport React from 'react'\nimport { center } from 'styles/styles'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport { Images } from '../../theme/Images'\nimport { SignInForm } from './LoginForm'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Login.messages'\n\nconst useStyles = makeStyles({\n center: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n flexGrow: 1,\n backgroundColor: Colors.background[0],\n },\n\n card: {\n minWidth: 400,\n minHeight: 516,\n borderTop: `4px solid ${Colors.primary[3]}`,\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n width: '100%',\n height: '100%',\n borderRadius: 0,\n },\n borderRadius: 8,\n },\n\n titleBg: {\n position: 'relative',\n maxWidth: '250px',\n top: '50px',\n borderRadius: 8,\n },\n\n logo: {\n ...center,\n marginBottom: theme.spacing() * 3,\n marginTop: theme.spacing() * 3,\n },\n\n title: {\n fontSize: '1.4rem',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n\n logoImg: {},\n})\n\nexport const Login = () => {\n const intl = useIntl()\n const loginInstitutesTitle = intl.formatMessage(messages.loginInstitutesTitle)\n\n const { center, card, logo, logoImg } = useStyles()\n\n return (\n <MainPageLayout title={loginInstitutesTitle} showTranslationSwitch>\n <div className={center}>\n <Card className={card} elevation={3}>\n <CardContent>\n <div className={logo}>\n <img\n className={logoImg}\n height='150'\n src={Images.logoSmallUrl}\n alt='logo'\n />\n </div>\n <SignInForm />\n </CardContent>\n </Card>\n </div>\n </MainPageLayout>\n )\n}\n\nexport default Login\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n pageTitle: {\n id: 'cp.pages.dashboard.pageTitle',\n defaultMessage: 'Statistics',\n },\n usersCount: {\n id: 'cp.pages.dashboard.usersCount',\n defaultMessage: 'total amount of registered users',\n },\n mobilesCount: {\n id: 'cp.pages.dashboard.mobilesCount',\n defaultMessage: 'all mobiles recognized',\n },\n cpsCount: {\n id: 'cp.pages.dashboard.cpsCount',\n defaultMessage: 'total CPS at work',\n },\n trainingsCount: {\n id: 'cp.pages.dashboard.trainingsCount',\n defaultMessage: 'all trainings absolved',\n },\n lastMonth: {\n id: 'cp.pages.dashboard.lastMonth',\n defaultMessage: 'Development in the last month.',\n },\n usersCountRecently: {\n id: 'cp.pages.dashboard.usersCountRecently',\n defaultMessage: 'new users registered',\n },\n mobilesCountRecently: {\n id: 'cp.pages.dashboard.mobilesCountRecently',\n defaultMessage: 'recently newly seen mobiles',\n },\n cpsCountRecently: {\n id: 'cp.pages.dashboard.cpsCountRecently',\n defaultMessage: 'new CPS connected',\n },\n})\n","import { createStateHook } from '@restate/core'\nimport { AppStoreProvider } from '../../state/store'\n\nexport const useDashboardState = createStateHook(\n AppStoreProvider,\n state => state.pages.dashboard\n)\n","import React from 'react'\nimport { makeStyles } from '@material-ui/styles'\nimport Typography from '@material-ui/core/Typography'\nimport { Grid } from '@material-ui/core'\nimport { useGoToHook } from '../../services/router/useGoTo.hook'\nimport { AppRoutes } from '../../routes'\n\nconst useStyles = makeStyles({\n Tile: {\n textAlign: 'center',\n margin: '100px 0',\n position: 'relative',\n cursor: 'pointer',\n },\n})\n\ninterface DashboardTileProps {\n amount: number\n description: string\n size: 3 | 4\n children: any\n}\n\nexport const DashboardTile: React.FC<DashboardTileProps> = props => {\n const classes = useStyles()\n const goTo = useGoToHook()\n\n return (\n <Grid\n item\n xs={props.size}\n className={classes.Tile}\n onClick={() => {\n goTo(AppRoutes.Trainees)\n }}\n >\n {props.children}\n <Typography variant='h3'>{props.amount}</Typography>\n <br />\n <Typography variant='h6'>{props.description}</Typography>\n </Grid>\n )\n}\n\nexport default DashboardTile\n","import React from 'react'\nimport { makeStyles } from '@material-ui/styles'\nimport { AppPageLayout } from '../../components/layouts/AppPageLayout'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Dashboard.messages'\nimport { Grid } from '@material-ui/core'\nimport { useDashboardState } from './Dashboard.restate'\nimport PhoneAndroidIcon from '@material-ui/icons/PhoneAndroid'\nimport GroupIcon from '@material-ui/icons/Group'\nimport HealingIcon from '@material-ui/icons/Healing'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport CalendarTodayIcon from '@material-ui/icons/CalendarToday'\nimport { Typography } from '@material-ui/core'\nimport { DashboardTile } from './DashboardTile'\n\nconst useStyles = makeStyles({\n title: {\n width: '100%',\n textAlign: 'center',\n },\n wrapper: {\n width: '100%',\n height: '100%',\n },\n numberBox: {\n textAlign: 'center',\n margin: '100px 0',\n },\n materialIcon: {\n position: 'relative',\n fontSize: '200%',\n },\n})\n\nconst Dashboard = () => {\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n const usersCount = intl.formatMessage(messages.usersCount)\n const mobilesCount = intl.formatMessage(messages.mobilesCount)\n const cpsCount = intl.formatMessage(messages.cpsCount)\n const trainingsCount = intl.formatMessage(messages.trainingsCount)\n const lastMonth = intl.formatMessage(messages.lastMonth)\n const usersCountRecently = intl.formatMessage(messages.usersCountRecently)\n const mobilesCountRecently = intl.formatMessage(messages.mobilesCountRecently)\n const cpsCountRecently = intl.formatMessage(messages.cpsCountRecently)\n\n const dashboard = useDashboardState(s => s.data)\n const classes = useStyles()\n\n return (\n <AppPageLayout title={pageTitle}>\n <div className={classes.wrapper}>\n <Grid container>\n <DashboardTile\n amount={dashboard.usersCount}\n description={usersCount}\n size={3}\n >\n <GroupIcon className={classes.materialIcon} />\n </DashboardTile>\n <DashboardTile\n amount={dashboard.mobilesCount}\n description={mobilesCount}\n size={3}\n >\n <PhoneAndroidIcon className={classes.materialIcon} />\n </DashboardTile>\n <DashboardTile\n amount={dashboard.cpsCount}\n description={cpsCount}\n size={3}\n >\n <FavoriteBorderIcon className={classes.materialIcon} />\n </DashboardTile>\n <DashboardTile\n amount={dashboard.trainingsCount}\n description={trainingsCount}\n size={3}\n >\n <HealingIcon className={classes.materialIcon} />\n </DashboardTile>\n </Grid>\n <Grid container>\n <Grid item xs={12}>\n <Typography variant={'h5'} className={classes.title}>\n {lastMonth}\n <CalendarTodayIcon className={classes.materialIcon} />\n </Typography>\n </Grid>\n </Grid>\n <Grid container>\n <DashboardTile\n amount={dashboard.usersCountRecently}\n description={usersCountRecently}\n size={4}\n >\n <GroupIcon className={classes.materialIcon} />\n </DashboardTile>\n <DashboardTile\n amount={dashboard.mobilesCountRecently}\n description={mobilesCountRecently}\n size={4}\n >\n <PhoneAndroidIcon className={classes.materialIcon} />\n </DashboardTile>\n <DashboardTile\n amount={dashboard.cpsCountRecently}\n description={cpsCountRecently}\n size={4}\n >\n <FavoriteBorderIcon className={classes.materialIcon} />\n </DashboardTile>\n </Grid>\n </div>\n </AppPageLayout>\n )\n}\n\nexport default Dashboard\n","import { createStateHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useTraineesState = createStateHook(\n AppStoreProvider,\n state => state.pages.trainees\n)\n","import React from 'react'\nimport Button from '@material-ui/core/Button'\nimport { makeStyles } from '@material-ui/styles'\nimport { useNextAppState } from '../../state/store'\nimport { routes } from '../../model/ctrl/routes'\nimport { config } from '../../config/config'\nimport axios from 'axios'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Trainees.messages'\n\nconst useClasses = makeStyles({\n root: {\n '& > *': {\n margin: '0 75px',\n },\n },\n})\n\nconst DownloadTraineeData: React.FC = () => {\n const intl = useIntl()\n const mobileButton = intl.formatMessage(messages.mobileButton)\n const cpsButton = intl.formatMessage(messages.cpsButton)\n\n const classes = useClasses()\n const next = useNextAppState(s => s)\n const options = { year: 'numeric', month: 'long', day: 'numeric' }\n const date = new Date().toLocaleDateString([], options)\n\n const downloadMobileAncCpsData = (dataType: string) => {\n let path\n if (dataType === 'mobileCSV') {\n path = routes.export.allMobiles\n } else if (dataType === 'cpsCSV') {\n path = routes.export.allCPS\n }\n\n const fileName = `${date}${dataType}.zip`\n const url = config().api + path\n\n next(state => {\n state.pages.trainees.meta.loading = true\n })\n\n axios({\n url,\n method: 'GET',\n responseType: 'blob',\n }).then((response: any) => {\n const url = window.URL.createObjectURL(new Blob([response.data]))\n const link = document.createElement('a')\n link.href = url\n link.setAttribute('download', fileName)\n document.body.appendChild(link)\n link.click()\n next(state => {\n state.pages.trainees.meta.loading = false\n })\n })\n }\n\n return (\n <div className={classes.root}>\n <Button\n variant='contained'\n color='primary'\n onClick={() => downloadMobileAncCpsData('mobileCSV')}\n >\n {mobileButton}\n </Button>\n <Button\n variant='contained'\n color='secondary'\n onClick={() => downloadMobileAncCpsData('cpsCSV')}\n >\n {cpsButton}\n </Button>\n </div>\n )\n}\n\nexport default DownloadTraineeData\n","import { createStateHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useGlobalSettingsState = createStateHook(\n AppStoreProvider,\n state => state.pages.globalSettings\n)\n","import { Card, CardContent, TextField, Typography } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport React from 'react'\nimport { useNextAppState } from 'state/store'\nimport { theme } from 'theme/theme'\nimport { useGlobalSettingsState } from './CptConfig.restate'\n\nconst useStyles = makeStyles({\n card: {\n marginTop: '1em',\n width: '100%',\n },\n dialogContent: {\n minWidth: '15vw',\n minHeight: '10vh',\n },\n cardHeader: {\n textTransform: 'uppercase',\n width: '100%',\n fontSize: '1.4rem',\n fontWeight: 'bold',\n marginTop: '4rem',\n color: theme.palette.grey.A700,\n paddingLeft: '25px',\n },\n row: {\n width: '100%',\n display: 'grid',\n gap: '1rem',\n gridTemplateColumns: '1fr 1fr',\n },\n cell: {\n marginTop: '1rem',\n marginBottom: '1rem',\n fontFamily: theme.typography.fontFamily,\n },\n select: {\n width: '100%',\n margin: 'auto',\n },\n})\n\ntype InputEvent = React.ChangeEvent<{ value: string }>\n\nexport const CptConfig: React.FC = () => {\n const classes = useStyles()\n\n const feedbackConfig = useGlobalSettingsState(s => s.feedbackConfig)\n const resultConfig = useGlobalSettingsState(s => s.resultConfig)\n const sessionConfig = useGlobalSettingsState(s => s.sessionConfig)\n\n const next = useNextAppState(s => s.pages.globalSettings)\n\n const setAverageCountDepth = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.averageCountDepth = Number.parseInt(e.target.value)\n })\n\n const setAverageCountFreq = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.averageCountFreq = Number.parseInt(e.target.value)\n })\n\n const setAverageCountRecoil = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.averageCountRecoil = Number.parseInt(e.target.value)\n })\n\n const setMaxDepth = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.maxDepth = Number.parseInt(e.target.value)\n })\n\n const setMaxDepthLimit = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.maxDepthLimit = Number.parseInt(e.target.value)\n })\n\n const setMaxFreq = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.maxFreq = Number.parseInt(e.target.value)\n })\n\n const setMaxFreqLimit = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.maxFreqLimit = Number.parseInt(e.target.value)\n })\n\n const setMaxRecoil = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.maxRecoil = Number.parseInt(e.target.value)\n })\n\n const setMinDepth = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.minDepth = Number.parseInt(e.target.value)\n })\n\n const setMinDepthLimit = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.minDepthLimit = Number.parseInt(e.target.value)\n })\n\n const setMinFreq = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.minFreq = Number.parseInt(e.target.value)\n })\n\n const setMinFreqLimit = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.minFreqLimit = Number.parseInt(e.target.value)\n })\n\n const setMinRecoil = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.minRecoil = Number.parseInt(e.target.value)\n })\n\n const setMinRecoilLimit = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.minRecoilLimit = Number.parseInt(e.target.value)\n })\n\n const setNoFlow = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.noFlow = Number.parseInt(e.target.value)\n })\n\n const setVentilationTime = (e: InputEvent) =>\n next(s => {\n s.feedbackConfig.ventilationTime = Number.parseInt(e.target.value)\n })\n\n const setThresholdGood = (e: InputEvent) =>\n next(s => {\n s.resultConfig.simple.thresholdGood = Number.parseInt(e.target.value)\n })\n\n const setThresholdGreat = (e: InputEvent) =>\n next(s => {\n s.resultConfig.simple.thresholdGreat = Number.parseInt(e.target.value)\n })\n\n const setDebounceTime = (e: InputEvent) =>\n next(s => {\n s.sessionConfig.audioFeedbackDebounceTime = Number.parseInt(\n e.target.value\n )\n })\n\n const Cell: React.FC = props => (\n <div className={classes.cell}> {props.children}</div>\n )\n\n const Row: React.FC = props => (\n <div className={classes.row}>{props.children}</div>\n )\n\n const AvgCountDepth = () => (\n <Row>\n <Cell>averageCountDepth</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.averageCountDepth}\n onChange={setAverageCountDepth}\n />\n </Cell>\n </Row>\n )\n\n const AvgCountFreq = () => (\n <Row>\n <Cell>averageCountFreq</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.averageCountFreq}\n onChange={setAverageCountFreq}\n />\n </Cell>\n </Row>\n )\n\n const MaxDepth = () => (\n <Row>\n <Cell>maxDepth</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.maxDepth}\n onChange={setMaxDepth}\n />\n </Cell>\n </Row>\n )\n\n const MaxDepthLimit = () => (\n <Row>\n <Cell>maxDepthLimit</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.maxDepthLimit}\n onChange={setMaxDepthLimit}\n />\n </Cell>\n </Row>\n )\n\n const MaxFreq = () => (\n <Row>\n <Cell>maxFreq</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.maxFreq}\n onChange={setMaxFreq}\n />\n </Cell>\n </Row>\n )\n\n const MaxRecoil = () => (\n <Row>\n <Cell>maxRecoil</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.maxRecoil}\n onChange={setMaxRecoil}\n ></TextField>\n </Cell>\n </Row>\n )\n\n const AvgCountRecoil = () => (\n <Row>\n <Cell>averageCountRecoil</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.averageCountRecoil}\n onChange={setAverageCountRecoil}\n ></TextField>\n </Cell>\n </Row>\n )\n\n const MinDepth = () => (\n <Row>\n <Cell>minDepth</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.minDepth}\n onChange={setMinDepth}\n />\n </Cell>\n </Row>\n )\n\n const MinDepthLimit = () => (\n <Row>\n <Cell>minDepthLimit</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.minDepthLimit}\n onChange={setMinDepthLimit}\n />\n </Cell>\n </Row>\n )\n\n const MinFrequency = () => (\n <Row>\n <Cell>minFreq</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.minFreq}\n onChange={setMinFreq}\n />\n </Cell>\n </Row>\n )\n\n const MinFrequencyLimit = () => (\n <Row>\n <Cell>minFreqLimit</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.minFreqLimit}\n onChange={setMinFreqLimit}\n />\n </Cell>\n </Row>\n )\n\n const MaxFrequencyLimit = () => (\n <Row>\n <Cell>maxFreqLimit</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.maxFreqLimit}\n onChange={setMaxFreqLimit}\n />\n </Cell>\n </Row>\n )\n\n const MinRecoil = () => (\n <Row>\n <Cell>minRecoil</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.minRecoil}\n onChange={setMinRecoil}\n />\n </Cell>\n </Row>\n )\n const MinRecoilLimit = () => (\n <Row>\n <Cell>minRecoilLimit</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.minRecoilLimit}\n onChange={setMinRecoilLimit}\n />\n </Cell>\n </Row>\n )\n const NoFlow = () => (\n <Row>\n <Cell>noFlow</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.noFlow}\n onChange={setNoFlow}\n />\n </Cell>\n </Row>\n )\n const VentilationTime = () => (\n <Row>\n <Cell>ventilationTime</Cell>\n <Cell>\n <TextField\n type='number'\n value={feedbackConfig.ventilationTime}\n onChange={setVentilationTime}\n />\n </Cell>\n </Row>\n )\n const DebounceTime = () => (\n <Row>\n <Cell>audioFeedbackDebounceTime</Cell>\n <Cell>\n <TextField\n type='number'\n value={sessionConfig.audioFeedbackDebounceTime}\n onChange={setDebounceTime}\n />\n </Cell>\n </Row>\n )\n\n return (\n <>\n <Typography className={classes.cardHeader}>Depth</Typography>\n <Card className={classes.card}>\n <CardContent>\n <AvgCountDepth />\n <MinDepthLimit />\n <MinDepth />\n <MaxDepth />\n <MaxDepthLimit />\n </CardContent>\n </Card>\n\n <Typography className={classes.cardHeader}>Frequency</Typography>\n <Card className={classes.card}>\n <CardContent>\n <AvgCountFreq />\n <MinFrequencyLimit />\n <MinFrequency />\n <MaxFreq />\n <MaxFrequencyLimit />\n </CardContent>\n </Card>\n\n <Typography className={classes.cardHeader}>Recoil</Typography>\n <Card className={classes.card}>\n <CardContent>\n <AvgCountRecoil />\n <MinRecoilLimit />\n <MinRecoil />\n <MaxRecoil />\n </CardContent>\n </Card>\n\n <Typography className={classes.cardHeader}>Misc</Typography>\n <Card className={classes.card}>\n <CardContent>\n <NoFlow />\n <VentilationTime />\n <DebounceTime />\n </CardContent>\n </Card>\n\n <Typography className={classes.cardHeader}>\n Global Result Config\n </Typography>\n\n <Card className={classes.card}>\n <CardContent>\n <Row>\n <Cell>Threshold result \"Good\"</Cell>\n <Cell>\n <TextField\n type='number'\n value={resultConfig.simple.thresholdGood}\n onChange={setThresholdGood}\n />\n </Cell>\n </Row>\n <Row>\n <Cell>Threshold result \"Perfect\"</Cell>\n <Cell>\n <TextField\n type='number'\n value={resultConfig.simple.thresholdGreat}\n onChange={setThresholdGreat}\n />\n </Cell>\n </Row>\n </CardContent>\n </Card>\n </>\n )\n}\n\nexport default CptConfig\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useGlobalSettingsState = createStateHook(\n AppStoreProvider,\n state => state.pages.globalSettings\n)\nexport const useNextGlobalSettingsState = () =>\n createNextHook(AppStoreProvider, state => state.pages.globalSettings)\n","import {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControl,\n InputLabel,\n MenuItem,\n Select,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { NotificationType } from 'model/Notification'\nimport React, { useEffect, useState } from 'react'\nimport { useDispatchHook } from 'state/store'\nimport CptConfig from '../../components/Config/CptConfig/CptConfig'\nimport { useGlobalSettingsState } from './GlobalSettings.restate'\n\nconst useStyles = makeStyles({\n card: {\n marginTop: '1em',\n width: '100%',\n },\n dialogContent: {\n minWidth: '15vw',\n minHeight: '10vh',\n },\n select: {\n width: '100%',\n margin: 'auto',\n },\n})\n\nconst GlobalSettingsLoading: React.FC = () => (\n <AppPageLayout title='Global Settings' loading></AppPageLayout>\n)\n\nexport const GlobalSettings: React.FC = () => {\n const cptConfig = useGlobalSettingsState(s => s)\n const cptConfigLoading = cptConfig.meta.loading\n\n const dispatch = useDispatchHook()\n\n const save = () => dispatch({ type: 'Page/GlobalSettings/Config/Save' })\n\n useEffect(() => {\n dispatch({ type: 'Page/GlobalSettings/Config/Load' })\n\n // dispatch is not wrapped inside useCallback an thus cause infinite call of this side effect, too bad.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n if (cptConfigLoading) return <GlobalSettingsLoading />\n\n return (\n <AppPageLayout title='Global Settings'>\n <CptConfig />\n\n <Button\n variant='contained'\n color='secondary'\n style={{ marginTop: '2rem', minWidth: '300px' }}\n onClick={save}\n >\n Save All\n </Button>\n </AppPageLayout>\n )\n}\n\nexport interface NotificationSelectCardProps {\n handleSubmit: (notificationType: NotificationType) => void\n handleClose: () => void\n showClose: boolean\n}\n\nexport const NotificationSelectCard = ({\n handleSubmit,\n showClose,\n handleClose,\n}: NotificationSelectCardProps) => {\n const classes = useStyles()\n\n const notificationDefinitions: Record<NotificationType, string> = {\n 'soc-critical': 'state of charge critical',\n 'soc-low': 'state of charge low',\n 'soh-critical': 'State of health',\n onboarding: 'onboarding',\n training: 'Training',\n 'long-time-no-see': 'long-time-no-see',\n }\n\n const [\n notificationType,\n setNotificationType,\n ] = useState<NotificationType | null>(null)\n const [isOpen, setIsOpen] = useState(true)\n return (\n <Dialog open={isOpen} onClose={() => setIsOpen(false)}>\n <DialogTitle>Test Notifications globally</DialogTitle>\n <DialogContent className={classes.dialogContent}>\n <FormControl className={classes.select}>\n <InputLabel id='notification-select'>\n Select the type of notification to send\n </InputLabel>\n <Select\n value={notificationType}\n onChange={e =>\n setNotificationType(e.target.value as NotificationType)\n }\n labelId='notification-select'\n >\n {Object.entries(notificationDefinitions).map(\n ([key, description]) => (\n <MenuItem value={key}>{description}</MenuItem>\n )\n )}\n </Select>\n </FormControl>\n </DialogContent>\n <DialogActions>\n {showClose && <Button onClick={() => handleClose()}>Close</Button>}\n\n <Button\n variant='contained'\n color='primary'\n disabled={!notificationType}\n onClick={() => notificationType && handleSubmit(notificationType)}\n >\n Send Notification\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nexport default GlobalSettings\n","import React, { useState } from 'react'\nimport { AppPageLayout } from '../../components/layouts/AppPageLayout'\nimport {\n GenericTable,\n GenericTableCellHeader,\n} from '../../components/GenericTable/GenericTable'\nimport { useTraineesState } from './Trainees.restate'\nimport { TableCell, Tooltip, IconButton } from '@material-ui/core'\nimport { FormattedMessage, FormattedDate } from 'react-intl'\nimport DownloadTraineeData from './DownloadTraineeData'\nimport { useIntl } from 'react-intl'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport NotificationsActiveIcon from '@material-ui/icons/NotificationsActive'\nimport { useDispatchHook } from 'state/store'\nimport { NotificationType } from 'model/Notification'\nimport { NotificationSelectCard } from 'pages/GlobalSettings/GlobalSettings'\n\nimport messages from './Trainees.messages'\nimport { TraineeData } from './Trainees.state'\nimport { SelectedUserIds } from 'pages/Institute/SelectedUserIds'\nimport { ConfirmDeletionDialog } from 'components/dialogs/ConfirmDeletionDialog'\n\nexport const Trainees = () => {\n const intl = useIntl()\n const title = intl.formatMessage(messages.title)\n const tableName = intl.formatMessage(messages.tableName)\n const tableEmail = intl.formatMessage(messages.tableEmail)\n const tableCreated = intl.formatMessage(messages.tableCreated)\n const tableSelected = intl.formatMessage(messages.tableSelected)\n const singleTrainee = intl.formatMessage(messages.singleTrainee)\n const multipleTrainees = intl.formatMessage(messages.multipleTrainees)\n const deleteLabel = intl.formatMessage(messages.deleteLabel)\n\n const dispatch = useDispatchHook()\n\n const [selectedIdsToDelete, setSelectedIdsToDelete] = useState<\n SelectedUserIds\n >(null)\n const [selectedIdsToNotify, setSelectedIdsToNotify] = useState<\n SelectedUserIds\n >(null)\n\n const cellHeaders = (\n name: string,\n email: string,\n created: string\n ): GenericTableCellHeader[] => {\n return [\n { id: 'displayName', numeric: false, disablePadding: false, label: name },\n { id: 'email', numeric: false, disablePadding: false, label: email },\n {\n id: 'createdAt',\n numeric: false,\n disablePadding: false,\n label: created,\n },\n ]\n }\n\n const trainees = useTraineesState(s => s.data)\n\n const search = (searchTerm: string) => {\n const searchExp = RegExp(searchTerm, 'i')\n return (entry: TraineeData) => {\n return (\n searchExp.test(entry.displayName as string) ||\n searchExp.test(entry.email)\n )\n }\n }\n\n const getTraineeRoles = (id: string) => {\n return trainees.find(t => t._id === id)?.roles ?? []\n }\n\n const deleteTrainees = (ids: string[]) => {\n dispatch({ type: 'Pages/Trainees/Delete', payload: { ids } })\n }\n\n return (\n <AppPageLayout title={title}>\n <GenericTable\n rows={trainees}\n headers={cellHeaders(tableName, tableEmail, tableCreated)}\n singleSelect={true}\n search={search as any}\n selectedItemsMessage={({ count }) => (\n <FormattedMessage\n id='trainees_count'\n defaultMessage={`{count, number} {count, plural, one { ${singleTrainee} } other { ${multipleTrainees} }} ${tableSelected}`}\n values={{ count }}\n />\n )}\n rowRender={({ row }: { row: TraineeData }) => (\n <>\n <TableCell>{row.displayName}</TableCell>\n <TableCell>{row.email}</TableCell>\n <TableCell>\n {\n <FormattedDate\n value={row.createdAt}\n year='numeric'\n month='2-digit'\n day='2-digit'\n />\n }\n </TableCell>\n </>\n )}\n tools={({ selected, setSelected }) => (\n <div style={{ width: '6em' }}>\n <Tooltip title={deleteLabel}>\n <IconButton\n style={{ display: 'inline-block' }}\n aria-label={deleteLabel}\n onClick={() => {\n setSelectedIdsToDelete({\n selectedIds: selected,\n clearSelection: () => setSelected([]),\n })\n }}\n >\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n\n <Tooltip title={'notify user'}>\n <IconButton\n style={{ display: 'inline-block' }}\n aria-label={'notify user'}\n onClick={() => {\n setSelectedIdsToNotify({\n selectedIds: selected,\n clearSelection: () => setSelected([]),\n })\n }}\n >\n <NotificationsActiveIcon />\n </IconButton>\n </Tooltip>\n </div>\n )}\n ></GenericTable>\n\n <ConfirmDeletionDialog\n open={\n !!selectedIdsToDelete && selectedIdsToDelete?.selectedIds.length === 1\n }\n userRoles={getTraineeRoles(selectedIdsToDelete?.selectedIds[0] ?? '')}\n onPositiveButtonClick={() => {\n deleteTrainees(selectedIdsToDelete?.selectedIds ?? [])\n selectedIdsToDelete?.clearSelection()\n setSelectedIdsToDelete(null)\n }}\n onNegativeButtonClick={() => {\n selectedIdsToDelete?.clearSelection()\n setSelectedIdsToDelete(null)\n }}\n />\n\n {selectedIdsToNotify && selectedIdsToNotify.selectedIds.length > 0 && (\n <NotificationSelectCard\n handleSubmit={(notificationType: NotificationType) => {\n dispatch({\n type: 'Pages/Trainees/Notify',\n payload: {\n ids: selectedIdsToNotify.selectedIds ?? [],\n notificationType,\n },\n })\n selectedIdsToNotify?.clearSelection()\n setSelectedIdsToNotify(null)\n }}\n showClose={true}\n handleClose={() => {\n selectedIdsToNotify?.clearSelection()\n setSelectedIdsToNotify(null)\n }}\n />\n )}\n <DownloadTraineeData />\n </AppPageLayout>\n )\n}\n\nexport default Trainees\n","import { useAppState, useNextAppState, AppStoreProvider } from 'state/store'\nimport { ActionFactoryProps, createActionsHook } from '@restate/core'\nimport { RegisterState } from './Register.state'\nimport { AppMessages } from 'state/appMessages'\nimport { RegisterMessage, RegisterService } from './Register.page-service'\nimport { config } from 'config/config'\nimport { isEmail } from '../../utils/isEmail'\nimport { FormEvent } from 'react'\n\nexport const useRegisterState = () => useAppState(state => state.pages.register)\nexport const useNextRegisterState = () =>\n useNextAppState(state => state.pages.register)\n\nconst RegisterActions = ({\n next,\n dispatch,\n state,\n}: ActionFactoryProps<RegisterState, AppMessages>) => ({\n setPassword(password: string) {\n next(loginState => (loginState.password = password))\n },\n setEmail(email: string) {\n next(loginState => (loginState.email = email))\n },\n setfirstName(firstName: string) {\n next(registerState => (registerState.firstName = firstName))\n },\n setlastName(lastName: string) {\n next(registerState => (registerState.lastName = lastName))\n },\n setTermsOfUseAccepted(accepted: boolean) {\n next(registerState => (registerState.termsOfUseAccepted = accepted))\n },\n\n register(event: FormEvent<HTMLFormElement>) {\n event.preventDefault()\n\n const password = state().password\n const email = state().email\n const termsOfUseAccepted = state().termsOfUseAccepted\n const error = state().error\n\n const firstName = state().firstName\n const lastName = state().lastName\n\n const isValid =\n password.length >= config().passwordMinLen &&\n isEmail(email) &&\n termsOfUseAccepted &&\n error === null\n\n if (!isValid) {\n return\n }\n\n const registerMessage: RegisterMessage = {\n type: RegisterService.Register,\n payload: {\n email,\n password,\n firstName,\n lastName,\n },\n }\n dispatch(registerMessage)\n },\n})\n\nexport const useRegisterActions = createActionsHook(\n AppStoreProvider,\n state => state.pages.register,\n RegisterActions\n)\n","import React, { useState } from 'react'\nimport { theme } from 'theme/theme'\nimport { makeStyles } from '@material-ui/styles'\nimport {\n Grid,\n FormControl,\n InputAdornment,\n Input,\n Button,\n Checkbox,\n Typography,\n} from '@material-ui/core'\nimport { useRegisterActions, useRegisterState } from './Register.restate'\nimport InputLabel from '@material-ui/core/InputLabel'\nimport EmailIcon from '@material-ui/icons/Email'\nimport PersonIcon from '@material-ui/icons/Person'\nimport LockIcon from '@material-ui/icons/Lock'\nimport { AppRoutes } from 'routes'\nimport { Busy } from '../Login/LoginForm'\nimport { useIntl } from 'react-intl'\n\nimport messages from './Register.messages'\nimport { config } from 'config/config'\nimport { useAppState } from '../../state/store'\nimport { useRTL } from 'utils/useRTL'\n\nconst useClasses = makeStyles({\n formItem: {\n margin: '10px 10px 0 10px',\n },\n\n submitButton: {\n marginTop: 10,\n },\n\n innerContainer: {\n height: 'auto',\n [theme.breakpoints.down('xs')]: {\n height: 'auto',\n },\n },\n\n forgotPassword: {\n marginLeft: 10,\n marginTop: 10,\n marginBottom: theme.spacing() * 2,\n color: theme.palette.primary.main,\n cursor: 'pointer',\n },\n\n error: {\n ...theme.typography.h6,\n color: theme.palette.error.dark,\n padding: theme.spacing(),\n fontSize: '1rem',\n backgroundColor: theme.palette.grey[50],\n border: '1px solid ' + theme.palette.primary.dark,\n },\n})\n\nexport const RegisterForm = () => {\n const classes = useClasses()\n\n const intl = useIntl()\n const firstnameField = intl.formatMessage(messages.firstnameField)\n const lastnameField = intl.formatMessage(messages.lastnameField)\n const emailField = intl.formatMessage(messages.emailField)\n const passwordField = intl.formatMessage(messages.passwordField)\n const acceptTermsOfUse = intl.formatMessage(messages.acceptTermsOfUse)\n const create = intl.formatMessage(messages.create)\n const newToShortError = intl.formatMessage(messages.newToShortError)\n const isRTL = useRTL()\n\n const {\n error,\n email,\n password,\n firstName,\n lastName,\n termsOfUseAccepted,\n showProgress,\n } = useRegisterState()\n const {\n setPassword,\n setEmail,\n register,\n setfirstName,\n setlastName,\n setTermsOfUseAccepted,\n } = useRegisterActions()\n const [errorPassword, setErrorPassword] = useState(false)\n const [errorPasswordMessage, setErrorPasswordMessage] = useState('')\n const embeddedMode = useAppState(state => state.routerExtension.embeddedMode)\n\n const isValid =\n password !== '' && email !== '' && termsOfUseAccepted && !errorPassword\n\n function validatePasswordInput() {\n setErrorPassword(false)\n setErrorPasswordMessage('')\n\n if (password.length < config().passwordMinLen) {\n setErrorPassword(true)\n setErrorPasswordMessage(newToShortError)\n }\n }\n\n if (showProgress) return <Busy />\n\n return (\n <form onSubmit={register}>\n {error ? <div className={classes.error}>{error}</div> : null}\n <Grid\n direction='column'\n container={true}\n className={classes.innerContainer}\n >\n <FormControl className={classes.formItem}>\n <InputLabel htmlFor='firstName'>{firstnameField}</InputLabel>\n <Input\n id='firstName'\n type='text'\n value={firstName}\n onChange={event => setfirstName(event.target.value)}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <PersonIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <PersonIcon color='action' />\n </InputAdornment>\n )\n }\n />\n </FormControl>\n <FormControl className={classes.formItem}>\n <InputLabel htmlFor='lastName'>{lastnameField}</InputLabel>\n <Input\n id='lastName'\n type='text'\n value={lastName}\n onChange={event => setlastName(event.target.value)}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <PersonIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <PersonIcon color='action' />\n </InputAdornment>\n )\n }\n />\n </FormControl>\n <FormControl className={classes.formItem}>\n <InputLabel htmlFor='email'>{emailField}*</InputLabel>\n <Input\n id='email'\n type='email'\n value={email}\n required={true}\n autoComplete='email'\n onChange={event => setEmail(event.target.value)}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <EmailIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <EmailIcon color='action' />\n </InputAdornment>\n )\n }\n />\n </FormControl>\n <FormControl className={classes.formItem}>\n <InputLabel htmlFor='adornment-password'>{passwordField}*</InputLabel>\n <Input\n id='adornment-password'\n type='password'\n autoComplete='password'\n value={password}\n required={true}\n error={errorPassword}\n onChange={event => {\n setPassword(event.target.value)\n if (errorPassword) {\n validatePasswordInput()\n }\n }}\n onBlur={validatePasswordInput}\n endAdornment={\n !isRTL && (\n <InputAdornment position='end'>\n <LockIcon color='action' />\n </InputAdornment>\n )\n }\n startAdornment={\n isRTL && (\n <InputAdornment position='end'>\n <LockIcon color='action' />\n </InputAdornment>\n )\n }\n />\n <Typography style={{ fontSize: '75%', color: 'red' }}>\n {errorPasswordMessage}\n </Typography>\n </FormControl>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n gap: theme.spacing() * 3,\n }}\n >\n {!embeddedMode && (\n <FormControl\n className={classes.formItem}\n style={{ marginTop: '30px' }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <a\n style={{ textDecoration: 'none' }}\n href={AppRoutes.LoginTermsOfUse}\n >\n {acceptTermsOfUse}*\n </a>\n <Checkbox\n style={{\n display: 'inline-block',\n float: 'right',\n padding: '0',\n }}\n checked={termsOfUseAccepted}\n onChange={() => setTermsOfUseAccepted(!termsOfUseAccepted)}\n />\n </div>\n </FormControl>\n )}\n\n <Button\n variant='contained'\n size='large'\n color='primary'\n type='submit'\n className={classes.formItem + ' ' + classes.submitButton}\n disabled={!isValid}\n >\n {create}\n </Button>\n </div>\n </Grid>\n </form>\n )\n}\n","import React from 'react'\nimport { Card, CardContent } from '@material-ui/core'\nimport { Images } from 'theme/Images'\nimport { MainPageLayout } from 'components/layouts/MainPageLayout'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport { center } from 'styles/styles'\nimport { makeStyles } from '@material-ui/styles'\nimport { RegisterForm } from './RegisterForm'\n\nconst useStyles = makeStyles({\n center: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n flexGrow: 1,\n backgroundColor: Colors.background[0],\n },\n\n card: {\n minWidth: 400,\n minHeight: 516,\n borderTop: `4px solid ${Colors.primary[3]}`,\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n width: '100%',\n height: '100%',\n borderRadius: 0,\n },\n borderRadius: 8,\n },\n\n titleBg: {\n position: 'relative',\n maxWidth: '250px',\n top: '50px',\n borderRadius: 8,\n },\n\n logo: {\n ...center,\n marginBottom: theme.spacing() * 3,\n marginTop: theme.spacing() * 3,\n },\n\n title: {\n fontSize: '1.4rem',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n\n logoImg: {},\n})\n\nexport const Register = () => {\n const { center, card, logo, logoImg } = useStyles()\n\n return (\n <MainPageLayout title={'Title'} showTranslationSwitch>\n <div className={center}>\n <Card className={card} elevation={3}>\n <CardContent>\n <div className={logo}>\n <img\n className={logoImg}\n height='150'\n src={Images.celebration}\n alt='logo'\n />\n </div>\n <RegisterForm />\n </CardContent>\n </Card>\n </div>\n </MainPageLayout>\n )\n}\n\nexport default Register\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n validationText: {\n id: 'cp.pages.email.validation.text',\n defaultMessage:\n 'Thank you for verifying you email. We will use it to keep your account secure and keep you up to date if you wish.',\n },\n loginButton: {\n id: 'cp.pages.email.validation.button',\n defaultMessage: 'Go to Login',\n },\n})\n","import React, { useEffect } from 'react'\nimport { Typography, Button } from '@material-ui/core'\nimport { useIntl } from 'react-intl'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { AppRoutes } from 'routes'\nimport { makeStyles } from '@material-ui/styles'\nimport { config } from 'config/config'\nimport {\n ImageCard,\n ImageCardActions,\n ImageCardContent,\n} from 'components/ImageCard/ImageCard'\nimport axios from 'axios'\nimport { Images } from 'theme/Images'\n\nimport messages from './Emailvalidation.messages'\nimport { useTitle } from 'components/layouts/useTitle.hook'\n\nconst useStyles = makeStyles({\n wrapper: {\n height: '100vh',\n display: 'grid',\n placeContent: 'center',\n },\n})\n\nexport const EmailValidation = (props: any) => {\n const goTo = useGoToHook()\n const classes = useStyles()\n const intl = useIntl()\n\n useTitle('Corpatch')\n\n const validationText = intl.formatMessage(messages.validationText)\n const loginButton = intl.formatMessage(messages.loginButton)\n\n const { api } = config()\n const id = props.match.params.id\n\n useEffect(() => {\n axios\n .get(api + '/api/auth/email/validate/' + id)\n .then(() => {\n console.log('SUCCESS VALDIATION')\n })\n .catch(() => {\n console.error('FAILURE VALIDATION')\n })\n }, [id, api])\n\n return (\n <div className={classes.wrapper}>\n <ImageCard imgUrl={Images.emailValidation}>\n <ImageCardContent>\n <Typography>{validationText}</Typography>\n </ImageCardContent>\n <ImageCardActions>\n <Button\n variant='contained'\n color='secondary'\n onClick={() => goTo(AppRoutes.Login)}\n >\n {loginButton}\n </Button>\n </ImageCardActions>\n </ImageCard>\n </div>\n )\n}\n\nexport default EmailValidation\n","import { defineMessages } from 'react-intl'\n\nexport default defineMessages({\n title: {\n id: 'cp.pages.singleTraining.title',\n defaultMessage: 'Your trainings',\n },\n tableName: {\n id: 'cp.pages.singleTraining.table.name',\n defaultMessage: 'Full Name',\n },\n tableCreated: {\n id: 'cp.pages.singleTraining.table.created',\n defaultMessage: 'Created',\n },\n singleTraining: {\n id: 'cp.pages.singleTraining.singleTraining',\n defaultMessage: 'training',\n },\n multipleTrainings: {\n id: 'cp.pages.singleTraining.multipleTrainings',\n defaultMessage: 'trainings',\n },\n tableSelected: {\n id: 'cp.pages.singleTraining.table.selected',\n defaultMessage: 'selected',\n },\n tableRowDate: {\n id: 'cp.components.singleTrainingsTable.tableRowDate',\n defaultMessage: 'Date',\n },\n tableRowOrigin: {\n id: 'cp.components.singleTrainingsTable.tableRowOrigin',\n defaultMessage: 'Origin',\n },\n tableRowFlow: {\n id: 'cp.components.singleTrainingsTable.tableRowFlow',\n defaultMessage: 'Flow',\n },\n tableRowDepth: {\n id: 'cp.components.singleTrainingsTable.tableRowDepth',\n defaultMessage: 'Depth',\n },\n tableRowRecoil: {\n id: 'cp.components.singleTrainingsTable.tableRowRecoil',\n defaultMessage: 'Recoil',\n },\n tableRowFrequency: {\n id: 'cp.components.singleTrainingsTable.tableRowFrequency',\n defaultMessage: 'Frequency',\n },\n tableShareTrainingTooltip: {\n id: 'cp.components.singleTrainingsTable.tableShareTrainingTooltip',\n defaultMessage: 'Share training',\n },\n shareDialogTitle: {\n id: 'cp.components.singleTrainingsTable.shareDialogTitle',\n defaultMessage: 'Share training',\n },\n shareDialogContent: {\n id: 'cp.components.singleTrainingsTable.shareDialogContent',\n defaultMessage:\n 'Select the institute you want to share this training with:',\n },\n shareDialogTooltip: {\n id: 'cp.components.singleTrainingsTable.shareDialogTooltip',\n defaultMessage: 'Share training',\n },\n sharedDialogTooltip: {\n id: 'cp.components.singleTrainingsTable.sharedDialogTooltip',\n defaultMessage: 'Shared at: ',\n },\n shareDialogCancelButton: {\n id: 'cp.components.singleTrainingsTable.sharedDialogCancelButton',\n defaultMessage: 'Cancel',\n },\n shareDialogShareButton: {\n id: 'cp.components.singleTrainingsTable.sharedDialogShareButton',\n defaultMessage: 'Share',\n },\n})\n","import { createStateHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useSingleTrainingsState = createStateHook(\n AppStoreProvider,\n state => state.pages.singleTrainings\n)\n","import {\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n List,\n ListItem,\n ListItemIcon,\n ListItemText,\n TableCell,\n Tooltip,\n Typography,\n} from '@material-ui/core'\nimport ShareIcon from '@material-ui/icons/Share'\nimport { CircularTrainingProgress } from 'components/CircularTrainingProgress/CircularTrainingProgress'\nimport {\n GenericTable,\n GenericTableCellHeader,\n GenericTableData,\n} from 'components/GenericTable/GenericTable'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport React from 'react'\nimport { FormattedDate, FormattedMessage, useIntl } from 'react-intl'\nimport { useAppState, useDispatchHook, useNextAppState } from 'state/store'\nimport { Colors } from 'theme/colors'\nimport { theme } from 'theme/theme'\nimport messages from './SingleTrainings.messages'\nimport { SingleTrainingView } from './SingleTrainings.page-service'\nimport { useSingleTrainingsState } from './SingleTrainings.restate'\n\nfunction ShareDialog({\n open = false,\n onCancel = () => {},\n onShare = () => {},\n}) {\n const intl = useIntl()\n const selectedTraineeSharingObject = useAppState(\n // TODO: typings AND wording of this - otherwise it's not maintainable\n s => s.pages.singleTrainings.share.selectedTraineeSharingObject\n )\n const selectedTrainingId = useAppState(\n s => s.pages.singleTrainings.share.selectedTrainingId\n )\n\n const next = useNextAppState(s => s.pages.singleTrainings.share)\n\n const traineeSharingObjects = useAppState(\n s => s.pages.singleTrainings.traineeSharingObjects\n )\n\n const shareButtonDisabled = useAppState(\n s => s.pages.singleTrainings.share.selectedTraineeSharingObject.length === 0\n )\n\n function handleToggle(sharingObject: any) {\n if (trainingHasBeenSharedAlready(sharingObject)) {\n return\n }\n\n next(share => {\n if (\n share.selectedTraineeSharingObject[0] === sharingObject.sharingObjectId\n ) {\n share.selectedTraineeSharingObject = []\n } else {\n share.selectedTraineeSharingObject = [sharingObject.sharingObjectId]\n }\n })\n }\n\n function trainingHasBeenSharedAlready(sharingObject: any) {\n return sharingObject.trainings.some(\n (training: any) => training.trainingId === selectedTrainingId\n )\n }\n\n function sharingIsDisabled(traineeSharingObject: any) {\n return (\n traineeSharingObject.endDate !== null ||\n traineeSharingObject.sharingObject.meta.deletedAt !== null\n )\n }\n\n function trainingSharedDate(traineeSharingObject: any) {\n const training = traineeSharingObject.trainings.find(\n (training: any) => training.trainingId === selectedTrainingId\n )\n\n if (training) {\n return intl.formatDate(training.sharedAt)\n }\n return ''\n }\n\n const visibleTraineeSharingObjects = traineeSharingObjects\n .filter(\n (sharingObject: any) =>\n !sharingIsDisabled(sharingObject) ||\n trainingHasBeenSharedAlready(sharingObject)\n )\n .sort((a: any, b: any) => {\n if (trainingHasBeenSharedAlready(a)) {\n return 1\n }\n if (trainingHasBeenSharedAlready(b)) {\n return -1\n }\n return a.institute.name.localeCompare(b.institute.name)\n })\n\n return (\n <Dialog open={open}>\n <DialogTitle>{intl.formatMessage(messages.shareDialogTitle)}</DialogTitle>\n <DialogContent>\n <Typography>\n {intl.formatMessage(messages.shareDialogContent)}\n </Typography>\n </DialogContent>\n <List>\n {visibleTraineeSharingObjects.map(traineeSharingObject => (\n <ListItem\n key={traineeSharingObject._id}\n onClick={() => handleToggle(traineeSharingObject)}\n >\n <ListItemIcon>\n <Checkbox\n edge='start'\n checked={\n selectedTraineeSharingObject.some(\n value => value === traineeSharingObject.sharingObjectId\n ) || trainingHasBeenSharedAlready(traineeSharingObject)\n }\n disabled={trainingHasBeenSharedAlready(traineeSharingObject)}\n tabIndex={-1}\n disableRipple\n />\n </ListItemIcon>\n <Tooltip\n title={\n trainingHasBeenSharedAlready(traineeSharingObject)\n ? intl.formatMessage(messages.sharedDialogTooltip) +\n trainingSharedDate(traineeSharingObject)\n : intl.formatMessage(messages.shareDialogTooltip)\n }\n >\n <ListItemText\n primary={traineeSharingObject.institute.name}\n secondary={traineeSharingObject.sharingObject.name}\n />\n </Tooltip>\n </ListItem>\n ))}\n </List>\n <DialogActions>\n <Button onClick={onCancel} color='secondary'>\n {intl.formatMessage(messages.shareDialogCancelButton)}\n </Button>\n <Button\n onClick={() => onShare()}\n color='primary'\n disabled={shareButtonDisabled}\n >\n {intl.formatMessage(messages.shareDialogShareButton)}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\ntype SingleTrainingsTableData = SingleTrainingView & GenericTableData\n\nconst SingleTrainings = () => {\n const intl = useIntl()\n const dispatch = useDispatchHook()\n const next = useNextAppState(s => s)\n const [shareDialogOpen, setShareDialogOpen] = React.useState(false)\n const traineeSharingObjects = useAppState(\n s => s.pages.singleTrainings.traineeSharingObjects\n )\n\n const title = intl.formatMessage(messages.title)\n const singleTraining = intl.formatMessage(messages.singleTraining)\n const multipleTrainings = intl.formatMessage(messages.multipleTrainings)\n const tableSelected = intl.formatMessage(messages.tableSelected)\n\n const tableRowDate = intl.formatMessage(messages.tableRowDate)\n const tableRowOrigin = intl.formatMessage(messages.tableRowOrigin)\n const tableRowFlow = intl.formatMessage(messages.tableRowFlow)\n const tableRowDepth = intl.formatMessage(messages.tableRowDepth)\n const tableRowRecoil = intl.formatMessage(messages.tableRowRecoil)\n const tableRowFrequency = intl.formatMessage(messages.tableRowFrequency)\n const tableShare = intl.formatMessage(messages.shareDialogShareButton)\n const tableShareTrainingTooltip = intl.formatMessage(\n messages.tableShareTrainingTooltip\n )\n\n const cellHeaders = (): GenericTableCellHeader[] => {\n return [\n {\n id: 'date',\n numeric: false,\n disablePadding: false,\n label: tableRowDate,\n },\n {\n id: 'origin',\n numeric: false,\n disablePadding: false,\n label: tableRowOrigin,\n },\n {\n id: 'flow',\n numeric: false,\n disablePadding: false,\n label: tableRowFlow,\n },\n {\n id: 'depth',\n numeric: false,\n disablePadding: false,\n label: tableRowDepth,\n },\n {\n id: 'recoil',\n numeric: false,\n disablePadding: false,\n label: tableRowRecoil,\n },\n {\n id: 'frequency',\n numeric: false,\n disablePadding: false,\n label: tableRowFrequency,\n },\n {\n id: 'dummy',\n numeric: false,\n disablePadding: false,\n label: tableShare,\n },\n ]\n }\n\n const rows = useSingleTrainingsState(s =>\n s.singleTrainings.map(training => {\n return {\n id: training._id,\n selected: false,\n isSelectionEnabled: true,\n ...training,\n }\n })\n )\n\n const search = (searchTerm: string) => {\n const searchExp = RegExp(searchTerm, 'i')\n return (entry: SingleTrainingView) => {\n return (\n searchExp.test(entry.sessionType as string) ||\n searchExp.test(entry.origin as string) ||\n searchExp.test(entry.sessionDuration.toString() as string) ||\n searchExp.test(entry.sessionType as string) ||\n searchExp.test(entry.frequency.toString() as string)\n )\n }\n }\n\n function openSharedDialog(row: SingleTrainingsTableData) {\n next(s => {\n s.pages.singleTrainings.share.selectedTrainingId = row.id\n s.pages.singleTrainings.share.selectedTraineeSharingObject = []\n })\n setShareDialogOpen(true)\n }\n\n function handleShare() {\n setShareDialogOpen(false)\n dispatch({ type: 'Page/SingleTraining/Share' })\n }\n\n function isShared(row: SingleTrainingsTableData) {\n return traineeSharingObjects.some(sharingObject =>\n sharingObject.trainings.some(training => training.trainingId === row._id)\n )\n }\n\n function shareButtonColor(row: SingleTrainingsTableData) {\n return isShared(row) ? Colors.supportingCyan[0] : Colors.neutrals[3]\n }\n\n return (\n <AppPageLayout title={title}>\n <GenericTable\n rows={rows}\n headers={cellHeaders()}\n singleSelect={true}\n search={search as any}\n checkboxEnabled={false}\n checkboxVisible={false}\n selectedItemsMessage={({ count }) => (\n <FormattedMessage\n id='trainees_count'\n defaultMessage={`{count, number} {count, plural, one { ${singleTraining} } other { ${multipleTrainings} }} ${tableSelected}`}\n values={{ count }}\n />\n )}\n rowRender={({ row }: { row: SingleTrainingsTableData }) => (\n <>\n <TableCell>\n {\n <FormattedDate\n value={row.date}\n year='numeric'\n month='2-digit'\n day='2-digit'\n />\n }\n </TableCell>\n <TableCell>{row.origin}</TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n styles={{ margin: theme.spacing(1) }}\n value={row.result.flowPercent}\n color={Colors.primary[3]}\n />\n </TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n styles={{ margin: theme.spacing(1) }}\n value={row.result.cprCorrectDepthPercent}\n color={Colors.vivid[3]}\n />\n </TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n styles={{ margin: theme.spacing(1) }}\n value={row.result.cprCorrectRecoilPercent}\n color={Colors.supportingLime[3]}\n />\n </TableCell>\n <TableCell>\n <CircularTrainingProgress\n size={50}\n fontSize={12}\n showLabel={false}\n thickness={4}\n styles={{ margin: theme.spacing(1) }}\n value={row.result.cprCorrectFrequencyPercent}\n color={Colors.supportingCyan[3]}\n />\n </TableCell>\n <TableCell>\n <Tooltip title={tableShareTrainingTooltip}>\n <Button\n style={{ color: shareButtonColor(row) }}\n onClick={() => {\n openSharedDialog(row)\n }}\n >\n <ShareIcon />\n </Button>\n </Tooltip>\n </TableCell>\n </>\n )}\n ></GenericTable>\n <ShareDialog\n open={shareDialogOpen}\n onCancel={() => setShareDialogOpen(false)}\n onShare={handleShare}\n />\n </AppPageLayout>\n )\n}\n\nexport default SingleTrainings\n","import {\n Button,\n Card,\n CardContent,\n CircularProgress,\n Typography,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/styles'\nimport React, { useEffect, useState } from 'react'\nimport { useIntl } from 'react-intl'\nimport { useHistory, useParams } from 'react-router-dom'\nimport {\n ImageCard,\n ImageCardContent,\n ImageCardActions,\n} from '../../components/ImageCard/ImageCard'\nimport { AppRoutes } from '../../routes'\nimport {\n LoginService,\n LS_VERIFICATION_KEY,\n} from '../../services/login/login.service'\nimport { useAppState, useDispatchHook } from '../../state/store'\nimport { Images } from '../../theme/Images'\n\nimport messages from './ValidateLogin.messages'\n\nconst useStyles = makeStyles({\n root: {\n display: 'grid',\n placeItems: 'center',\n height: '100%',\n },\n})\n\nfunction ValidateLogin() {\n const classes = useStyles()\n const intl = useIntl()\n\n const validationTitle = intl.formatMessage(messages.validationTitle)\n const validationContent = intl.formatMessage(messages.validationContent)\n const validationButton = intl.formatMessage(messages.validationButton)\n const successTitle = intl.formatMessage(messages.successTitle)\n const successContent = intl.formatMessage(messages.successContent)\n const errorTitle = intl.formatMessage(messages.errorTitle)\n const errorContent = intl.formatMessage(messages.errorContent)\n\n const [verificationToken] = useState(() =>\n localStorage.getItem(LS_VERIFICATION_KEY)\n )\n\n const { token } = useParams<{ token: string }>()\n const dispatch = useDispatchHook()\n const history = useHistory()\n\n const isNetworkInitialized = useAppState(s => s.network.online)\n const isLoggedInAllready = useAppState(s => s.session.token)\n\n useEffect(() => {\n if (isNetworkInitialized && token && verificationToken) {\n dispatch({\n type: LoginService.LoginValidate,\n payload: { validationToken: token, verificationToken },\n })\n }\n }, [token, isNetworkInitialized, dispatch, verificationToken])\n\n if (Boolean(isLoggedInAllready)) {\n history.push(AppRoutes.Home)\n }\n\n if (token && verificationToken) {\n return (\n <div className={classes.root}>\n <Card>\n <CardContent>\n <Typography variant='h5'>{successTitle}</Typography>\n\n <Typography>{successContent}</Typography>\n\n <div className={classes.root}>\n <CircularProgress />\n </div>\n </CardContent>\n </Card>\n </div>\n )\n }\n\n if (token && !verificationToken) {\n return (\n <div className={classes.root}>\n <ImageCard imgUrl={Images.bugFix}>\n <ImageCardContent>\n <Typography variant='h5'>{errorTitle}</Typography>\n\n <Typography>{errorContent}</Typography>\n </ImageCardContent>\n\n <ImageCardActions>\n <Button onClick={() => history.push(AppRoutes.Login)}>\n {validationButton}\n </Button>\n </ImageCardActions>\n </ImageCard>\n </div>\n )\n }\n\n return (\n <div className={classes.root}>\n <ImageCard imgUrl={Images.mail}>\n <ImageCardContent>\n <Typography variant='h5'>{validationTitle}</Typography>\n\n <Typography>{validationContent}</Typography>\n </ImageCardContent>\n\n <ImageCardActions>\n <Button onClick={() => history.push(AppRoutes.Login)}>\n {validationButton}\n </Button>\n </ImageCardActions>\n </ImageCard>\n </div>\n )\n}\n\nexport default ValidateLogin\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useSharingObjectsState = createStateHook(\n AppStoreProvider,\n state => state.pages.sharingObjects\n)\nexport const useNextSharingObjectsState = () =>\n createNextHook(AppStoreProvider, state => state.pages.sharingObjects)\n","import { makeStyles } from '@material-ui/styles'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport React from 'react'\nimport { Images } from 'theme/Images'\nimport { useSharingObjectsState } from './SharingObject.restate'\nimport { theme } from 'theme/theme'\nimport { Colors } from 'theme/colors'\nimport Card from '@material-ui/core/Card'\nimport CardHeader from '@material-ui/core/CardHeader'\nimport CardContent from '@material-ui/core/CardContent'\nimport FormGroup from '@material-ui/core/FormGroup'\nimport TextField from '@material-ui/core/TextField'\nimport Button from '@material-ui/core/Button'\nimport { useAppState, useDispatchHook, useNextAppState } from 'state/store'\nimport {\n FormControl,\n InputLabel,\n MenuItem,\n Select,\n Typography,\n} from '@material-ui/core'\nimport { config } from 'config/config'\nimport { YesNoDialog } from 'components/YesNoDialog/GenericConfirmDeletionDialog'\nimport { USERROLES } from 'model/UserRole'\nimport messages from './SharingObject.messages'\nimport { useIntl } from 'react-intl'\n\nconst SharingObjectsLoading = () => {\n const intl = useIntl()\n return (\n <AppPageLayout\n title={intl.formatMessage(messages.pageTitle)}\n loading={true}\n ></AppPageLayout>\n )\n}\n\nconst SharingObjectsNotFound = () => {\n const intl = useIntl()\n\n return (\n <PageNotFound\n title={intl.formatMessage(messages.pageNotFoundTitle)}\n message={intl.formatMessage(messages.pageNotFoundMessage)}\n img={Images.detailedExamination}\n />\n )\n}\n\nexport function SharingObject() {\n const { loading, notFound } = useSharingObjectsState(s => s.meta)\n const intl = useIntl()\n if (loading) return <SharingObjectsLoading />\n if (notFound) return <SharingObjectsNotFound />\n\n return (\n <AppPageLayout showBackButton title={intl.formatMessage(messages.title)}>\n <SharingObjectForm />\n </AppPageLayout>\n )\n}\n\nconst useStyles = makeStyles({\n card: {\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n width: '100%',\n },\n\n field: {\n marginRight: theme.spacing(),\n marginTop: theme.spacing(),\n [theme.breakpoints.down('xs')]: {\n marginRight: 0,\n width: '100%',\n },\n },\n\n button: {\n margin: theme.spacing(1),\n },\n\n secondaryButton: {\n margin: theme.spacing(1),\n color: Colors.neutrals[4],\n },\n\n modal: {\n position: 'absolute',\n height: '250',\n width: '250',\n top: '40%',\n left: '40%',\n padding: '20px',\n },\n\n cardHeader: {},\n})\n\nfunction getHostUrl() {\n return window.location.protocol + '//' + window.location.host\n}\n\nfunction SharingObjectForm() {\n const sharingObject = useSharingObjectsState(s => s.data)\n const intl = useIntl()\n\n const isInstituteAdmin = useAppState(s =>\n s.session.user.availableRoles.includes(USERROLES.InstituteAdmin)\n )\n const isCorPatchAdmin = useAppState(s =>\n s.session.user.availableRoles.includes(USERROLES.CorPatchAdmin)\n )\n\n const [confirmDeleteDialogOpen, setConfirmDeleteDialogOpen] = React.useState(\n false\n )\n const next = useNextAppState(s => s.pages.sharingObjects)\n const dispatch = useDispatchHook()\n const classes = useStyles()\n\n const pullUrl =\n config().apiAbsolute + `/api/sharing/pull/${sharingObject._id}`\n\n const invitationLink =\n getHostUrl() + `/trainee-shares/invite/${sharingObject.invitationCode}`\n\n function saveSharingObject() {\n dispatch({ type: 'Page/SharingObject/Save' })\n }\n\n function deleteSharingObject() {\n dispatch({ type: 'Page/SharingObject/Delete' })\n setConfirmDeleteDialogOpen(false)\n }\n return (\n <>\n <div style={{ width: '100%' }}>\n <Card className={classes.card}>\n <CardHeader title={intl.formatMessage(messages.title)} />\n <CardContent>\n <FormGroup row>\n <TextField\n label={intl.formatMessage(messages.name)}\n disabled={isInstituteAdmin}\n required\n className={classes.field}\n style={{ width: '100%' }}\n value={sharingObject.name}\n onChange={e => next(s => (s.data.name = e.target.value))}\n />\n </FormGroup>\n <FormGroup row>\n <TextField\n label={intl.formatMessage(messages.invitationCode)}\n disabled\n required\n style={{ width: '100%' }}\n className={classes.field}\n value={sharingObject.invitationCode}\n onChange={e =>\n next(s => (s.data.invitationCode = e.target.value))\n }\n />\n <TextField\n disabled\n label={intl.formatMessage(messages.invitationLink)}\n style={{ width: '100%' }}\n className={classes.field}\n value={invitationLink}\n />\n\n <TextField\n disabled={isCorPatchAdmin}\n label={intl.formatMessage(messages.webHook)}\n style={{ width: '100%' }}\n className={classes.field}\n value={sharingObject.webHook}\n onChange={e => next(s => (s.data.webHook = e.target.value))}\n />\n <TextField\n disabled={true}\n label={intl.formatMessage(messages.pullUrl)}\n style={{ width: '100%' }}\n className={classes.field}\n value={pullUrl}\n />\n \n <TextField\n disabled\n label={intl.formatMessage(messages.pullApiSecret)}\n style={{ width: '100%' }}\n className={classes.field}\n value={sharingObject.pullApiSecret}\n onChange={e =>\n next(s => (s.data.pullApiSecret = e.target.value))\n }\n />\n \n {!isInstituteAdmin && (\n <FormControl style={{ width: '100%', marginTop: 10 }}>\n <InputLabel id='notification-select'>\n {intl.formatMessage(messages.apiAccess)}\n </InputLabel>\n <Select\n style={{ width: 200 }}\n value={sharingObject.active ? 'true' : 'false'}\n onChange={e =>\n next(\n s =>\n (s.data.active =\n e.target.value === 'true' ? true : false)\n )\n }\n >\n <MenuItem value={'true'}>\n {intl.formatMessage(messages.enabled)}\n </MenuItem>\n <MenuItem value={'false'}>\n {intl.formatMessage(messages.disabled)}\n </MenuItem>\n </Select>\n </FormControl>\n )}\n </FormGroup>\n </CardContent>\n </Card>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row-reverse',\n justifyContent: 'space-between',\n marginTop: theme.spacing(2),\n }}\n >\n <Button\n variant='contained'\n color='secondary'\n size='small'\n className={classes.button}\n onClick={saveSharingObject}\n >\n {intl.formatMessage(messages.saveButton)}\n </Button>\n {!isInstituteAdmin && (\n <Button\n variant='contained'\n color='primary'\n size='small'\n className={classes.button}\n onClick={() => {\n setConfirmDeleteDialogOpen(true)\n }}\n >\n {intl.formatMessage(messages.deleteButton)}\n </Button>\n )}\n </div>\n </div>\n\n {!isInstituteAdmin && (\n <YesNoDialog\n open={confirmDeleteDialogOpen}\n dialogTitle={intl.formatMessage(messages.confirmDeleteDialogTitle)}\n yesButtonTitle={intl.formatMessage(messages.confirmDeleteDialogYes)}\n noButtonTitle={intl.formatMessage(messages.confirmDeleteDialogNo)}\n onYesButtonClick={deleteSharingObject}\n onNoButtonClick={() => {\n setConfirmDeleteDialogOpen(false)\n }}\n >\n <div>\n <Typography>\n {intl.formatMessage(messages.confirmDeleteDialogMessage1)}{' '}\n </Typography>\n <Typography style={{ marginTop: 20 }}>\n {intl.formatMessage(messages.confirmDeleteDialogMessage2)}\n </Typography>\n </div>\n </YesNoDialog>\n )}\n </>\n )\n}\n\nexport default SharingObject\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useTraineeSharesState = createStateHook(\n AppStoreProvider,\n state => state.pages.traineeShares\n)\nexport const useNextTraineeSharesState = () =>\n createNextHook(AppStoreProvider, state => state.pages.traineeShares)\n","import {\n Button,\n Card,\n CardContent,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Fab,\n FormGroup,\n IconButton,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core'\nimport AddIcon from '@material-ui/icons/Add'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport { makeStyles } from '@material-ui/styles'\nimport { PageNotFound } from 'components/PageNotFound/PageNotFound'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport { SharingTraineeAggregate } from 'model/SharingTraineeAggregate'\nimport React from 'react'\nimport { useAppState, useDispatchHook, useNextAppState } from 'state/store'\nimport { Images } from 'theme/Images'\nimport { theme } from 'theme/theme'\nimport { useTraineeSharesState } from './TraineeShares.restate'\nimport { YesNoDialog } from 'components/YesNoDialog/GenericConfirmDeletionDialog'\nimport { useIntl } from 'react-intl'\nimport messages from './TraineeShares.messages'\n\nconst TraineeSharesLoading = () => {\n const intl = useIntl()\n return (\n <AppPageLayout\n title={intl.formatMessage(messages.pageTitle)}\n loading={true}\n ></AppPageLayout>\n )\n}\n\nconst TraineeSharesNotFound = () => {\n const intl = useIntl()\n return (\n <PageNotFound\n title={intl.formatMessage(messages.pageTitleNotFound)}\n message={intl.formatMessage(messages.pageNotFoundMessage)}\n img={Images.detailedExamination}\n />\n )\n}\n\nconst useClasses = makeStyles({\n listItem: {\n backgroundColor: 'white',\n },\n card: {\n [theme.breakpoints.down('xs')]: {\n minWidth: 'auto',\n },\n width: '100%',\n },\n fab: {\n margin: theme.spacing(1),\n position: 'fixed',\n bottom: 20,\n right: 20,\n },\n})\n\nfunction isActive(s: SharingTraineeAggregate) {\n return s.endDate === null && s.sharingObject.meta.deletedAt === null\n}\n\nexport const TraineeShares: React.FC<{}> = () => {\n const { loading, notFound } = useTraineeSharesState(s => s.meta)\n const next = useNextAppState(s => s.pages.traineeShares)\n const classes = useClasses()\n const sharingTrainee = useTraineeSharesState(s => s.sharingTrainee)\n const intl = useIntl()\n const pageTitle = intl.formatMessage(messages.pageTitle)\n\n if (loading) return <TraineeSharesLoading />\n\n if (notFound) return <TraineeSharesNotFound />\n\n const activeSharingTrainee = sharingTrainee.filter(isActive)\n const deactivatedSharingTrainee = sharingTrainee.filter(s => !isActive(s))\n\n return (\n <AppPageLayout title={pageTitle}>\n <div style={{ width: '100%' }}>\n <Typography variant='h5'>\n {intl.formatMessage(messages.active)}\n </Typography>\n {activeSharingTrainee.length === 0 && <NoActiveItems />}\n {activeSharingTrainee.map(s => (\n <SharingTraineeCard sharingTrainee={s} />\n ))}\n </div>\n\n <div style={{ width: '100%', marginTop: 20 }}>\n <Typography variant='h5'>\n {intl.formatMessage(messages.inactive)}\n </Typography>\n {deactivatedSharingTrainee.length === 0 && <NoDeActiveItems />}\n {deactivatedSharingTrainee.map(s => (\n <SharingTraineeCard sharingTrainee={s} />\n ))}\n </div>\n\n <Fab\n className={classes.fab}\n color='secondary'\n aria-label={intl.formatMessage(messages.addShare)}\n onClick={() =>\n next(s => {\n s.addDialogCode = ''\n s.addDialogOpen = true\n })\n }\n >\n <AddIcon />\n </Fab>\n <AddDialog />\n </AppPageLayout>\n )\n}\n\nfunction NoActiveItems() {\n const intl = useIntl()\n return (\n <Typography\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n paddingTop: 20,\n paddingBottom: 20,\n }}\n >\n {intl.formatMessage(messages.noActiveItemsMessage)}\n </Typography>\n )\n}\n\nfunction NoDeActiveItems() {\n const intl = useIntl()\n\n return (\n <Typography\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n paddingTop: 20,\n paddingBottom: 20,\n }}\n >\n {intl.formatMessage(messages.noInactiveItemsMessage)}\n </Typography>\n )\n}\n\nfunction SharingTraineeCard(props: {\n sharingTrainee: SharingTraineeAggregate\n}) {\n const { sharingTrainee } = props\n const { institute } = sharingTrainee\n const dispatch = useDispatchHook()\n const [deactivateDialogOpen, setDeactivateDialogOpen] = React.useState(false)\n const active = isActive(sharingTrainee)\n const intl = useIntl()\n\n function deactivate() {\n setDeactivateDialogOpen(true)\n }\n\n return (\n <Card elevation={1} style={{ marginTop: 20 }}>\n <DeactivateDialog\n sharingTrainee={sharingTrainee}\n open={deactivateDialogOpen}\n onYesButtonClick={() =>\n dispatch({\n type: 'Pages/TraineeShares/Shares/Deactivate',\n sharingTrainee,\n })\n }\n onNoButtonClick={() => setDeactivateDialogOpen(false)}\n />\n <CardContent>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <div style={{ flexGrow: 1 }}>\n <Typography variant='h6'>{institute.name}</Typography>\n <Typography>{sharingTrainee.sharingObject.name}</Typography>\n </div>\n <div style={{ minWidth: active ? 250 : 298 }}>\n <Typography>\n {intl.formatMessage(messages.startDate)}\n {formatDate(sharingTrainee.startDate)}\n </Typography>\n <Typography>\n {intl.formatMessage(messages.endDate)}\n {formatDate(sharingTrainee.endDate)}\n </Typography>\n </div>\n {active && (\n <div>\n <Tooltip title={intl.formatMessage(messages.deactivateTooltip)}>\n <IconButton onClick={deactivate}>\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n </div>\n )}\n </div>\n </CardContent>\n </Card>\n )\n}\n\nfunction AddDialog() {\n const open = useAppState(s => s.pages.traineeShares.addDialogOpen)\n const code = useAppState(s => s.pages.traineeShares.addDialogCode)\n const next = useNextAppState(s => s.pages.traineeShares)\n const dispatch = useDispatchHook()\n const addButtonDisabled = !code || code.length === 0\n const intl = useIntl()\n\n return (\n <Dialog open={open}>\n <DialogTitle>{intl.formatMessage(messages.addDialogTitle)}</DialogTitle>\n <DialogContent>\n <Typography variant='body1' style={{ marginBottom: 20 }}>\n {intl.formatMessage(messages.addDialogDescription)}\n </Typography>\n <FormGroup>\n <TextField\n value={code}\n variant='outlined'\n onChange={e =>\n next(s => {\n s.addDialogCode = e.target.value\n })\n }\n />\n </FormGroup>\n\n <Typography style={{ marginTop: 20 }}>\n {intl.formatMessage(messages.addDialogDescription2)}\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() =>\n next(s => {\n s.addDialogOpen = false\n })\n }\n >\n {intl.formatMessage(messages.addDialogCancel)}\n </Button>\n <Button\n disabled={addButtonDisabled}\n color='primary'\n onClick={() => dispatch({ type: 'Pages/TraineeShares/Shares/Add' })}\n >\n {intl.formatMessage(messages.addDialogAdd)}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nfunction DeactivateDialog(props: {\n open: boolean\n sharingTrainee: SharingTraineeAggregate\n onYesButtonClick: () => void\n onNoButtonClick: () => void\n}) {\n const intl = useIntl()\n return (\n <YesNoDialog\n open={props.open}\n dialogTitle={intl.formatMessage(messages.deactivateDialogTitle)}\n onYesButtonClick={props.onYesButtonClick}\n onNoButtonClick={props.onNoButtonClick}\n noButtonTitle={intl.formatMessage(messages.deactivateDialogNo)}\n yesButtonTitle={intl.formatMessage(messages.deactivateDialogYes)}\n >\n <Typography style={{ marginTop: 20, marginBottom: 30 }}>\n {intl.formatMessage(messages.deactivateDialogDescription, {\n instituteName: props.sharingTrainee.institute.name,\n })}\n </Typography>\n </YesNoDialog>\n )\n}\n\nfunction formatDate(dateStr: string | null) {\n if (!dateStr) {\n return '-'\n }\n\n const date = new Date(dateStr)\n\n return date.toLocaleString('de-DE', {\n hour: '2-digit',\n minute: '2-digit',\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n })\n}\n\nexport default TraineeShares\n","import { createStateHook, createNextHook } from '@restate/core'\nimport { AppStoreProvider } from 'state/store'\n\nexport const useInstituteAdminSharesState = createStateHook(\n AppStoreProvider,\n state => state.pages.instituteAdminShares\n)\nexport const useNextInstituteAdminSharesState = () =>\n createNextHook(AppStoreProvider, state => state.pages.instituteAdminShares)\n","import {\n Card,\n CardContent,\n CardHeader,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableRow,\n Typography,\n makeStyles,\n} from '@material-ui/core'\nimport RightIcon from '@material-ui/icons/ChevronRightRounded'\nimport { SharingObjectDocument } from 'model/db/SharingObjectDocument.db-schema'\nimport React from 'react'\nimport { useIntl } from 'react-intl'\nimport { AppRoutes } from 'routes'\nimport { useGoToHook } from 'services/router/useGoTo.hook'\nimport { useInstituteAdminSharesState } from './InstituteAdminShares.restate'\nimport { AppPageLayout } from 'components/layouts/AppPageLayout'\nimport messages from './InstituteAdminShares.messages'\n\nconst useClasses = makeStyles(theme => ({\n table: {\n [theme.breakpoints.up('md')]: {\n minWidth: 600,\n },\n },\n fab: {\n margin: theme.spacing(1),\n position: 'fixed',\n bottom: 10,\n right: 10,\n },\n startDate: {\n fontSize: '0.8rem',\n color: theme.palette.grey[500],\n },\n}))\n\nexport function InstituteAdminShares() {\n const sharingObjects = useInstituteAdminSharesState(s => s.sharingObjects)\n const classes = useClasses()\n const intl = useIntl()\n const active = intl.formatMessage(messages.active)\n const deleted = intl.formatMessage(messages.deleted)\n\n const activeSharingObjects = sharingObjects.filter(\n sharingObject => sharingObject.meta.deletedAt === null\n )\n\n const deactivatedSharingObjects = sharingObjects.filter(\n sharingObject => sharingObject.meta.deletedAt !== null\n )\n\n const hasActiveSharingObjects = activeSharingObjects.length > 0\n const hasDeactivatedSharingObjects = deactivatedSharingObjects.length > 0\n\n return (\n <AppPageLayout title={intl.formatMessage(messages.pageTitle)}>\n <Card>\n <CardHeader title={active} />\n <CardContent>\n <Table size={'small'} className={classes.table}>\n <TableBody>\n {!hasActiveSharingObjects && (\n <Typography>\n {intl.formatMessage(messages.noActiveSharingObjectsMessage)}\n </Typography>\n )}\n {hasActiveSharingObjects &&\n activeSharingObjects.map(sharingObject => (\n <SharingObjectRow sharingObject={sharingObject} />\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n\n <Card style={{ marginTop: 20 }}>\n <CardHeader title={deleted} />\n <CardContent>\n <Table size={'small'} className={classes.table}>\n <TableBody>\n {!hasDeactivatedSharingObjects && (\n <Typography>\n {intl.formatMessage(messages.noDeletedSharingObjectsMessage)}\n </Typography>\n )}\n {hasDeactivatedSharingObjects &&\n deactivatedSharingObjects.map(sharingObject => (\n <SharingObjectRow sharingObject={sharingObject} disabled />\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </AppPageLayout>\n )\n}\n\nfunction SharingObjectRow(props: {\n sharingObject: SharingObjectDocument\n disabled?: boolean\n}) {\n const { sharingObject, disabled = false } = props\n const classes = useClasses()\n const intl = useIntl()\n\n const goTo = useGoToHook()\n const navigateToSharingObject = () =>\n goTo(AppRoutes.InstituteAdminSharingObject, { id: sharingObject._id })\n\n return (\n <TableRow>\n <TableCell style={{ height: 60 }}>\n <div>{sharingObject.name}</div>\n <div className={classes.startDate}>\n {intl.formatMessage(messages.startDate)}\n {intl.formatDate(sharingObject.meta.createdAt)}\n </div>\n {sharingObject.meta.deletedAt && (\n <div className={classes.startDate}>\n {intl.formatMessage(messages.endDate)}\n {intl.formatDate(sharingObject.meta.deletedAt)}\n </div>\n )}\n </TableCell>\n <TableCell align='right'>\n {!disabled && (\n <IconButton onClick={navigateToSharingObject}>\n <RightIcon />\n </IconButton>\n )}\n </TableCell>\n </TableRow>\n )\n}\n","import { ThemeProvider } from '@material-ui/styles'\nimport { AppSnackBar } from 'components/AppSnackBar/AppSnackBar'\nimport Imprint from 'components/Imprint/Imprint'\nimport AcceptInvitation from 'pages/AcceptInvitation.tsx/AcceptInvitation'\nimport AdminInvite from 'pages/AdminInvite/AdminInvite'\nimport { Course } from 'pages/Course/Course'\nimport { Courses } from 'pages/Courses/Courses'\nimport Export from 'pages/Export/Export'\nimport Institute from 'pages/Institute/Institute'\nimport Institutes from 'pages/Institutes/Institutes'\nimport InternalServerError from 'pages/InternalServerError/InternalServerError'\nimport LoginPasswordForgot from 'pages/LoginPasswordForgot/LoginPasswordForgot'\nimport { LoginPasswordForgotSetPassword } from 'pages/LoginPasswordForgotSetPassword/LoginPasswordForgotSetPassword'\nimport Logout from 'pages/Logout/Logout'\nimport { Me } from 'pages/Me/Me'\nimport NetworkError from 'pages/NetworkError/NetworkError'\nimport Settings from 'pages/Settings/Settings'\nimport { Shop } from 'pages/Shop/Shop'\nimport TrainerInvite from 'pages/TrainerInvite/TrainerInvite'\nimport Trainers from 'pages/Trainers/Trainers'\nimport Trainings from 'pages/Trainings/Trainings'\nimport { UserChangeEmail } from 'pages/UserChangeEmail/UserChangeEmail'\nimport { UserChangePassword } from 'pages/UserChangePassword/UserChangePassword'\nimport { UserDetails } from 'pages/UserDetails/UserDetails'\nimport React, { useEffect, useMemo } from 'react'\nimport { Redirect, Route, Router, Switch, useLocation } from 'react-router-dom'\nimport { AppRoutes } from 'routes'\nimport Reminder from './components/Reminder/Reminder'\nimport { AppIntlProvider } from './I18N/AppIntlProvider'\nimport './index.css'\nimport { Login } from './pages/Login/Login'\nimport {\n AppStoreProvider,\n history,\n store,\n useAppState,\n useNextAppState,\n} from './state/store'\nimport { theme } from './theme/theme'\nimport Dashboard from './pages/Dashboard/Dashboard'\nimport Trainees from './pages/Trainees/Trainees'\nimport GlobalSettings from 'pages/GlobalSettings/GlobalSettings'\nimport TermsOfUse from 'components/TermsOfUse/TermsOfUse'\nimport Register from 'pages/Register/Register'\nimport EmailValidation from 'pages/EmailValidation/EmailValidation'\nimport SingleTrainings from 'pages/SingleTrainings/SingleTrainings'\nimport ValidateLogin from './pages/ValidateLogin/ValidateLogin'\nimport { USERROLES } from './model/UserRole'\nimport SharingObjects from 'pages/SharingObject/SharingObject'\nimport TraineeShares from 'pages/TraineeShares/TraineeShares'\nimport { InstituteAdminShares } from 'pages/InstituteAdminShares/InstituteAdminShares'\nimport { deDE, enUS, fiFI, frFR, itIT, esES } from '@material-ui/core/locale'\nimport { createTheme } from '@material-ui/core'\nimport { useRTL } from 'utils/useRTL'\n\nconst UserMenuPages = () => (\n <>\n <Route exact path={AppRoutes.MeEMail} component={UserChangeEmail} />\n <Route exact path={AppRoutes.MePassword} component={UserChangePassword} />\n <Route exact path={AppRoutes.MeAccount} component={Me} />\n </>\n)\n\nconst CorPatchAdminPages = () => {\n const isCorPatchAdmin = useAppState(\n s => s.session.user.role === USERROLES.CorPatchAdmin\n )\n\n if (!isCorPatchAdmin) {\n return <></>\n }\n\n return (\n <>\n <Route exact path={AppRoutes.Home} component={Dashboard} />\n <UserMenuPages />\n <Route exact path={AppRoutes.AdminInvite} component={AdminInvite} />\n <Route exact path={AppRoutes.GlobalSettings} component={GlobalSettings} />\n <Route exact path={AppRoutes.Course} component={Course} />\n <Route exact path={AppRoutes.Courses} component={Courses} />\n <Route exact path={AppRoutes.Export} component={Export} />\n <Route exact path={AppRoutes.Imprint} component={Imprint} />\n <Route exact path={AppRoutes.Institute} component={Institute} />\n <Route exact path={AppRoutes.Institutes} component={Institutes} />\n <Route exact path={AppRoutes.Settings} component={Settings} />\n <Route exact path={AppRoutes.TrainerInvite} component={TrainerInvite} />\n <Route exact path={AppRoutes.Trainers} component={Trainers} />\n <Route exact path={AppRoutes.Trainings} component={Trainings} />\n <Route exact path={AppRoutes.Trainees} component={Trainees} />\n <Route exact path={AppRoutes.UserDetails} component={UserDetails} />\n <Route exact path={AppRoutes.SharingObject} component={SharingObjects} />\n </>\n )\n}\n\nconst TrainerPages = () => {\n const isTrainer = useAppState(s => s.session.user.role === USERROLES.Trainer)\n if (!isTrainer) {\n return <></>\n }\n return (\n <>\n <Route exact path='/'>\n <Redirect to={AppRoutes.Courses} />\n </Route>\n <UserMenuPages />\n <Route exact path={AppRoutes.Course} component={Course} />\n <Route exact path={AppRoutes.Courses} component={Courses} />\n <Route exact path={AppRoutes.Export} component={Export} />\n <Route exact path={AppRoutes.Imprint} component={Imprint} />\n <Route exact path={AppRoutes.Settings} component={Settings} />\n <Route exact path={AppRoutes.Trainings} component={Trainings} />\n <Route exact path={AppRoutes.UserDetails} component={UserDetails} />\n </>\n )\n}\n\nconst TraineePages = () => {\n const isTrainee = useAppState(s => s.session.user.role === USERROLES.Trainee)\n if (!isTrainee) {\n return <></>\n }\n\n return (\n <>\n <Route exact path={'/'} component={Reminder} />\n <UserMenuPages />\n <Route exact path={AppRoutes.TraineeShares} component={TraineeShares} />\n <Route\n exact\n path={AppRoutes.TraineeSharesInvite}\n component={TraineeShares}\n />\n <Route exact path={AppRoutes.Imprint} component={Imprint} />\n <Route\n exact\n path={AppRoutes.SingleTrainings}\n component={SingleTrainings}\n />\n </>\n )\n}\n\nconst InstituteAdminPages = () => {\n const isInstituteAdmin = useAppState(\n s => s.session.user.role === USERROLES.InstituteAdmin\n )\n if (!isInstituteAdmin) {\n return <></>\n }\n\n return (\n <>\n <Route exact path='/'>\n <Redirect to={AppRoutes.Courses} />\n </Route>\n <UserMenuPages />\n <Route exact path={AppRoutes.AdminInvite} component={AdminInvite} />\n <Route exact path={AppRoutes.Course} component={Course} />\n <Route exact path={AppRoutes.Courses} component={Courses} />\n {/* <Route exact path={AppRoutes.Export} component={Export} /> */}\n <Route exact path={AppRoutes.Imprint} component={Imprint} />\n <Route exact path={AppRoutes.Settings} component={Settings} />\n <Route\n exact\n path={AppRoutes.InstituteAdminShares}\n component={InstituteAdminShares}\n />\n <Route exact path={AppRoutes.TrainerInvite} component={TrainerInvite} />\n <Route exact path={AppRoutes.Trainers} component={Trainers} />\n <Route exact path={AppRoutes.Trainings} component={Trainings} />\n <Route exact path={AppRoutes.UserDetails} component={UserDetails} />\n <Route\n exact\n path={AppRoutes.InstituteAdminSharingObject}\n component={SharingObjects}\n />\n </>\n )\n}\n\nconst PublicPages = () => {\n // Routing is restricted if the query for embeddedMode has been set.\n // This is the case when the app is displayed as a webview from a mobile device.\n const next = useNextAppState(state => state.routerExtension)\n\n const { search } = useLocation()\n\n const embeddedMode = useMemo(() => {\n const query = new URLSearchParams(search)\n\n return Boolean(query.get('embeddedMode'))\n }, [search])\n\n useEffect(() => {\n // Only unidirectional change to embedded mode. Will be persisted over route changes.\n // A reload will refresh this value, because it will usually stay consistent if embedded mode is turned on.\n if (embeddedMode) {\n next(session => {\n session.embeddedMode = true\n })\n }\n }, [embeddedMode, next])\n\n return (\n <>\n <Route\n exact\n path={AppRoutes.AcceptInvitation}\n component={AcceptInvitation}\n />\n <Route\n exact\n path={AppRoutes.LoginPasswordForgotSetPassword}\n component={LoginPasswordForgotSetPassword}\n />\n <Route\n exact\n path={AppRoutes.InternalServerError}\n component={InternalServerError}\n />\n <Route exact path={AppRoutes.Login} component={Login} />\n <Route\n exact\n path={AppRoutes.LoginPasswordForgot}\n component={LoginPasswordForgot}\n />\n <Route path={AppRoutes.ValidateLogin} component={ValidateLogin} />\n <Route\n path={AppRoutes.ValidateLoginPublic}\n exact\n component={ValidateLogin}\n />\n <Route exact path={AppRoutes.Logout} component={Logout} />\n <Route exact path={AppRoutes.NetworkError} component={NetworkError} />\n <Route exact path={AppRoutes.LoginTermsOfUse} component={TermsOfUse} />\n <Route exact path={AppRoutes.Register} component={Register} />\n <Route\n exact\n path={AppRoutes.EmailValidation}\n component={EmailValidation}\n />\n </>\n )\n}\n\nfunction useLocalizedTheme() {\n function localization(locale: string) {\n switch (locale) {\n case 'de-DE':\n return deDE\n case 'en-US':\n return enUS\n case 'da-DA':\n return enUS\n case 'fi-FI':\n return fiFI\n case 'it-IT':\n return itIT\n case 'fr-FR':\n return frFR\n case 'es-ES':\n return esES\n case 'ar-SA': // no arabic support in MUI v4\n return enUS\n default:\n return enUS\n }\n }\n\n const s = useAppState(s => s.i18n.locale)\n const isRTL = useRTL()\n\n const localizedTheme = React.useMemo(\n () =>\n createTheme(\n { ...theme, direction: isRTL ? 'rtl' : 'ltr' },\n localization(s)\n ),\n [s, isRTL]\n )\n return localizedTheme\n}\n\nfunction App() {\n const theme = useLocalizedTheme()\n const RTL = useAppState(s => s.i18n.locale === 'ar-SA')\n\n return (\n <div dir={RTL ? 'rtl' : 'ltr'}>\n <AppStoreProvider.Provider value={store}>\n <AppIntlProvider>\n <Router history={history}>\n <ThemeProvider theme={theme}>\n <AppSnackBar>\n <Shop />\n <Switch>\n <>\n <CorPatchAdminPages />\n <InstituteAdminPages />\n <TrainerPages />\n <TraineePages />\n <PublicPages />\n </>\n </Switch>\n </AppSnackBar>\n </ThemeProvider>\n </Router>\n </AppIntlProvider>\n </AppStoreProvider.Provider>\n </div>\n )\n}\n\nexport default App\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport './index.css'\nimport App from './App'\n\nReactDOM.render(<App />, document.getElementById('root'))\n"],"sourceRoot":""}