MOBILE-3592 user: Implement about page
parent
c608432d24
commit
537846e1cf
|
@ -0,0 +1,97 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title *ngIf="title">{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher slot="fixed" [disabled]="!userLoaded" (ionRefresh)="refreshUser($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="userLoaded">
|
||||
<ion-list *ngIf="user">
|
||||
<ion-item-group *ngIf="hasContact">
|
||||
<ion-item-divider>{{ 'core.user.contact' | translate}}</ion-item-divider>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.email">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.email' | translate }}</h2>
|
||||
<p><a class="core-anchor" href="mailto:{{user.email}}" core-link auto-login="no">
|
||||
{{ user.email }}
|
||||
</a></p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.phone1">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.phone1' | translate}}</h2>
|
||||
<p><a class="core-anchor" href="tel:{{user.phone1}}" core-link auto-login="no">
|
||||
{{ user.phone1 }}
|
||||
</a></p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.phone2">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.phone2' | translate}}</h2>
|
||||
<p><a class="core-anchor" href="tel:{{user.phone2}}" core-link auto-login="no">
|
||||
{{ user.phone2 }}
|
||||
</a></p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.address">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.address' | translate}}</h2>
|
||||
<p><a class="core-anchor" [href]="user.encodedAddress" core-link auto-login="no">
|
||||
{{ user.address }}
|
||||
</a></p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.city && !user.address">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.city' | translate}}</h2>
|
||||
<p>{{ user.city }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.country && !user.address">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.country' | translate}}</h2>
|
||||
<p>{{ user.country }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
<ion-item-group *ngIf="hasDetails">
|
||||
<ion-item-divider>{{ 'core.userdetails' | translate}}</ion-item-divider>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.url">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.webpage' | translate}}</h2>
|
||||
<p><a class="core-anchor" href="{{user.url}}" core-link>
|
||||
{{ user.url }}
|
||||
</a></p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap" *ngIf="user.interests">
|
||||
<ion-label>
|
||||
<h2>{{ 'core.user.interests' | translate}}</h2>
|
||||
<p>{{ user.interests }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<!-- @todo <core-user-profile-field *ngFor="let field of user.customfields" [field]="field" contextLevel="course"
|
||||
[contextInstanceId]="courseId" [courseId]="courseId">
|
||||
</core-user-profile-field> -->
|
||||
</ion-item-group>
|
||||
<ion-item-group *ngIf="user.description">
|
||||
<ion-item-divider>{{ 'core.user.description' | translate}}</ion-item-divider>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<p><core-format-text [text]="user.description" contextLevel="user" [contextInstanceId]="user.id">
|
||||
</core-format-text></p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-list>
|
||||
|
||||
<core-empty-box *ngIf="!user || (!hasContact && !hasDetails && !user.description)" icon="fa-user"
|
||||
[message]=" 'core.user.detailsnotavailable' | translate">
|
||||
</core-empty-box>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -0,0 +1,47 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
import { CoreUserAboutPage } from './about.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: CoreUserAboutPage,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
],
|
||||
declarations: [
|
||||
CoreUserAboutPage,
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class CoreUserAboutPageModule {}
|
|
@ -0,0 +1,115 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { SafeUrl } from '@angular/platform-browser';
|
||||
import { IonRefresher } from '@ionic/angular';
|
||||
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreTextUtils } from '@services/utils/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
import { CoreUser, CoreUserProfile, CoreUserProfileRefreshedData, CoreUserProvider } from '@core/user/services/user';
|
||||
import { CoreUserHelper } from '@core/user/services/user.helper';
|
||||
|
||||
/**
|
||||
* Page that displays info about a user.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'page-core-user-about',
|
||||
templateUrl: 'about.html',
|
||||
})
|
||||
export class CoreUserAboutPage implements OnInit {
|
||||
|
||||
protected courseId!: number;
|
||||
protected userId!: number;
|
||||
protected siteId: string;
|
||||
|
||||
userLoaded = false;
|
||||
hasContact = false;
|
||||
hasDetails = false;
|
||||
user?: CoreUserProfile;
|
||||
title?: string;
|
||||
formattedAddress?: string;
|
||||
encodedAddress?: SafeUrl;
|
||||
|
||||
constructor(
|
||||
protected route: ActivatedRoute,
|
||||
) {
|
||||
this.siteId = CoreSites.instance.getCurrentSiteId();
|
||||
}
|
||||
|
||||
/**
|
||||
* On init.
|
||||
*
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.userId = this.route.snapshot.queryParams['userId'];
|
||||
this.courseId = this.route.snapshot.queryParams['courseId'];
|
||||
|
||||
this.fetchUser().finally(() => {
|
||||
this.userLoaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the user data.
|
||||
*
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async fetchUser(): Promise<void> {
|
||||
try {
|
||||
const user = await CoreUser.instance.getProfile(this.userId, this.courseId);
|
||||
|
||||
if (user.address) {
|
||||
this.formattedAddress = CoreUserHelper.instance.formatAddress(user.address, user.city, user.country);
|
||||
this.encodedAddress = CoreTextUtils.instance.buildAddressURL(user.address);
|
||||
}
|
||||
|
||||
this.hasContact = !!(user.email || user.phone1 || user.phone2 || user.city || user.country || user.address);
|
||||
this.hasDetails = !!(user.url || user.interests || (user.customfields && user.customfields.length > 0));
|
||||
|
||||
this.user = user;
|
||||
this.title = user.fullname;
|
||||
} catch (error) {
|
||||
CoreDomUtils.instance.showErrorModalDefault(error, 'core.user.errorloaduser', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the user data.
|
||||
*
|
||||
* @param event Event.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async refreshUser(event?: CustomEvent<IonRefresher>): Promise<void> {
|
||||
await CoreUtils.instance.ignoreErrors(CoreUser.instance.invalidateUserCache(this.userId));
|
||||
|
||||
await this.fetchUser();
|
||||
|
||||
event?.detail.complete();
|
||||
|
||||
if (this.user) {
|
||||
CoreEvents.trigger<CoreUserProfileRefreshedData>(CoreUserProvider.PROFILE_REFRESHED, {
|
||||
courseId: this.courseId,
|
||||
userId: this.userId,
|
||||
user: this.user,
|
||||
}, this.siteId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -25,6 +25,10 @@ const routes: Routes = [
|
|||
path: 'profile',
|
||||
loadChildren: () => import('./pages/profile/profile.page.module').then( m => m.CoreUserProfilePageModule),
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
loadChildren: () => import('./pages/about/about.page.module').then( m => m.CoreUserAboutPageModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -261,3 +261,9 @@ ion-select.core-button-select,
|
|||
z-index: 100;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.core-anchor, core-format-text a {
|
||||
color: -webkit-link;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue