feat: profile page sections

Close #233, #261, #267
This commit is contained in:
Thea Schöbl
2022-10-11 16:01:38 +00:00
committed by Jovan Krunić
parent 6b9b1fa854
commit e395e9d270
26 changed files with 923 additions and 236 deletions

View File

@@ -1,3 +1,18 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Injectable} from '@angular/core';
import {
CanActivate,
@@ -34,6 +49,7 @@ export class AuthGuardService implements CanActivate {
extras = {queryParams: {origin_path: url}};
}
this.router.navigate(['profile'], extras);
await this.authHelper.getProvider(route.data.authProvider).signIn();
return false;
}

View File

@@ -22,7 +22,7 @@
<ion-icon name="local_cafe"></ion-icon>
<ion-label>{{ 'tabs.canteens' | translate }}</ion-label>
</ion-tab-button>
<ion-tab-button rootLink="/schedule">
<ion-tab-button rootLink="/profile">
<ion-icon name="school"></ion-icon>
<ion-label>{{ 'tabs.schedule' | translate }}</ion-label>
</ion-tab-button>
@@ -30,8 +30,4 @@
<ion-icon name="map"></ion-icon>
<ion-label>{{ 'tabs.map' | translate }}</ion-label>
</ion-tab-button>
<ion-tab-button rootLink="/profile">
<ion-icon name="account_circle"></ion-icon>
<ion-label>{{ 'tabs.profile' | translate }}</ion-label>
</ion-tab-button>
</ion-tab-bar>

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
import {SCSection} from './sections';
import {AuthHelperService} from '../../auth/auth-helper.service';
import {Subscription} from 'rxjs';
import {SCAuthorizationProviderType} from '@openstapps/core';
import Swiper from 'swiper';
@Component({
selector: 'stapps-profile-page-section',
templateUrl: 'profile-page-section.html',
styleUrls: ['profile-page-section.scss'],
})
export class ProfilePageSectionComponent implements OnInit, OnDestroy {
@Input() item: SCSection;
@Input() minSlideWidth = 110;
isLoggedIn: boolean;
isEnd = false;
isBeginning = true;
subscriptions: Subscription[] = [];
slidesPerView: number;
slidesFillScreen = false;
constructor(private authHelper: AuthHelperService) {}
ngOnInit() {
if (this.item.authProvider) {
const provider = this.item.authProvider;
this.subscriptions.push(
this.authHelper
.getProvider(provider as 'default')
.token$.subscribe(_token => {
this.authHelper
.getProvider(provider)
.getValidToken()
.then(() => {
this.isLoggedIn = true;
})
.catch(_error => {
this.isLoggedIn = false;
});
}),
);
}
}
activeIndexChange(swiper: Swiper) {
this.isBeginning = swiper.isBeginning;
this.isEnd = swiper.isEnd;
this.slidesFillScreen = this.slidesPerView >= swiper.slides.length;
}
resizeSwiper(resizeEvent: ResizeObserverEntry, swiper: Swiper) {
const slidesPerView =
Math.floor(
(resizeEvent.contentRect.width - this.minSlideWidth / 2) /
this.minSlideWidth,
) + 0.5;
if (slidesPerView > 1 && slidesPerView !== this.slidesPerView) {
this.slidesPerView = slidesPerView;
swiper.params.slidesPerView = this.slidesPerView;
swiper.update();
this.activeIndexChange(swiper);
}
}
async toggleLogIn() {
if (!this.item.authProvider) return;
await (this.isLoggedIn
? this.signOut(this.item.authProvider)
: this.signIn(this.item.authProvider));
}
async signIn(providerType: SCAuthorizationProviderType) {
await this.authHelper.getProvider(providerType).signIn();
}
async signOut(providerType: SCAuthorizationProviderType) {
await this.authHelper.getProvider(providerType).signOut();
}
ngOnDestroy() {
for (const subscription of this.subscriptions) {
subscription.unsubscribe();
}
}
}

View File

@@ -0,0 +1,72 @@
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ion-label class="section-headline">
<!-- TODO: move this to thing translate -->
{{ 'name' | translateSimple: item }}
</ion-label>
<ion-button
*ngIf="item.authProvider"
fill="clear"
(click)="toggleLogIn()"
style="grid-area: login"
>
<ion-icon
*ngIf="isLoggedIn; else loginIcon"
slot="icon-only"
color="dark"
name="logout"
></ion-icon>
<ng-template #loginIcon>
<ion-icon slot="icon-only" color="dark" name="login"></ion-icon>
</ng-template>
</ion-button>
<ion-button
[disabled]="isBeginning"
(click)="swiper.swiperRef.slidePrev()"
fill="clear"
color="dark"
class="navigation"
[class.hidden]="slidesFillScreen"
style="grid-area: prev"
><ion-icon slot="icon-only" name="chevron_left"></ion-icon
></ion-button>
<ion-button
[disabled]="isEnd"
(click)="swiper.swiperRef.slideNext()"
fill="clear"
color="dark"
class="navigation"
[class.hidden]="slidesFillScreen"
style="grid-area: next"
><ion-icon slot="icon-only" name="chevron_right"></ion-icon
></ion-button>
<swiper
#swiper
(elementSizeChange)="resizeSwiper($event, swiper.swiperRef)"
(activeIndexChange)="activeIndexChange($event[0])"
[simulateTouch]="false"
[touchMoveStopPropagation]="false"
[spaceBetween]="0"
[slidesPerView]="slidesPerView"
class="card-swiper"
>
<ng-template swiperSlide *ngFor="let link of item.links">
<stapps-section-link-card
[disabled]="link.needsAuth && !isLoggedIn"
[item]="link"
></stapps-section-link-card>
</ng-template>
</swiper>

View File

@@ -0,0 +1,59 @@
/*!
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
.section-headline {
padding-inline-start: var(--spacing-md);
}
.log-in-hint {
padding: var(--spacing-xl);
height: 100%;
box-shadow: none;
background: var(--ion-color-light-tint);
}
.navigation::part(native) {
padding-inline: 0;
}
:host {
display: grid;
grid-template-columns: 1fr auto auto auto;
grid-template-rows: 42px 1fr;
grid-template-areas:
"title prev next login"
"swiper swiper swiper swiper";
align-items: center;
> ion-label {
margin-block-end: 0;
}
> swiper {
grid-area: swiper;
width: 100%;
padding-right: 0;
}
}
ion-button.hidden {
display: none;
}
@media (hover: none) {
ion-button.navigation {
display: none;
}
}

View File

@@ -1,158 +0,0 @@
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ion-header>
<ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>{{ 'profile.title' | translate | titlecase }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<section class="user-card-wrapper">
<ion-card class="user-card">
<ion-card-header>
<ion-img src="assets/imgs/header.svg"></ion-img>
<span>
{{
userInfo?.role
? (userInfo?.role | titlecase)
: ('profile.role_guest' | translate | titlecase)
}}
</span>
</ion-card-header>
<ion-card-content>
<ion-img
class="profile-card-img"
src="assets/imgs/profile-card-head.svg"
></ion-img>
<ion-grid>
<ion-row>
<ion-col size="3"></ion-col>
<ion-col
*ngIf="data.default.loggedIn; else logInPrompt"
size="9"
class="main-info"
>
<ion-text class="full-name">
{{ userInfo?.givenName }}
{{ userInfo?.familyName }}
</ion-text>
<div class="matriculation-number">
<ion-label>
{{ 'profile.userInfo.studentId' | translate | uppercase }}
</ion-label>
<ion-text>
{{ userInfo?.studentId }}
</ion-text>
</div>
<div class="user-name">
<ion-label>
{{ 'profile.userInfo.username' | translate | uppercase }}
</ion-label>
<ion-text>{{ userInfo?.name }}</ion-text>
</div>
<div class="email">
<ion-label>
{{ 'profile.userInfo.email' | translate | uppercase }}
</ion-label>
<ion-text>
{{ userInfo?.email }}
</ion-text>
</div>
</ion-col>
<ng-template #logInPrompt>
<ion-col size="9">
<ion-text class="log-in-prompt">
{{ 'profile.userInfo.logInPrompt' | translate }}
</ion-text>
</ion-col>
</ng-template>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>
</section>
<section class="login">
<ion-label class="section-headline">
{{ 'profile.titleLogins' | translate | uppercase }}
</ion-label>
<swiper [config]="sliderOptions" slidesPerView="auto" class="card-swiper">
<ng-template swiperSlide *ngFor="let loginItem of logins">
<a
*ngIf="!data[loginItem]['loggedIn']"
class="swiper-card card"
(click)="signIn(loginItem)"
>
<ion-label>
{{
'profile.buttons.' + loginItem + '.log_in' | translate | titlecase
}}
</ion-label>
</a>
<a
*ngIf="data[loginItem]['loggedIn']"
class="swiper-card card"
(click)="signOut(loginItem)"
>
{{
'profile.buttons.' + loginItem + '.log_out' | translate | titlecase
}}
</a>
</ng-template>
</swiper>
</section>
<section class="courses">
<ion-label class="section-headline">
{{ 'profile.titleCourses' | translate | uppercase }}
</ion-label>
<ion-card class="courses-card">
<ion-card-header (click)="toggleCourseCardState()">
<span>{{ 'profile.courses.today' | translate | uppercase }}</span>
<ion-icon [name]="courseCardState" fill="red" size="20"></ion-icon>
</ion-card-header>
<ion-card-content
class="course-card"
[class.show-card]="courseCardState === courseCardEnum.expanded"
>
<ng-container *ngIf="myCoursesToday.length === 0">
<div class="no-course">
{{ 'profile.courses.no_courses' | translate }}
</div>
</ng-container>
<ng-container *ngFor="let myCourse of myCoursesToday">
<div
class="clickable"
[routerLink]="['/data-detail', myCourse.course.event.uid]"
>
<div>{{ myCourse?.startTime }} - {{ myCourse?.endTime }}</div>
<div>{{ myCourse?.course.event?.originalCategory }}</div>
<div [class.last]="!myCourse?.course.inPlace?.name">
{{ myCourse.course?.event?.name }}
</div>
<div
*ngIf="myCourse.course?.inPlace?.name"
[class.last]="myCourse.course?.inPlace?.name"
>
{{ myCourse.course?.inPlace.name }}
</div>
</div>
</ng-container>
</ion-card-content>
</ion-card>
</section>
</ion-content>

View File

@@ -1,16 +1,16 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, OnInit} from '@angular/core';
@@ -27,6 +27,7 @@ import {ActivatedRoute} from '@angular/router';
import {ScheduleProvider} from '../../calendar/schedule.provider';
import moment from 'moment';
import {SCIcon} from '../../../util/ion-icon/icon';
import {profilePageSections} from './sections';
const CourseCard = {
collapsed: SCIcon`expand_more`,
@@ -41,8 +42,8 @@ interface MyCoursesTodayInterface {
@Component({
selector: 'app-home',
templateUrl: './profile-page.component.html',
styleUrls: ['./profile-page.component.scss'],
templateUrl: 'profile-page.html',
styleUrls: ['profile-page.scss'],
})
export class ProfilePageComponent implements OnInit {
data: {[key in SCAuthorizationProviderType]: {loggedIn: boolean}} = {
@@ -50,24 +51,14 @@ export class ProfilePageComponent implements OnInit {
paia: {loggedIn: false},
};
sections = profilePageSections;
logins: SCAuthorizationProviderType[] = [];
originPath: string | null;
userInfo?: SCUserConfiguration;
/**
* Slider options
*/
sliderOptions = {
spaceBetween: 12,
freeMode: {
enabled: true,
sticky: true,
},
width: 130,
};
courseCardEnum = CourseCard;
courseCardState = CourseCard.expanded;

View File

@@ -0,0 +1,135 @@
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ion-header>
<ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>{{ 'profile.title' | translate | titlecase }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div>
<section class="user-card-wrapper">
<ion-card class="user-card">
<ion-card-header>
<ion-img src="assets/imgs/header.svg"></ion-img>
<span>
{{
userInfo?.role
? (userInfo?.role | titlecase)
: ('profile.role_guest' | translate | titlecase)
}}
</span>
</ion-card-header>
<ion-card-content>
<ion-img
class="profile-card-img"
src="assets/imgs/profile-card-head.svg"
></ion-img>
<ion-grid>
<ion-row>
<ion-col size="3"></ion-col>
<ion-col
*ngIf="data.default.loggedIn; else logInPrompt"
size="9"
class="main-info"
>
<ion-text class="full-name">
{{ userInfo?.givenName }}
{{ userInfo?.familyName }}
</ion-text>
<div class="matriculation-number">
<ion-label>
{{ 'profile.userInfo.studentId' | translate | uppercase }}
</ion-label>
<ion-text>
{{ userInfo?.studentId }}
</ion-text>
</div>
<div class="user-name">
<ion-label>
{{ 'profile.userInfo.username' | translate | uppercase }}
</ion-label>
<ion-text>{{ userInfo?.name }}</ion-text>
</div>
<div class="email">
<ion-label>
{{ 'profile.userInfo.email' | translate | uppercase }}
</ion-label>
<ion-text>
{{ userInfo?.email }}
</ion-text>
</div>
</ion-col>
<ng-template #logInPrompt>
<ion-col size="9">
<ion-text class="log-in-prompt">
{{ 'profile.userInfo.logInPrompt' | translate }}
</ion-text>
</ion-col>
</ng-template>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>
</section>
<stapps-profile-page-section
*ngFor="let section of sections"
[item]="section"
></stapps-profile-page-section>
<section class="courses">
<ion-label class="section-headline">
{{ 'profile.titleCourses' | translate | uppercase }}
</ion-label>
<ion-card class="courses-card">
<ion-card-header (click)="toggleCourseCardState()">
<span>{{ 'profile.courses.today' | translate | uppercase }}</span>
<ion-icon [name]="courseCardState" fill="red" size="20"></ion-icon>
</ion-card-header>
<ion-card-content
class="course-card"
[class.show-card]="courseCardState === courseCardEnum.expanded"
>
<ng-container *ngIf="myCoursesToday.length === 0">
<div class="no-course">
{{ 'profile.courses.no_courses' | translate }}
</div>
</ng-container>
<ng-container *ngFor="let myCourse of myCoursesToday">
<div
class="clickable"
[routerLink]="['/data-detail', myCourse.course.event.uid]"
>
<div>{{ myCourse?.startTime }} - {{ myCourse?.endTime }}</div>
<div>{{ myCourse?.course.event?.originalCategory }}</div>
<div [class.last]="!myCourse?.course.inPlace?.name">
{{ myCourse.course?.event?.name }}
</div>
<div
*ngIf="myCourse.course?.inPlace?.name"
[class.last]="myCourse.course?.inPlace?.name"
>
{{ myCourse.course?.inPlace.name }}
</div>
</div>
</ng-container>
</ion-card-content>
</ion-card>
</section>
</div>
</ion-content>

View File

@@ -1,21 +1,24 @@
/*!
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
@import "src/theme/common/ion-content-parallax";
:host {
ion-content {
--background: var(--ion-color-light);
@include ion-content-parallax($content-size: 130px)
}
section {
@@ -30,18 +33,6 @@
margin-bottom: var(--spacing-md);
}
.user-card-wrapper {
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 75%;
max-height: 17vh;
background-color: var(--ion-color-primary);
z-index: -1;
}
.user-card {
border-radius: var(--border-radius-default);
position: relative;
@@ -137,20 +128,6 @@
}
}
.login {
.swiper.card-swiper {
text-align: left;
.swiper-card {
padding: var(--spacing-lg) var(--spacing-md);
font-size: var(--font-size-md);
font-weight: var(--font-weight-black);
justify-content: center;
height: 120px;
cursor: pointer;
}
}
}
ion-thumbnail {
background: var(--placeholder-gray);
height: 80%;

View File

@@ -0,0 +1,233 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
// TODO: move this to external configuration & stapps core
import {
SCAuthorizationProviderType,
SCThing,
SCThingOriginType,
SCThingRemoteOrigin,
SCThingType,
} from '@openstapps/core';
import {SCIcon} from '../../../util/ion-icon/icon';
export const SCSectionThingType = 'section' as SCThingType;
export const SCSectionLinkThingType = 'section link' as SCThingType;
const StubOrigin: SCThingRemoteOrigin = {
type: SCThingOriginType.Remote,
name: 'todo',
indexed: new Date(Date.now()).toISOString(),
};
const SCSectionConstantValues: Pick<SCSection, 'type' | 'origin' | 'uid'> = {
type: SCSectionThingType,
origin: StubOrigin,
uid: 'stub',
};
const SCSectionLinkConstantValues: Pick<SCSection, 'type' | 'origin' | 'uid'> =
{
type: SCSectionLinkThingType,
origin: StubOrigin,
uid: 'stub',
};
export interface SCSectionLink extends SCThing {
link: string[];
needsAuth?: true;
icon?: string;
}
export interface SCSection extends SCThing {
authProvider?: SCAuthorizationProviderType;
links: SCSectionLink[];
}
export const profilePageSections: SCSection[] = [
{
name: 'Your StApps',
links: [
{
name: 'Favorites',
icon: SCIcon`grade`,
link: ['/favorites'],
translations: {
de: {
name: 'Favoriten',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Schedule',
icon: SCIcon`calendar_today`,
link: ['/schedule'],
translations: {
de: {
name: 'Stundenplan',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Course Catalog',
icon: SCIcon`inventory_2`,
link: ['/catalog'],
translations: {
de: {
name: 'Vorlesungs Verzeichnis',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Settings',
icon: SCIcon`settings`,
link: ['/settings'],
translations: {
de: {
name: 'Einstellungen',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Feedback',
icon: SCIcon`rate_review`,
link: ['/feedback'],
translations: {
de: {
name: 'Einstellungen',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'About StApps',
icon: SCIcon`info`,
link: ['/about'],
translations: {
de: {
name: 'Über StApps',
},
},
...SCSectionLinkConstantValues,
},
],
translations: {
de: {
name: 'Dein StApps',
},
},
...SCSectionConstantValues,
},
{
name: 'Campus Services',
authProvider: 'default',
links: [
{
name: 'Assessments',
icon: SCIcon`fact_check`,
link: ['/assessments'],
needsAuth: true,
translations: {
de: {
name: 'Noten',
},
},
...SCSectionLinkConstantValues,
},
],
translations: {
de: {
name: 'Campus Dienste',
},
},
...SCSectionConstantValues,
},
{
name: 'Library',
authProvider: 'paia',
links: [
{
name: 'Library Search',
icon: SCIcon`local_library`,
link: ['/hebis-search'],
translations: {
de: {
name: 'Bibliotheks Suche',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Library Account',
icon: SCIcon`badge`,
needsAuth: true,
link: ['/library-account/profile'],
translations: {
de: {
name: 'Bibliotheks Konto',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Holdings & Reservations',
icon: SCIcon`collections_bookmark`,
needsAuth: true,
link: ['/library-account/holds-and-reservations'],
translations: {
de: {
name: 'Bestellungen & Vormerkungen',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Checked out items',
icon: SCIcon`library_books`,
needsAuth: true,
link: ['/library-account/checked-out'],
translations: {
de: {
name: 'Deine Ausleihen',
},
},
...SCSectionLinkConstantValues,
},
{
name: 'Fines',
icon: SCIcon`request_page`,
needsAuth: true,
link: ['/library-account/fines'],
translations: {
de: {
name: 'Gebühren',
},
},
...SCSectionLinkConstantValues,
},
],
translations: {
de: {
name: 'Bibliothek',
},
},
...SCSectionConstantValues,
},
];

View File

@@ -1,28 +1,31 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {Routes, RouterModule} from '@angular/router';
import {RouterModule, Routes} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {ProfilePageComponent} from './page/profile-page.component';
import {TranslateModule} from '@ngx-translate/core';
import {SwiperModule} from 'swiper/angular';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {ProfilePageSectionComponent} from './page/profile-page-section.component';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {SectionModule} from '../../util/section/section.module';
const routes: Routes = [
{
@@ -32,7 +35,7 @@ const routes: Routes = [
];
@NgModule({
declarations: [ProfilePageComponent],
declarations: [ProfilePageComponent, ProfilePageSectionComponent],
imports: [
CommonModule,
FormsModule,
@@ -42,6 +45,8 @@ const routes: Routes = [
TranslateModule,
SwiperModule,
UtilModule,
ThingTranslateModule,
SectionModule,
],
})
export class ProfilePageModule {}