Merge branch 'max_dev' of Software_Engineering_I/greenvironment-frontend into master
commit
1964aae1ea
@ -0,0 +1,28 @@
|
|||||||
|
<div id="profile-page">
|
||||||
|
<div id="profilecontainer" *ngIf="!groupNotFound && !loading">
|
||||||
|
<mat-toolbar color="primary" id="toolbar">
|
||||||
|
<mat-toolbar-row>
|
||||||
|
<div class="profile-picture"></div>
|
||||||
|
<span id="username">{{groupProfile.name}}</span>
|
||||||
|
<span id="handle">created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}}</span>
|
||||||
|
<button mat-icon-button
|
||||||
|
class="request-button"
|
||||||
|
(click)="joinGroup(groupProfile)"
|
||||||
|
[disabled]="!groupProfile.allowedToJoinGroup">
|
||||||
|
<mat-icon>group_add</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-toolbar-row>
|
||||||
|
<mat-toolbar-row>
|
||||||
|
<div id="info-box">
|
||||||
|
<span class="info">{{groupProfile.members.length}} member(s)</span>
|
||||||
|
</div>
|
||||||
|
</mat-toolbar-row>
|
||||||
|
</mat-toolbar>
|
||||||
|
</div>
|
||||||
|
<div id="profilecontainer" *ngIf="groupNotFound">
|
||||||
|
<h1>Group not found :(</h1>
|
||||||
|
</div>
|
||||||
|
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 10em;" diameter="100"></mat-spinner>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
@import '../../../styles/mixins.sass'
|
||||||
|
@import '../../../styles/vars.sass'
|
||||||
|
|
||||||
|
#profile-page
|
||||||
|
position: fixed
|
||||||
|
width: 100%
|
||||||
|
height: calc(100% - 56px)
|
||||||
|
overflow: scroll
|
||||||
|
|
||||||
|
#profile
|
||||||
|
padding: 2em
|
||||||
|
max-width: 1200px
|
||||||
|
margin: 0 auto
|
||||||
|
|
||||||
|
#profile-card-container
|
||||||
|
margin: 0 auto
|
||||||
|
width: 100%
|
||||||
|
max-width: 690px
|
||||||
|
.icon-box
|
||||||
|
text-align: right
|
||||||
|
width: 100%
|
||||||
|
.request-button
|
||||||
|
margin-top: 0.5em
|
||||||
|
margin-bottom: 0.5em
|
||||||
|
margin-left: auto
|
||||||
|
#toolbar
|
||||||
|
margin-top: 32px
|
||||||
|
.mat-toolbar-row
|
||||||
|
max-height: 40px
|
||||||
|
#info-box
|
||||||
|
font-size: 14px
|
||||||
|
margin-left: calc(100px + 0.5em)
|
||||||
|
.info
|
||||||
|
margin-right: 3em
|
||||||
|
#username
|
||||||
|
margin: 0 0.5em
|
||||||
|
#handle
|
||||||
|
font-size: 14px
|
||||||
|
|
||||||
|
|
||||||
|
.mat-table
|
||||||
|
width: 100%
|
||||||
|
max-width: 690px
|
||||||
|
margin: 0 auto
|
||||||
|
.mat-header-cell
|
||||||
|
padding-right: 0.5em
|
||||||
|
|
||||||
|
$mat-card-header-size: 100px !default
|
||||||
|
.profile-picture
|
||||||
|
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
|
||||||
|
height: $mat-card-header-size
|
||||||
|
width: $mat-card-header-size
|
||||||
|
border-radius: 50%
|
||||||
|
flex-shrink: 0
|
||||||
|
background-size: cover
|
||||||
|
// Makes `<img>` tags behave like `background-size: cover`. Not supported
|
||||||
|
// in IE, but we're using it as a progressive enhancement.
|
||||||
|
object-fit: cover
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#postlist
|
||||||
|
margin: 0.5em auto
|
||||||
|
padding: 0
|
||||||
|
max-width: 690px
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GroupComponent } from './group.component';
|
||||||
|
|
||||||
|
describe('GroupComponent', () => {
|
||||||
|
let component: GroupComponent;
|
||||||
|
let fixture: ComponentFixture<GroupComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ GroupComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(GroupComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,64 @@
|
|||||||
|
import { Component, OnInit, ViewChild} from '@angular/core';
|
||||||
|
import {Router, NavigationEnd} from '@angular/router';
|
||||||
|
import { User } from 'src/app/models/user';
|
||||||
|
import {MatSort} from '@angular/material/sort';
|
||||||
|
import { RequestService } from 'src/app/services/request/request.service';
|
||||||
|
import { DatasharingService } from '../../services/datasharing.service';
|
||||||
|
import { GroupService } from 'src/app/services/group/group.service';
|
||||||
|
import { Group } from 'src/app/models/group';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-profile',
|
||||||
|
templateUrl: './group.component.html',
|
||||||
|
styleUrls: ['./group.component.sass']
|
||||||
|
})
|
||||||
|
|
||||||
|
export class GroupComponent implements OnInit {
|
||||||
|
groupProfile: Group = new Group();
|
||||||
|
self: User;
|
||||||
|
id: string;
|
||||||
|
groupNotFound = false;
|
||||||
|
|
||||||
|
loading = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private requestService: RequestService,
|
||||||
|
private data: DatasharingService,
|
||||||
|
private groupService: GroupService) {
|
||||||
|
router.events.forEach((event) => {
|
||||||
|
// check if url changes
|
||||||
|
if (event instanceof NavigationEnd) {
|
||||||
|
const possibleID = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
|
||||||
|
if (this.id !== possibleID && this.id && this.router.url.includes('group/')) {
|
||||||
|
// reload the group
|
||||||
|
console.log('search for group id: ' + this.router.url.substr(this.router.url.lastIndexOf('/') + 1));
|
||||||
|
this.ngOnInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewChild(MatSort, {static: true}) sort: MatSort;
|
||||||
|
ngOnInit() {
|
||||||
|
this.loading = true;
|
||||||
|
this.id = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
|
||||||
|
this.data.currentUserInfo.subscribe(user => {
|
||||||
|
this.self = user;
|
||||||
|
});
|
||||||
|
this.groupService.getGroupData(this.id);
|
||||||
|
this.groupService.group.subscribe(response => {
|
||||||
|
if (response) {
|
||||||
|
this.groupProfile = response;
|
||||||
|
// tslint:disable-next-line:max-line-length
|
||||||
|
this.groupProfile.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(this.groupProfile.id, this.self);
|
||||||
|
} else { this.groupNotFound = true; }
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public joinGroup(group: Group) {
|
||||||
|
group.allowedToJoinGroup = false;
|
||||||
|
this.requestService.joinGroup(group);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import { User } from 'src/app/models/user';
|
||||||
|
|
||||||
|
export class Group {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
handle: string;
|
||||||
|
creator: User = new User();
|
||||||
|
members: User[] = new Array();
|
||||||
|
admins: User[] = new Array();
|
||||||
|
allowedToJoinGroup = false;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GroupService } from './group.service';
|
||||||
|
|
||||||
|
describe('GroupService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: GroupService = TestBed.get(GroupService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,75 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Http } from '@angular/http';
|
||||||
|
import { Author } from 'src/app/models/author';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
import { User } from 'src/app/models/user';
|
||||||
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
import { Group } from 'src/app/models/group';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class GroupService {
|
||||||
|
|
||||||
|
public group: Subject<any> = new Subject();
|
||||||
|
|
||||||
|
constructor(private http: Http) { }
|
||||||
|
|
||||||
|
public getGroupData(groupId: string) {
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set('Content-Type', 'application/json');
|
||||||
|
this.http.post(environment.graphQLUrl, this.buildGetGroupJson(groupId)).subscribe(result => {
|
||||||
|
// push onto subject
|
||||||
|
this.group.next(this.renderGroup(result.json()));
|
||||||
|
return this.group;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public buildGetGroupJson(id: string): any {
|
||||||
|
const body = {
|
||||||
|
query: `query($groupId: ID!) {
|
||||||
|
getGroup(groupId:$groupId){
|
||||||
|
id
|
||||||
|
name
|
||||||
|
creator{id name handle}
|
||||||
|
admins{id name handle}
|
||||||
|
members{id name handle}
|
||||||
|
}
|
||||||
|
}`, variables: {
|
||||||
|
groupId: id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public renderGroup(response: any): Group {
|
||||||
|
const group = new Group();
|
||||||
|
const members: User[] = new Array();
|
||||||
|
const admins: User[] = new Array();
|
||||||
|
if (response.data.getGroup != null) {
|
||||||
|
group.id = response.data.getGroup.id;
|
||||||
|
group.name = response.data.getGroup.name;
|
||||||
|
group.creator.userID = response.data.getGroup.creator.id;
|
||||||
|
group.creator.handle = response.data.getGroup.creator.handle;
|
||||||
|
group.creator.username = response.data.getGroup.creator.name;
|
||||||
|
for (const member of response.data.getGroup.members) {
|
||||||
|
const user = new User();
|
||||||
|
user.userID = member.id;
|
||||||
|
user.username = member.name;
|
||||||
|
user.handle = member.handle;
|
||||||
|
members.push(user);
|
||||||
|
}
|
||||||
|
group.members = members;
|
||||||
|
for (const admin of response.data.getGroup.admins) {
|
||||||
|
const user = new User();
|
||||||
|
user.userID = admin.id;
|
||||||
|
user.username = admin.name;
|
||||||
|
user.handle = admin.handle;
|
||||||
|
admins.push(user);
|
||||||
|
}
|
||||||
|
group.admins = admins;
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ProfileService } from './profile.service';
|
||||||
|
|
||||||
|
describe('ProfileService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: ProfileService = TestBed.get(ProfileService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,145 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Http } from '@angular/http';
|
||||||
|
import { Post } from 'src/app/models/post';
|
||||||
|
import { Author } from 'src/app/models/author';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
import { User } from 'src/app/models/user';
|
||||||
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ProfileService {
|
||||||
|
|
||||||
|
public proflile: Subject<any> = new Subject();
|
||||||
|
|
||||||
|
constructor(private http: Http) { }
|
||||||
|
|
||||||
|
public getUserData(userId: string) {
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set('Content-Type', 'application/json');
|
||||||
|
// return this.renderProfile(this.http.post(environment.graphQLUrl, this.buildGetProfileJson(userId)));
|
||||||
|
this.http.post(environment.graphQLUrl, this.buildGetProfileJson(userId)).subscribe(result => {
|
||||||
|
// push onto subject
|
||||||
|
this.proflile.next(this.renderProfile(result.json()));
|
||||||
|
return this.proflile;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserDataBySelfId(userId: string, selfId: string) {
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set('Content-Type', 'application/json');
|
||||||
|
// return this.renderProfile(this.http.post(environment.graphQLUrl, this.buildGetProfileJson(userId)));
|
||||||
|
this.http.post(environment.graphQLUrl, this.buildGetProfileJsonBySelfId(userId, selfId)).subscribe(result => {
|
||||||
|
// push onto subject
|
||||||
|
this.proflile.next(this.renderProfile(result.json()));
|
||||||
|
return this.proflile;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public buildGetProfileJson(id: string): any {
|
||||||
|
const body = {query: `query($userId: ID) {
|
||||||
|
getUser(userId:$userId){
|
||||||
|
id
|
||||||
|
handle
|
||||||
|
name
|
||||||
|
profilePicture
|
||||||
|
points
|
||||||
|
level
|
||||||
|
friendCount
|
||||||
|
groupCount
|
||||||
|
joinedAt
|
||||||
|
friends{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
posts{
|
||||||
|
id,
|
||||||
|
content,
|
||||||
|
htmlContent,
|
||||||
|
upvotes,
|
||||||
|
downvotes,
|
||||||
|
author{
|
||||||
|
name,
|
||||||
|
handle,
|
||||||
|
id},
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, variables: {
|
||||||
|
userId: id
|
||||||
|
}};
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public buildGetProfileJsonBySelfId(id: string, selfId: string): any {
|
||||||
|
const body = {query: `query($userId: ID, $selfId: ID!) {
|
||||||
|
getUser(userId:$userId){
|
||||||
|
id
|
||||||
|
handle
|
||||||
|
name
|
||||||
|
profilePicture
|
||||||
|
points
|
||||||
|
level
|
||||||
|
friendCount
|
||||||
|
groupCount
|
||||||
|
joinedAt
|
||||||
|
friends{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
posts{
|
||||||
|
id,
|
||||||
|
content,
|
||||||
|
htmlContent,
|
||||||
|
upvotes,
|
||||||
|
downvotes,
|
||||||
|
userVote(userId: $selfId),
|
||||||
|
deletable(userId: $selfId)
|
||||||
|
author{
|
||||||
|
name,
|
||||||
|
handle,
|
||||||
|
id},
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, variables: {
|
||||||
|
userId: id,
|
||||||
|
selfId: selfId
|
||||||
|
}};
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public renderProfile(response: any): User {
|
||||||
|
const posts = new Array<Post>();
|
||||||
|
const profile = new User();
|
||||||
|
if (response.data.getUser != null) {
|
||||||
|
|
||||||
|
profile.userID = response.data.getUser.id;
|
||||||
|
profile.username = response.data.getUser.name;
|
||||||
|
profile.handle = response.data.getUser.handle;
|
||||||
|
profile.points = response.data.getUser.points;
|
||||||
|
profile.level = response.data.getUser.level;
|
||||||
|
profile.friendCount = response.data.getUser.friendCount;
|
||||||
|
profile.groupCount = response.data.getUser.groupCount;
|
||||||
|
const temp = new Date(Number(response.data.getUser.joinedAt));
|
||||||
|
const date = temp.toLocaleString('en-GB');
|
||||||
|
profile.joinedAt = date;
|
||||||
|
for (const post of response.data.getUser.posts) {
|
||||||
|
const id: number = post.id;
|
||||||
|
const content: string = post.content;
|
||||||
|
const htmlContent: string = post.htmlContent;
|
||||||
|
const upvotes: number = post.upvotes;
|
||||||
|
const downvotes: number = post.downvotes;
|
||||||
|
const userVote: string = post.userVote;
|
||||||
|
const deletable: boolean = post.deletable;
|
||||||
|
const author = new Author(post.author.id, post.author.name, post.author.handle);
|
||||||
|
const ptemp = new Date(Number(post.createdAt));
|
||||||
|
const pdate = ptemp.toLocaleString('en-GB');
|
||||||
|
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, pdate, author));
|
||||||
|
}
|
||||||
|
profile.posts = posts;
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue