Merge branch 'max_dev' of Software_Engineering_I/greenvironment-frontend into master

master
Trivernis 5 years ago committed by Gitea
commit 49aeb71ec0

@ -17,6 +17,7 @@ import { HomeComponent } from './components/home/home.component';
import { SocialComponent } from './components/social/social.component'; import { SocialComponent } from './components/social/social.component';
import { GroupsComponent } from './components/social/groups/groups.component'; import { GroupsComponent } from './components/social/groups/groups.component';
import { DialogCreateGroupComponent } from './components/social/groups/groups.component'; import { DialogCreateGroupComponent } from './components/social/groups/groups.component';
import { DialogCreateEventComponent } from './components/group/group.component';
import { ChatmanagerComponent } from './components/chatmanager/chatmanager.component'; import { ChatmanagerComponent } from './components/chatmanager/chatmanager.component';
import { ChatlistComponent } from './components/chatlist/chatlist.component'; import { ChatlistComponent } from './components/chatlist/chatlist.component';
import { PostlistComponent } from './components/feed/postlist/postlist.component'; import { PostlistComponent } from './components/feed/postlist/postlist.component';
@ -61,6 +62,8 @@ import {MatIconRegistry} from '@angular/material/icon';
import {MatDialogModule} from '@angular/material/dialog'; import {MatDialogModule} from '@angular/material/dialog';
import {MatTooltipModule} from '@angular/material/tooltip'; import {MatTooltipModule} from '@angular/material/tooltip';
import {MatExpansionModule} from '@angular/material/expansion'; import {MatExpansionModule} from '@angular/material/expansion';
import {MatDatepickerModule} from '@angular/material/datepicker';
import {MatNativeDateModule} from '@angular/material/';
// import logo from 'src/assets/gv-new-logo.svg'; // import logo from 'src/assets/gv-new-logo.svg';
import logo from '!!raw-loader!./gv-new-logo-white.svg'; import logo from '!!raw-loader!./gv-new-logo-white.svg';
@ -101,7 +104,8 @@ const appRoutes: Routes = [
MainNavigationComponent, MainNavigationComponent,
SearchComponent, SearchComponent,
DialogCreateGroupComponent, DialogCreateGroupComponent,
GroupComponent GroupComponent,
DialogCreateEventComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -110,6 +114,8 @@ const appRoutes: Routes = [
SocketIoModule.forRoot(config), SocketIoModule.forRoot(config),
GraphQLModule, GraphQLModule,
HttpClientModule, HttpClientModule,
MatDatepickerModule,
MatNativeDateModule,
RouterModule.forRoot( RouterModule.forRoot(
appRoutes appRoutes
), ),
@ -140,9 +146,10 @@ const appRoutes: Routes = [
MatProgressSpinnerModule, MatProgressSpinnerModule,
MatDialogModule, MatDialogModule,
MatTooltipModule, MatTooltipModule,
MatExpansionModule MatExpansionModule,
MatDatepickerModule
], ],
entryComponents: [ DialogCreateGroupComponent ], entryComponents: [ DialogCreateGroupComponent, DialogCreateEventComponent ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })

@ -21,12 +21,16 @@ export class PostlistComponent implements OnInit {
voteUp(pPost: Post) { voteUp(pPost: Post) {
this.feedService.upvote(pPost.id).subscribe(response => { this.feedService.upvote(pPost.id).subscribe(response => {
this.voteEvent.emit(true); }); // this.voteEvent.emit(true);
pPost.userVote = response.json().data.vote;
});
} }
voteDown(pPost: Post) { voteDown(pPost: Post) {
this.feedService.downvote(pPost.id).subscribe(response => { this.feedService.downvote(pPost.id).subscribe(response => {
this.voteEvent.emit(true); }); // this.voteEvent.emit(true);
pPost.userVote = response.json().data.vote;
});
} }
deletePost(pPost: Post) { deletePost(pPost: Post) {

@ -0,0 +1,15 @@
<h1 mat-dialog-title>Create a new event!</h1>
<div mat-dialog-content>
<mat-form-field style="display:contents;">
<input matInput placeholder="Enter eventname" #name>
</mat-form-field>
<mat-form-field style="display:contents;">
<input matInput [matDatepicker]="picker" placeholder="Choose a date" #date disabled>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker disabled="false"></mat-datepicker>
</mat-form-field>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">Cancel</button>
<button mat-button cdkFocusInitial (click)="createEvent(name.value, date.value)">Create Event</button>
</div>

@ -1,23 +1,110 @@
<div id="profile-page"> <div id="profile-page">
<div id="profilecontainer" *ngIf="!groupNotFound && !loading"> <div id="profilecontainer" *ngIf="!groupNotFound && !loading">
<mat-toolbar color="primary" id="toolbar"> <!--on small screen-->
<mat-toolbar color="primary" id="toolbar" fxShow="true" fxHide.gt-sm="true">
<mat-toolbar-row> <mat-toolbar-row>
<div class="profile-picture"></div> <div class="profile-picture"></div>
<span id="username">{{groupProfile.name}}</span> <span id="username">{{groupProfile.name}}</span>
<span id="handle">created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}}</span> <div class="button-box">
<button mat-icon-button <button mat-icon-button
class="request-button" class="request-button"
(click)="joinGroup(groupProfile)" matTooltip="join group" matTooltipShowDelay="500"
[disabled]="!groupProfile.allowedToJoinGroup"> (click)="joinGroup(groupProfile)"
<mat-icon>group_add</mat-icon> [disabled]="!groupProfile.allowedToJoinGroup">
</button> <mat-icon>group_add</mat-icon>
</button>
<button mat-icon-button
class="request-button"
matTooltip="create event" matTooltipShowDelay="500"
(click)="openDialog()"
[disabled]="!isAdmin">
<mat-icon>event</mat-icon>
</button>
</div>
</mat-toolbar-row>
<mat-toolbar-row>
<div class="info-box">
<span id="handle">created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}}</span>
</div>
</mat-toolbar-row>
<mat-toolbar-row>
<div class="info-box">
<span class="info">{{groupProfile.members.length}} member(s)</span>
</div>
</mat-toolbar-row>
</mat-toolbar>
<!--on big screen-->
<mat-toolbar color="primary" id="toolbar" fxShow="true" fxHide.lt-md="true">
<mat-toolbar-row>
<div class="profile-picture"></div>
<span id="username">{{groupProfile.name}}</span>
<span id="handle" class="pointer" (click)="showUserProfile(groupProfile.creator)">created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}}</span>
<div class="button-box">
<button mat-icon-button
class="request-button"
matTooltip="join group" matTooltipShowDelay="500"
(click)="joinGroup(groupProfile)"
[disabled]="!groupProfile.allowedToJoinGroup">
<mat-icon>group_add</mat-icon>
</button>
<button mat-icon-button
class="request-button"
matTooltip="create event" matTooltipShowDelay="500"
(click)="openDialog()"
[disabled]="!isAdmin">
<mat-icon>event</mat-icon>
</button>
</div>
</mat-toolbar-row> </mat-toolbar-row>
<mat-toolbar-row> <mat-toolbar-row>
<div id="info-box"> <div class="info-box">
<span class="info">{{groupProfile.members.length}} member(s)</span> <span class="info">{{groupProfile.members.length}} member(s)</span>
</div> </div>
</mat-toolbar-row> </mat-toolbar-row>
</mat-toolbar> </mat-toolbar>
<mat-accordion>
<mat-expansion-panel *ngIf="groupProfile.events.length > 0" expanded>
<mat-expansion-panel-header>
<mat-panel-title>
Events
</mat-panel-title>
</mat-expansion-panel-header>
<div class="list">
<mat-card class="card" *ngFor="let event of groupProfile.events"
[class.selected]="event === selectedEvent"
tabindex="0">
<mat-card-header>
<mat-card-title>{{event.name}}</mat-card-title>
<mat-card-subtitle >{{event.date}}</mat-card-subtitle>
<!--<div class="icon-box">
<button mat-icon-button class="request-button" (click)="sendFriendRequest(user)" [disabled]="!user.allowedToSendRequest"><mat-icon>person_add</mat-icon></button>
</div>-->
</mat-card-header>
</mat-card>
</div>
</mat-expansion-panel>
<mat-expansion-panel [expanded]="groupProfile.events.length < 1">
<mat-expansion-panel-header>
<mat-panel-title>
Members
</mat-panel-title>
</mat-expansion-panel-header>
<div class="list">
<mat-card class="card" *ngFor="let user of groupProfile.members"
[class.selected]="user === selectedUser"
tabindex="0">
<mat-card-header>
<div mat-card-avatar class="profile-picture" (click)="showUserProfile(user)"></div>
<mat-card-title class="pointer" (click)="showUserProfile(user)">{{user.username}}</mat-card-title>
<mat-card-subtitle class="pointer" (click)="showUserProfile(user)">{{user.handle}}</mat-card-subtitle>
<div class="icon-box">
<button mat-icon-button class="request-button" (click)="sendFriendRequest(user)" [disabled]="!user.allowedToSendRequest"><mat-icon>person_add</mat-icon></button>
</div>
</mat-card-header>
</mat-card>
</div>
</mat-expansion-panel>
</mat-accordion>
</div> </div>
<div id="profilecontainer" *ngIf="groupNotFound"> <div id="profilecontainer" *ngIf="groupNotFound">
<h1>Group not found :(</h1> <h1>Group not found :(</h1>

@ -6,12 +6,14 @@
width: 100% width: 100%
height: calc(100% - 56px) height: calc(100% - 56px)
overflow: scroll overflow: scroll
overflow-x: hidden
#profile #profile
padding: 2em padding: 2em
max-width: 1200px max-width: 1200px
margin: 0 auto margin: 0 auto
$mat-card-header-size: 100px !default
#profile-card-container #profile-card-container
margin: 0 auto margin: 0 auto
width: 100% width: 100%
@ -19,15 +21,16 @@
.icon-box .icon-box
text-align: right text-align: right
width: 100% width: 100%
.button-box
width: 100%
text-align: right
.request-button .request-button
margin-top: 0.5em margin: auto 0
margin-bottom: 0.5em
margin-left: auto
#toolbar #toolbar
margin-top: 32px margin-top: 32px
.mat-toolbar-row .mat-toolbar-row
max-height: 40px max-height: 40px
#info-box .info-box
font-size: 14px font-size: 14px
margin-left: calc(100px + 0.5em) margin-left: calc(100px + 0.5em)
.info .info
@ -36,30 +39,45 @@
margin: 0 0.5em margin: 0 0.5em
#handle #handle
font-size: 14px font-size: 14px
.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
.card
.mat-table box-sizing: border-box
width: 100% width: 100%
max-width: 690px margin-top: 0.5em
margin: 0 auto outline: none
.mat-header-cell user-select: none
padding-right: 0.5em /deep/ .mat-card-header-text
width: 1000%
$mat-card-header-size: 100px !default margin: 0
.profile-picture margin-left: 16px
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg) .mat-card-subtitle
height: $mat-card-header-size margin: 0
width: $mat-card-header-size word-break: break-all
border-radius: 50% .mat-card-title
flex-shrink: 0 margin: 0
background-size: cover word-break: break-all
// Makes `<img>` tags behave like `background-size: cover`. Not supported .request-button
// in IE, but we're using it as a progressive enhancement. margin-top: 0.5em
object-fit: cover margin-bottom: 0.5em
.profile-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
background-size: cover
#postlist .profile-picture:hover
margin: 0.5em auto cursor: pointer
padding: 0 .pointer
max-width: 690px cursor: pointer
/deep/ .mat-expansion-panel
background: #e6e6e6
/deep/.dark-theme .mat-expansion-panel
background: #121212

@ -6,7 +6,38 @@ import { RequestService } from 'src/app/services/request/request.service';
import { DatasharingService } from '../../services/datasharing.service'; import { DatasharingService } from '../../services/datasharing.service';
import { GroupService } from 'src/app/services/group/group.service'; import { GroupService } from 'src/app/services/group/group.service';
import { Group } from 'src/app/models/group'; import { Group } from 'src/app/models/group';
import {MatDialog, MatDialogRef} from '@angular/material/dialog';
// DIALOG COMPONENT to create events
@Component({
selector: 'dialog-overview-example-dialog',
templateUrl: 'dialog.html',
})
export class DialogCreateEventComponent {
groupId: string;
constructor(
public dialogRef: MatDialogRef<DialogCreateEventComponent>,
private group: GroupService,
private router: Router) {
this.groupId = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
}
onNoClick(): void {
this.dialogRef.close();
}
createEvent(name: string, date: string) {
name = name.trim();
if (name && date) {
this.group.createEvent(name, (new Date(date)).getTime().toString(), this.groupId);
this.dialogRef.close();
}
}
}
// GROUP COMPONENT
@Component({ @Component({
selector: 'app-profile', selector: 'app-profile',
templateUrl: './group.component.html', templateUrl: './group.component.html',
@ -17,12 +48,14 @@ export class GroupComponent implements OnInit {
groupProfile: Group = new Group(); groupProfile: Group = new Group();
self: User; self: User;
id: string; id: string;
isAdmin = false;
groupNotFound = false; groupNotFound = false;
loading = false; loading = false;
constructor( constructor(
private router: Router, private router: Router,
public dialog: MatDialog,
private requestService: RequestService, private requestService: RequestService,
private data: DatasharingService, private data: DatasharingService,
private groupService: GroupService) { private groupService: GroupService) {
@ -48,17 +81,41 @@ export class GroupComponent implements OnInit {
}); });
this.groupService.getGroupData(this.id); this.groupService.getGroupData(this.id);
this.groupService.group.subscribe(response => { this.groupService.group.subscribe(response => {
if (response) { this.isAdmin = false;
this.groupProfile = response; if (response) {
// tslint:disable-next-line:max-line-length this.groupProfile = response;
this.groupProfile.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(this.groupProfile.id, this.self); // tslint:disable-next-line:max-line-length
} else { this.groupNotFound = true; } this.groupProfile.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(this.groupProfile.id, this.self);
this.loading = false; for (const admin of this.groupProfile.admins) {
}); if (admin.userID === this.self.userID) {
this.isAdmin = true;
}
}
for (const member of this.groupProfile.members) {
member.allowedToSendRequest = this.requestService.isAllowedToSendRequest(member.userID, this.self);
}
} else { this.groupNotFound = true; }
this.loading = false;
});
}
openDialog(): void {
const dialogRef = this.dialog.open(DialogCreateEventComponent, {
width: '250px'
});
} }
public joinGroup(group: Group) { public joinGroup(group: Group) {
group.allowedToJoinGroup = false; group.allowedToJoinGroup = false;
this.requestService.joinGroup(group); this.requestService.joinGroup(group);
} }
public showUserProfile(user: User) {
this.router.navigate(['profile/' + user.userID]);
}
public sendFriendRequest(user: User) {
user.allowedToSendRequest = false;
this.requestService.sendFriendRequest(user);
}
} }

@ -1,6 +1,41 @@
<div id="profile-page"> <div id="profile-page">
<div id="profilecontainer" *ngIf="!profileNotFound && !loading"> <div id="profilecontainer" *ngIf="!profileNotFound && !loading">
<mat-toolbar color="primary" id="toolbar"> <!--on small screen-->
<mat-toolbar color="primary" id="toolbar" fxShow="true" fxHide.gt-sm="true">
<mat-toolbar-row>
<div class="profile-picture"></div>
<span id="username">{{userProfile.username}}</span>
<button mat-icon-button
class="request-button"
(click)="sendFriendRequest(userProfile)"
[disabled]="!userProfile.allowedToSendRequest">
<mat-icon>person_add</mat-icon>
</button>
</mat-toolbar-row>
<mat-toolbar-row>
<div class="info-box">
<span id="handle">@{{userProfile.handle}}</span>
</div>
</mat-toolbar-row>
<mat-toolbar-row>
<div>
<span class="info">{{rankname}} ({{userProfile.points}} points)</span>
</div>
</mat-toolbar-row>
<mat-toolbar-row>
<div>
<span class="info">{{userProfile.friendCount}} friends</span>
<span class="info">{{userProfile.groupCount}} groups</span>
</div>
</mat-toolbar-row>
<mat-toolbar-row>
<div>
<span class="info">joined on {{userProfile.joinedAt}}</span>
</div>
</mat-toolbar-row>
</mat-toolbar>
<!--on big screen-->
<mat-toolbar color="primary" id="toolbar" fxShow="true" fxHide.lt-md="true">
<mat-toolbar-row> <mat-toolbar-row>
<div class="profile-picture"></div> <div class="profile-picture"></div>
<span id="username">{{userProfile.username}}</span> <span id="username">{{userProfile.username}}</span>
@ -13,7 +48,7 @@
</button> </button>
</mat-toolbar-row> </mat-toolbar-row>
<mat-toolbar-row> <mat-toolbar-row>
<div id="info-box"> <div class="info-box">
<span class="info">{{rankname}} ({{userProfile.points}} points)</span> <span class="info">{{rankname}} ({{userProfile.points}} points)</span>
<span class="info">{{userProfile.friendCount}} friends</span> <span class="info">{{userProfile.friendCount}} friends</span>
<span class="info">{{userProfile.groupCount}} groups</span> <span class="info">{{userProfile.groupCount}} groups</span>

@ -6,6 +6,7 @@
width: 100% width: 100%
height: calc(100% - 56px) height: calc(100% - 56px)
overflow: scroll overflow: scroll
overflow-x: hidden
#profile #profile
padding: 2em padding: 2em
@ -27,11 +28,12 @@
margin-top: 32px margin-top: 32px
.mat-toolbar-row .mat-toolbar-row
max-height: 40px max-height: 40px
#info-box .info-box
font-size: 14px font-size: 14px
margin-left: calc(100px + 0.5em) margin-left: calc(100px + 0.5em)
.info .info
margin-right: 3em margin-right: 1em
font-size: 14px
#username #username
margin: 0 0.5em margin: 0 0.5em
#handle #handle

@ -0,0 +1,11 @@
export class Event {
id: number;
name: string;
date: string;
constructor(pId: number, pName: string, pdate: string) {
this.id = pId;
this.name = pName;
this.date = pdate;
}
}

@ -1,4 +1,5 @@
import { User } from 'src/app/models/user'; import { User } from 'src/app/models/user';
import { Event } from 'src/app/models/event';
export class Group { export class Group {
id: number; id: number;
@ -7,5 +8,6 @@ export class Group {
creator: User = new User(); creator: User = new User();
members: User[] = new Array(); members: User[] = new Array();
admins: User[] = new Array(); admins: User[] = new Array();
events: Event[] = new Array();
allowedToJoinGroup = false; allowedToJoinGroup = false;
} }

@ -3,7 +3,8 @@ import { Http } from '@angular/http';
import { Author } from 'src/app/models/author'; import { Author } from 'src/app/models/author';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { User } from 'src/app/models/user'; import { User } from 'src/app/models/user';
import { Observable, Subject } from 'rxjs'; import { Event } from 'src/app/models/event';
import { Observable, BehaviorSubject } from 'rxjs';
import { Group } from 'src/app/models/group'; import { Group } from 'src/app/models/group';
@Injectable({ @Injectable({
@ -11,7 +12,7 @@ import { Group } from 'src/app/models/group';
}) })
export class GroupService { export class GroupService {
public group: Subject<any> = new Subject(); public group: BehaviorSubject<Group> = new BehaviorSubject(new Group());
constructor(private http: Http) { } constructor(private http: Http) { }
@ -34,6 +35,7 @@ export class GroupService {
creator{id name handle} creator{id name handle}
admins{id name handle} admins{id name handle}
members{id name handle} members{id name handle}
events{id name dueDate}
} }
}`, variables: { }`, variables: {
groupId: id groupId: id
@ -44,8 +46,6 @@ export class GroupService {
public renderGroup(response: any): Group { public renderGroup(response: any): Group {
const group = new Group(); const group = new Group();
const members: User[] = new Array();
const admins: User[] = new Array();
if (response.data.getGroup != null) { if (response.data.getGroup != null) {
group.id = response.data.getGroup.id; group.id = response.data.getGroup.id;
group.name = response.data.getGroup.name; group.name = response.data.getGroup.name;
@ -57,19 +57,45 @@ export class GroupService {
user.userID = member.id; user.userID = member.id;
user.username = member.name; user.username = member.name;
user.handle = member.handle; user.handle = member.handle;
members.push(user); group.members.push(user);
} }
group.members = members;
for (const admin of response.data.getGroup.admins) { for (const admin of response.data.getGroup.admins) {
const user = new User(); const user = new User();
user.userID = admin.id; user.userID = admin.id;
user.username = admin.name; user.username = admin.name;
user.handle = admin.handle; user.handle = admin.handle;
admins.push(user); group.admins.push(user);
}
for (const event of response.data.getGroup.events) {
const temp = new Date(Number(event.dueDate));
const date = temp.toLocaleString('en-GB');
group.events.push(new Event(event.id, event.name, date));
} }
group.admins = admins;
return group; return group;
} }
return null; return null;
} }
public createEvent(name: string, date: string, groupId: string) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
const body = {query: `mutation($groupId: ID!, $name: String, $date: String) {
createEvent(name: $name, dueDate: $date, groupId: $groupId) {
id
name
dueDate
}
}`, variables: {
name: name,
date: date,
groupId: groupId
}};
this.http.post(environment.graphQLUrl, body).subscribe(response => {
const event = response.json().data.createEvent;
const temp = new Date(Number(event.dueDate));
const pdate = temp.toLocaleString('en-GB');
this.group.next(this.renderGroup(this.group.getValue().events.push(new Event(event.id, event.name, pdate))));
});
}
} }

Loading…
Cancel
Save