Merge branch 'master' into julius-dev

master
trivernis 5 years ago
commit 659630d96e

13
package-lock.json generated

@ -9337,6 +9337,14 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true "dev": true
}, },
"ngx-infinite-scroll": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-8.0.1.tgz",
"integrity": "sha512-YpgkTPDNT7UCEp0GRX178V1nF+M2slCPJ2TX3CpvPZb5AR99JYwj/fNivcue5lN51oUaTySEG27qjVU73vKhjw==",
"requires": {
"opencollective-postinstall": "^2.0.2"
}
},
"ngx-socket-io": { "ngx-socket-io": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-2.1.1.tgz", "resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-2.1.1.tgz",
@ -9823,6 +9831,11 @@
"is-wsl": "^1.1.0" "is-wsl": "^1.1.0"
} }
}, },
"opencollective-postinstall": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
"integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw=="
},
"opn": { "opn": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",

@ -33,6 +33,7 @@
"graphql-tag": "^2.10.0", "graphql-tag": "^2.10.0",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"js-sha512": "^0.8.0", "js-sha512": "^0.8.0",
"ngx-infinite-scroll": "^8.0.1",
"ngx-socket-io": "^2.1.1", "ngx-socket-io": "^2.1.1",
"node-sass": "^4.13.0", "node-sass": "^4.13.0",
"rxjs": "~6.3.3", "rxjs": "~6.3.3",

@ -30,6 +30,8 @@ import { AboutComponent } from './components/about/about.component';
import { ChatcontactsComponent } from './components/chatmanager/chatcontacts/chatcontacts.component'; import { ChatcontactsComponent } from './components/chatmanager/chatcontacts/chatcontacts.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatTableModule} from '@angular/material/table'; import {MatTableModule} from '@angular/material/table';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { MatSliderModule } from '@angular/material/slider'; import { MatSliderModule } from '@angular/material/slider';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
@ -64,6 +66,7 @@ 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 {MatDatepickerModule} from '@angular/material/datepicker';
import {MatNativeDateModule} from '@angular/material/'; import {MatNativeDateModule} from '@angular/material/';
import {MatSnackBarModule} from '@angular/material/snack-bar';
// 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';
@ -114,6 +117,7 @@ const appRoutes: Routes = [
SocketIoModule.forRoot(config), SocketIoModule.forRoot(config),
GraphQLModule, GraphQLModule,
HttpClientModule, HttpClientModule,
InfiniteScrollModule,
MatDatepickerModule, MatDatepickerModule,
MatNativeDateModule, MatNativeDateModule,
RouterModule.forRoot( RouterModule.forRoot(
@ -147,7 +151,8 @@ const appRoutes: Routes = [
MatDialogModule, MatDialogModule,
MatTooltipModule, MatTooltipModule,
MatExpansionModule, MatExpansionModule,
MatDatepickerModule MatDatepickerModule,
MatSnackBarModule,
], ],
entryComponents: [ DialogCreateGroupComponent, DialogCreateEventComponent ], entryComponents: [ DialogCreateGroupComponent, DialogCreateEventComponent ],
providers: [], providers: [],

@ -1,5 +1,6 @@
<div id="about"> <div id="about">
<div id="text0" style="text-align: center;"> <div id="text0" style="text-align: center;">
<h1>Greenvironment</h1> <h1>Greenvironment</h1>
<br> <br> <br> <br> <br> <br> <br> <br> <br> <br>
<h1 class="mat-display-3">Keep it clean and green!</h1> <h1 class="mat-display-3">Keep it clean and green!</h1>
@ -9,7 +10,57 @@
</div> </div>
<div id="text1" style="text-align: center;"> <div id="text1" style="text-align: center;">
<h1>What's Greenvironment?</h1> <h1>What's Greenvironment?</h1>
<p class="mat-display-1">We, the greenviroment team want to create a network for environmentalists who care for our nature and our planet as much as we do.</p> <p>We, the greenviroment team want to create a network for environmentalists who care for our nature and our planet as much as we do.</p>
<br>
<h1>What does the level mean?</h1>
<p>There are different levels you can reach through green behaviour.
Collect 100 points to level up! The levels are called:
</p>
<table mat-table [dataSource]="levelSource" class="mat-elevation-z8">
<ng-container matColumnDef="level">
<th mat-header-cell *matHeaderCellDef> level </th>
<td mat-cell *matCellDef="let level"> {{level.level}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> level name </th>
<td mat-cell *matCellDef="let level"> {{level.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedLevelColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedLevelColumns;"></tr>
</table>
<br>
<h1>How to level up?</h1>
<p>There is an always growing list of things you can do,
to support your environment
and earn points to level up at the same time.
You can get a different amount of points
for differnet actions you can see in the list below:
</p>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="points">
<th mat-header-cell *matHeaderCellDef mat-sort-header> points </th>
<td mat-cell *matCellDef="let action"> {{action.points}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> action </th>
<td mat-cell *matCellDef="let action"> {{action.name}} </td>
</ng-container>
<!-- decriotion Column -->
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header> description </th>
<td mat-cell *matCellDef="let action"> {{action.description}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div> </div>
<div id="text2" style="text-align: center;"> <div id="text2" style="text-align: center;">
<p class="mat-display-1">We believe, that together we can do amazing things to protect our environment and keep it clean and green.</p> <p class="mat-display-1">We believe, that together we can do amazing things to protect our environment and keep it clean and green.</p>

@ -1,7 +1,5 @@
@import '../../../styles/mixins.sass' @import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
@import '~@angular/material/theming'
@import '../../../styles/greenvironment-material-theme.scss'
#about #about
position: fixed position: fixed
@ -28,3 +26,11 @@
width: 100% width: 100%
max-width: 30em max-width: 30em
margin-bottom: 1em margin-bottom: 1em
.mat-table
width: 100%
max-width: 690px
margin: 0 auto
text-align: left
.mat-header-cell
padding-right: 0.5em

@ -1,4 +1,9 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, ViewChild } from '@angular/core';
import { Activitylist } from 'src/app/models/activity';
import { Levellist } from 'src/app/models/levellist';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
import { ActivityService } from 'src/app/services/activity/activity.service';
@Component({ @Component({
selector: 'app-about', selector: 'app-about',
@ -6,10 +11,24 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./about.component.sass'] styleUrls: ['./about.component.sass']
}) })
export class AboutComponent implements OnInit { export class AboutComponent implements OnInit {
actionlist: Activitylist = new Activitylist();
levellist: Levellist = new Levellist();
constructor() { } displayedColumns = ['points', 'name', 'description'];
dataSource = new MatTableDataSource(this.actionlist.Actions);
displayedLevelColumns = ['level', 'name'];
levelSource = this.levellist.levels;
constructor(private activityService: ActivityService) { }
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() { ngOnInit() {
this.activityService.getActivitys();
this.activityService.activitylist.subscribe(response => {
this.actionlist = response;
this.dataSource = new MatTableDataSource(this.actionlist.Actions);
this.dataSource.sort = this.sort;
});
} }
} }

@ -1,4 +1,8 @@
<div id="home"> <div id="home"
infinite-scroll
[infiniteScrollDistance]="0.5"
[scrollWindow]="false"
(scrolled)="onScroll()">
<div [hidden]="!loggedIn"> <div [hidden]="!loggedIn">
<mat-card > <mat-card >
<mat-card-content> <mat-card-content>
@ -9,18 +13,18 @@
</button> </button>
</mat-form-field> </mat-form-field>
<p id="check"> <p id="check">
<mat-checkbox color="primary" [(ngModel)]="checked">I protected the environment.</mat-checkbox> <mat-checkbox color="primary" [(ngModel)]="checked" checked="checked">I protected the environment.</mat-checkbox>
</p> </p>
<mat-form-field id="action-chooser" *ngIf="checked"> <mat-form-field id="action-chooser" *ngIf="checked">
<mat-label>What did you do?</mat-label> <mat-label>What did you do?</mat-label>
<mat-select [(ngModel)]="selectedValue" name="action"> <mat-select [(ngModel)]="activityId" name="action">
<mat-option>nothing ;)</mat-option> <mat-option>nothing ;)</mat-option>
<mat-option *ngFor="let action of actionlist.Actions" [value]="action.points"> <mat-option *ngFor="let action of actionlist.Actions" [value]="action.id" [matTooltip]="action.description" matTooltipShowDelay="200">
{{action.name}} {{action.name}} ({{action.description}})
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<button mat-raised-button *ngIf="empty" color="primary" id="post-button" (click)=createPost(content)> <button mat-raised-button *ngIf="empty" color="primary" id="post-button" (click)=createPost(content,activityId)>
POST POST
</button> </button>
</mat-card-content> </mat-card-content>
@ -37,20 +41,18 @@
</div> </div>
<div id="chooser-div" style="text-align: center; margin-top: 1em;"> <div id="chooser-div" style="text-align: center; margin-top: 1em;">
<mat-button-toggle-group id="feedchooser" value="new"> <mat-button-toggle-group id="feedchooser" [(ngModel)]="view" value="view">
<mat-button-toggle (click)="showNew()" value="new">New</mat-button-toggle> <mat-button-toggle (click)="showNew()" value="new">New</mat-button-toggle>
<mat-button-toggle (click)="showMostLiked()" value="mostliked">Most Liked</mat-button-toggle> <mat-button-toggle (click)="showMostLiked()" value="mostliked">Most Liked</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div id="complete-feed"> <div id="complete-feed">
<div id="feedlist"> <div id="feedlist">
<div *ngIf = "viewNew"> <feed-postlist [childPostList]="parentSelectedPostList"></feed-postlist>
<feed-postlist (voteEvent)="refresh($event)" [childPostList]="parentSelectedPostList"></feed-postlist> <div style="height: 60px;" [hidden]='(!loadingNew && view === "new") || (!loadingMostLiked && view === "mostliked") '>
<!--<mat-spinner *ngIf='loadingNew && view === "mostLiked"' style="margin:0 auto; margin-top: 2em;" diameter="50"></mat-spinner>-->
<mat-spinner style="margin:0 auto; margin-top: 2em;" diameter="50"></mat-spinner>
</div> </div>
<div *ngIf = "viewMostLiked">
<feed-postlist (voteEvent)="refresh($event)" [childPostList]="parentSelectedPostList"></feed-postlist>
</div>
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 5em;" diameter="50"></mat-spinner>
</div> </div>
</div> </div>
</div> </div>

@ -8,6 +8,7 @@
#home #home
width: 100% width: 100%
height: 100% height: 100%
overflow-y: scroll
#complete-feed #complete-feed
box-sizing: border-box box-sizing: border-box

@ -1,8 +1,9 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Post } from 'src/app/models/post'; import { Post } from 'src/app/models/post';
import { FeedService } from 'src/app/services/feed/feed.service'; import { FeedService } from 'src/app/services/feed/feed.service';
import { Actionlist } from 'src/app/models/actionlist'; import { Activitylist } from 'src/app/models/activity';
import { DatasharingService } from '../../services/datasharing.service'; import { DatasharingService } from '../../services/datasharing.service';
import { ActivityService } from 'src/app/services/activity/activity.service';
import { User } from 'src/app/models/user'; import { User } from 'src/app/models/user';
@Component({ @Component({
@ -11,71 +12,76 @@ import { User } from 'src/app/models/user';
styleUrls: ['./feed.component.sass'] styleUrls: ['./feed.component.sass']
}) })
export class FeedComponent implements OnInit { export class FeedComponent implements OnInit {
loading = true; loadingNew = true;
checked: boolean; // if the "I protected the environment."-box is checked loadingMostLiked = true;
empty: boolean;
// points value of the green action
value: any;
viewNew = true;
viewMostLiked = false;
feedNew: Array<Post>; checked = false; // if the "I protected the environment."-box is checked
feedMostLiked: Array<Post>; view = 'new';
empty: any;
// id of the green activity
value: any;
parentSelectedPostList: Array<Post>; parentSelectedPostList: Array<Post>;
actionlist: Activitylist = new Activitylist();
actionlist: Actionlist = new Actionlist();
loggedIn = false; loggedIn = false;
userId: number;
user: User; user: User;
constructor(private feedService: FeedService, private data: DatasharingService) { } constructor(
private feedService: FeedService,
private data: DatasharingService,
private activityService: ActivityService
) { }
ngOnInit() { ngOnInit() {
this.data.currentUserInfo.subscribe(user => { this.data.currentUserInfo.subscribe(user => {
this.user = user; this.user = user;
this.loggedIn = user.loggedIn; this.loggedIn = user.loggedIn;
this.feedService.getAllPostsRaw().subscribe(response => {
this.loading = false;
this.feedNew = this.feedService.renderAllPosts(response.json());
this.parentSelectedPostList = this.feedNew;
this.feedMostLiked = this.feedNew;
});
}); });
this.activityService.getActivitys();
this.activityService.activitylist.subscribe(response => {
this.actionlist = response;
});
this.feedService.getPosts('NEW');
this.feedService.posts.subscribe(response => {
if (response.length > 0) {
// this.loading = false;
}
this.parentSelectedPostList = response;
});
this.feedService.newPostsAvailable.subscribe(response => {
this.loadingNew = response;
});
this.feedService.topPostsAvailable.subscribe(response => {
console.log(response);
this.loadingMostLiked = response;
});
} }
createPost(pElement) { createPost(pElement, activityId: string) {
this.feedService.createPost(pElement.value); if (pElement && activityId && this.checked) {
this.feedService.createPostActivity(pElement.value, activityId);
pElement.value = ''; pElement.value = '';
this.feedService.getAllPostsRaw().subscribe(response => { this.empty = '';
this.feedNew = this.feedService.renderAllPosts(response.json()); this.view = 'new';
this.parentSelectedPostList = this.feedNew; } else if (pElement) {
this.feedMostLiked = this.feedNew; }); this.feedService.createPost(pElement.value);
pElement.value = '';
this.empty = '';
this.view = 'new';
}
} }
showNew() { onScroll() {
this.feedService.getAllPostsRaw().subscribe(response => { console.log('scrolled');
this.feedNew = this.feedService.renderAllPosts(response.json()); this.feedService.getNextPosts();
this.parentSelectedPostList = this.feedNew; });
this.viewNew = true;
this.viewMostLiked = false;
} }
showMostLiked() { showNew() {
this.feedService.getAllPostsRaw().subscribe(response => { this.feedService.getPosts('NEW');
this.feedMostLiked = this.feedService.renderAllPosts(response.json());
this.parentSelectedPostList = this.feedMostLiked; });
this.viewNew = false;
this.viewMostLiked = true;
} }
showMostLiked() {
refresh($event) { this.feedService.getPosts('TOP');
this.feedService.getAllPostsRaw().subscribe(response => {
this.parentSelectedPostList = this.feedService.renderAllPosts(response.json());
});
} }
} }

@ -21,16 +21,19 @@
<mat-card class="post" *ngFor = "let post of childPostList" [class.selected]="post === selectedPost" tabindex="0"> <mat-card class="post" *ngFor = "let post of childPostList" [class.selected]="post === selectedPost" tabindex="0">
<mat-card-header> <mat-card-header>
<div id="button-box"> <div mat-card-avatar>
<button mat-icon-button [matMenuTriggerFor]="menu" id="menu-button" *ngIf="post.deletable"> <img class="profile-picture" [src]="post.author.profilePicture"/>
<mat-icon>more_vert</mat-icon> </div>
</button> <div id="button-box">
<mat-menu #menu="matMenu"> <button mat-icon-button [matMenuTriggerFor]="menu" id="menu-button" *ngIf="post.deletable">
<button mat-menu-item (click)="deletePost(post)"> <mat-icon>more_vert</mat-icon>
<span>delete post</span>
</button> </button>
</mat-menu> <mat-menu #menu="matMenu">
</div> <button mat-menu-item (click)="deletePost(post)">
<span>delete post</span>
</button>
</mat-menu>
</div>
<!-- <div mat-card-avatar class="example-header-image"></div> --> <!-- <div mat-card-avatar class="example-header-image"></div> -->
<mat-card-title> <mat-card-title>
{{post.author.name}} {{post.author.name}}
@ -56,6 +59,11 @@
<mat-icon aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">keyboard_arrow_down</mat-icon> <mat-icon aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">keyboard_arrow_down</mat-icon>
</button> </button>
{{post.downvotes}} {{post.downvotes}}
<div *ngIf="post.activity" class="activity-info">
<span class="span" [matTooltip]="post.activity.description" matTooltipShowDelay="200">
{{post.activity.points}} points earned through <b>{{post.activity.name}}</b>
</span>
</div>
</mat-card-actions> </mat-card-actions>
</mat-card> </mat-card>

@ -8,7 +8,7 @@
outline: none outline: none
user-select: none user-select: none
::ng-deep .mat-card-header-text ::ng-deep .mat-card-header-text
margin: 0px margin-top: 10px
.mat-card-subtitle .mat-card-subtitle
display: contents display: contents
a:hover a:hover
@ -20,5 +20,24 @@
max-width: 100% max-width: 100%
height: auto height: auto
border-radius: 4px border-radius: 4px
.mat-button
min-width: 32px !important
padding: 0
margin: 0
margin-left: 8px
.activity-info
display: contents
.span
margin-left: 32px
$mat-card-header-size: 100px !default
.profile-picture
height: $mat-card-header-size
width: $mat-card-header-size
border-radius: 50%
flex-shrink: 0
background-size: cover
transition-duration: 0.5s
z-index: 10
object-fit: cover

@ -49,6 +49,8 @@ $mat-card-header-size: 100px !default
border-radius: 50% border-radius: 50%
flex-shrink: 0 flex-shrink: 0
background-size: cover background-size: cover
&:hover
height: 200
// Makes `<img>` tags behave like `background-size: cover`. Not supported // Makes `<img>` tags behave like `background-size: cover`. Not supported
// in IE, but we're using it as a progressive enhancement. // in IE, but we're using it as a progressive enhancement.
object-fit: cover object-fit: cover

@ -17,7 +17,6 @@ export class HomeComponent implements OnInit {
this.data.currentUserInfo.subscribe(user => { this.data.currentUserInfo.subscribe(user => {
this.loggedIn = user.loggedIn; this.loggedIn = user.loggedIn;
}); });
this.feedService.getAllPosts();
} }
} }

@ -41,18 +41,18 @@
<mat-icon svgIcon="logo" style="min-width: 35px;" routerLink="" class="link"></mat-icon> <mat-icon svgIcon="logo" style="min-width: 35px;" routerLink="" class="link"></mat-icon>
<span routerLink="" class="link">Greenvironment</span> <span routerLink="" class="link">Greenvironment</span>
<nav mat-tab-nav-bar backgroundColor="primary" fxShow="true" fxHide.lt-md="true" routerLinkActive #rla=""> <nav mat-tab-nav-bar backgroundColor="primary" fxShow="true" fxHide.lt-md="true" routerLinkActive #rla="">
<div [hidden]="!loggedIn"> <div *ngIf="loggedIn">
<a mat-tab-link class="link" <a mat-tab-link class="link"
*ngFor="let link of navLinksLoggedIn" *ngFor="let link of navLinksLoggedIn"
[routerLink]="link.path" [routerLink]="link.path"
(click)="activeLink = link" (click)="activeLink = link"
routerLinkActive #rla="routerLinkActive" routerLinkActive #rla="routerLinkActive"
[routerLinkActiveOptions]="{exact:true}" [routerLinkActiveOptions]="{exact:true}"
[active]="activeLink == link"> [active]="rla.isActive">
{{link.label}} {{link.label}}
</a> </a>
</div> </div>
<div [hidden]="loggedIn"> <div *ngIf="!loggedIn">
<a mat-tab-link class="link" <a mat-tab-link class="link"
*ngFor="let link of navLinks" *ngFor="let link of navLinks"
[routerLink]="link.path" [routerLink]="link.path"
@ -60,7 +60,7 @@
routerLinkActive #rla="routerLinkActive" routerLinkActive #rla="routerLinkActive"
[routerLinkActiveOptions]="{exact:true}" [routerLinkActiveOptions]="{exact:true}"
[active]="rla.isActive"> [active]="rla.isActive">
{{link.label}} {{link.label}}
</a> </a>
</div> </div>
</nav> </nav>

@ -3,7 +3,15 @@
<!--on small screen--> <!--on small screen-->
<mat-toolbar color="primary" id="toolbar" fxShow="true" fxHide.gt-sm="true"> <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="hover-box" matTooltip="upload new picture" *ngIf="ownProfile" (click)="fileInput.click()">
<img class="profile-picture" [src]="userProfile.profilePicture"/>
<mat-icon id="icon">camera_alt</mat-icon>
<input #fileInput type="file" accept="image/*" (change)="onFileInput($event)" style="display:none;" />
</div>
<div *ngIf="!ownProfile">
<img class="profile-picture" [src]="userProfile.profilePicture"/>
</div>
<span id="username">{{userProfile.username}}</span> <span id="username">{{userProfile.username}}</span>
<button mat-icon-button <button mat-icon-button
class="request-button" class="request-button"
@ -37,7 +45,14 @@
<!--on big screen--> <!--on big screen-->
<mat-toolbar color="primary" id="toolbar" fxShow="true" fxHide.lt-md="true"> <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="hover-box" matTooltip="upload new picture" *ngIf="ownProfile" (click)="fileInput.click()">
<img class="profile-picture" [src]="userProfile.profilePicture"/>
<mat-icon id="icon">camera_alt</mat-icon>
<input #fileInput type="file" accept="image/*" (change)="onFileInput($event)" style="display:none;" />
</div>
<div *ngIf="!ownProfile">
<img class="profile-picture" [src]="userProfile.profilePicture"/>
</div>
<span id="username">{{userProfile.username}}</span> <span id="username">{{userProfile.username}}</span>
<span id="handle">@{{userProfile.handle}}</span> <span id="handle">@{{userProfile.handle}}</span>
<button mat-icon-button <button mat-icon-button
@ -60,50 +75,7 @@
<feed-postlist [childPostList]="this.userProfile.posts"></feed-postlist> <feed-postlist [childPostList]="this.userProfile.posts"></feed-postlist>
</div> </div>
<div id="profile"> <div id="profile">
<br>
<h1>What does the level mean?</h1>
<p>There are different levels you can reach through green behaviour.
Collect 100 points to level up! The levels are called:
</p>
<table mat-table [dataSource]="levelSource" class="mat-elevation-z8">
<ng-container matColumnDef="level">
<th mat-header-cell *matHeaderCellDef> level </th>
<td mat-cell *matCellDef="let level"> {{level.level}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> level name </th>
<td mat-cell *matCellDef="let level"> {{level.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedLevelColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedLevelColumns;"></tr>
</table>
<br>
<h1>How to level up?</h1>
<p>There is an always growing list of things you can do,
to support your environment
and earn points to level up at the same time.
You can get a different amount of points
for differnet actions you can see in the list below:
</p>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="points">
<th mat-header-cell *matHeaderCellDef mat-sort-header> points </th>
<td mat-cell *matCellDef="let action"> {{action.points}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> action </th>
<td mat-cell *matCellDef="let action"> {{action.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<!--<table style="width:100%"> <!--<table style="width:100%">
<tr> <tr>
<th>points </th> <th>points </th>

@ -39,25 +39,37 @@
#handle #handle
font-size: 14px font-size: 14px
#icon
.mat-table display: none
width: 100% position: absolute
max-width: 690px z-index: 11
margin: 0 auto color: white
.mat-header-cell
padding-right: 0.5em
$mat-card-header-size: 100px !default $mat-card-header-size: 100px !default
.hover-box
cursor: pointer
text-align: center
display: flex
justify-content: center
align-items: center
&:hover
.profile-picture
filter: brightness(70%)
#icon
display: block
filter: none
// Makes `<img>` tags behave like `background-size: cover`. Not supported
// in IE, but we're using it as a progressive enhancement.
.profile-picture .profile-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg) height: $mat-card-header-size
height: $mat-card-header-size width: $mat-card-header-size
width: $mat-card-header-size border-radius: 50%
border-radius: 50% flex-shrink: 0
flex-shrink: 0 background-size: cover
background-size: cover transition-duration: 0.5s
// Makes `<img>` tags behave like `background-size: cover`. Not supported z-index: 10
// in IE, but we're using it as a progressive enhancement. object-fit: cover
object-fit: cover

@ -1,13 +1,14 @@
import { Component, OnInit, ViewChild} from '@angular/core'; import { Component, OnInit} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router'; import {Router, NavigationEnd} from '@angular/router';
import { User } from 'src/app/models/user'; import { User } from 'src/app/models/user';
import { Actionlist } from 'src/app/models/actionlist';
import { Levellist } from 'src/app/models/levellist'; import { Levellist } from 'src/app/models/levellist';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
import { RequestService } from 'src/app/services/request/request.service'; import { RequestService } from 'src/app/services/request/request.service';
import { DatasharingService } from '../../services/datasharing.service'; import { DatasharingService } from '../../services/datasharing.service';
import { ProfileService } from 'src/app/services/profile/profile.service'; import { ProfileService } from 'src/app/services/profile/profile.service';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import {MatSnackBar} from '@angular/material/snack-bar';
import { reduce } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-profile', selector: 'app-profile',
@ -16,22 +17,19 @@ import { ProfileService } from 'src/app/services/profile/profile.service';
}) })
export class ProfileComponent implements OnInit { export class ProfileComponent implements OnInit {
actionlist: Actionlist = new Actionlist();
levellist: Levellist = new Levellist(); levellist: Levellist = new Levellist();
ownProfile = false;
userProfile: User = new User(); userProfile: User = new User();
self: User; self: User;
id: string; id: string;
rankname: string; rankname: string;
profileNotFound = false; profileNotFound = false;
displayedColumns = ['points', 'name'];
dataSource = new MatTableDataSource(this.actionlist.Actions);
displayedLevelColumns = ['level', 'name'];
levelSource = this.levellist.levels;
loading = false; loading = false;
constructor( constructor(
private http: HttpClient,
private _snackBar: MatSnackBar,
private router: Router, private router: Router,
private requestService: RequestService, private requestService: RequestService,
private data: DatasharingService, private data: DatasharingService,
@ -48,10 +46,8 @@ export class ProfileComponent implements OnInit {
}); });
} }
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() { ngOnInit() {
this.loading = true; this.loading = true;
this.dataSource.sort = this.sort;
this.id = this.router.url.substr(this.router.url.lastIndexOf('/') + 1); this.id = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
this.data.currentUserInfo.subscribe(user => { this.data.currentUserInfo.subscribe(user => {
this.self = user; this.self = user;
@ -62,6 +58,9 @@ export class ProfileComponent implements OnInit {
this.userProfile = response; this.userProfile = response;
// tslint:disable-next-line:max-line-length // tslint:disable-next-line:max-line-length
this.userProfile.allowedToSendRequest = this.requestService.isAllowedToSendRequest(this.userProfile.userID, this.self); this.userProfile.allowedToSendRequest = this.requestService.isAllowedToSendRequest(this.userProfile.userID, this.self);
if (this.userProfile.userID === this.self.userID) {
this.ownProfile = true;
} else {this.ownProfile = false; }
this.rankname = this.levellist.getLevelName(this.userProfile.level); this.rankname = this.levellist.getLevelName(this.userProfile.level);
} else { this.profileNotFound = true; } } else { this.profileNotFound = true; }
this.loading = false; this.loading = false;
@ -72,4 +71,19 @@ export class ProfileComponent implements OnInit {
user.allowedToSendRequest = false; user.allowedToSendRequest = false;
this.requestService.sendFriendRequest(user); this.requestService.sendFriendRequest(user);
} }
onFileInput(event) {
console.log(event.target.files[0]);
const formData: any = new FormData();
formData.append('profilePicture', event.target.files[0]);
this.http.post(environment.greenvironmentUrl + '/upload', formData).subscribe(
(response: any) => {
this.userProfile.profilePicture = environment.greenvironmentUrl + response.fileName;
},
(error) => {
this._snackBar.open('failed to upload picture', 'okay', {
duration: 3000
});
});
}
} }

@ -1,23 +0,0 @@
export interface Action {
id: number;
name: string;
points: number;
}
export class Actionlist {
Actions: Action[] = [
{ id: 0, name: 'collect a lot of trash', points: 25},
{ id: 1, name: 'collect a bit of trash', points: 10 },
{ id: 2, name: 'do trash seperation', points: 5 },
{ id: 3, name: 'plant a tree', points: 2 },
{ id: 4, name: 'beautify your surroundings', points: 8 },
{ id: 5, name: 'reduce waste', points: 5 },
{ id: 6, name: 'reduce CO2 emission', points: 5 },
{ id: 7, name: 'eat a vegetarian meal', points: 2 },
{ id: 8, name: 'don\'t use the car', points: 10 },
{ id: 9, name: 'buy a fair trade / local product', points: 1 },
{ id: 10, name: 'donate money to an environment organisation ', points: 10 },
];
}

@ -0,0 +1,18 @@
export class Activity {
id: number;
name: string;
description: string;
points: number;
constructor(id: number, name: string, description: string, points: number) {
this.id = id;
this.name = name;
this.description = description;
this.points = points;
}
}
export class Activitylist {
Actions: Activity[] = new Array();
}

@ -2,10 +2,12 @@ export class Author {
id: number; id: number;
name: string; name: string;
handle: string; handle: string;
profilePicture: string;
constructor(pId: number, pName: string, pHandle: string) { constructor(pId: number, pName: string, pHandle: string, pic: string) {
this.id = pId; this.id = pId;
this.name = pName; this.name = pName;
this.handle = pHandle; this.handle = pHandle;
this.profilePicture = pic;
} }
} }

@ -1,4 +1,5 @@
import { Author } from './author'; import { Author } from './author';
import { Activity } from './activity';
export class Post { export class Post {
id: number; id: number;
@ -10,6 +11,7 @@ export class Post {
userVote: string; userVote: string;
deletable: boolean; deletable: boolean;
author: Author; author: Author;
activity: Activity;
// TODO: constructor properties need normal names // TODO: constructor properties need normal names
constructor( constructor(
@ -21,7 +23,8 @@ export class Post {
pUserVote: string, pUserVote: string,
pDeletable: boolean, pDeletable: boolean,
pDate: string, pDate: string,
pAuthor: Author pAuthor: Author,
pactivity: Activity
) { ) {
this.id = pId; this.id = pId;
this.content = pContent; this.content = pContent;
@ -32,5 +35,6 @@ export class Post {
this.deletable = pDeletable; this.deletable = pDeletable;
this.date = pDate; this.date = pDate;
this.author = pAuthor; this.author = pAuthor;
this.activity = pactivity;
} }
} }

@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { ActivityService } from './activity.service';
describe('ActivityService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: ActivityService = TestBed.get(ActivityService);
expect(service).toBeTruthy();
});
});

@ -0,0 +1,53 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { Activitylist, Activity } from 'src/app/models/activity';
import { environment } from 'src/environments/environment';
import { Http } from '@angular/http';
@Injectable({
providedIn: 'root'
})
export class ActivityService {
public activitylist = new BehaviorSubject<Activitylist>(new Activitylist());
constructor(private http: Http) { }
changeUserInfo(pActivitylist: Activitylist) {
this.activitylist.next(pActivitylist);
}
public getActivitys() {
if (this.activitylist.getValue().Actions.length < 1) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.buildJson()).subscribe(result => {
// push onto subject
this.activitylist.next(this.renderActivity(result.json()));
});
}
}
public buildJson(): any {
const body = {query: `query{getActivities{
id name description points
}}`, variables: {
}};
return body;
}
public renderActivity(response: any): Activitylist {
const activitylist = new Activitylist();
for (const activity of response.data.getActivities) {
activitylist.Actions.push(new Activity(
activity.id,
activity.name,
activity.description,
activity.points));
}
return activitylist;
}
}

@ -3,29 +3,97 @@ import { Http } from '@angular/http';
import { Post } from 'src/app/models/post'; import { Post } from 'src/app/models/post';
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 { Activity } from 'src/app/models/activity';
import { BehaviorSubject } from 'rxjs';
import { User } from 'src/app/models/user';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class FeedService { export class FeedService {
posts: Array<Post>; public newPostsAvailable = new BehaviorSubject<boolean>(true);
public topPostsAvailable = new BehaviorSubject<boolean>(true);
public posts: BehaviorSubject<Post[]> = new BehaviorSubject(new Array());
public newPosts: BehaviorSubject<Post[]> = new BehaviorSubject(new Array());
public mostLikedPosts: BehaviorSubject<Post[]> = new BehaviorSubject(new Array());
private activePostList = 'NEW';
private mostLikedOffset = 0;
private newOffset = 0;
constructor(private http: Http) { } constructor(private http: Http) { }
public createPost(pContent: String) { public createPost(pContent: String) {
const url = environment.graphQLUrl;
const headers = new Headers(); const headers = new Headers();
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
const body = {query: `mutation($content: String!) { const body = {query: `mutation($content: String!) {
createPost(content: $content) {id} createPost(content: $content) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`, variables: { }`, variables: {
content: pContent content: pContent
}}; }};
return this.http.post(environment.graphQLUrl, body).subscribe(response => {
const updatedposts = this.newPosts.getValue();
updatedposts.unshift(this.renderPost(response.json()));
this.newPosts.next(updatedposts);
this.setPost('NEW');
});
}
public createPostActivity(pContent: String, activityId: String) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(url, body).subscribe(response => { const body = {query: `mutation($content: String!, $id: ID) {
}); createPost(content: $content activityId: $id) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`, variables: {
content: pContent,
id: activityId
}};
return this.http.post(environment.graphQLUrl, body).subscribe(response => {
const updatedposts = this.newPosts.getValue();
updatedposts.unshift(this.renderPost(response.json()));
this.newPosts.next(updatedposts);
this.setPost('NEW');
});
} }
public upvote(pPostID: number): any { public upvote(pPostID: number): any {
@ -71,45 +139,123 @@ export class FeedService {
return this.http.post(environment.graphQLUrl, body); return this.http.post(environment.graphQLUrl, body);
} }
public getAllPosts(): Array<Post> { public getPosts(sort: string) {
const url = environment.graphQLUrl; if ((sort === 'NEW' && this.newPosts.getValue().length === 0) ||
(sort === 'TOP' && this.mostLikedPosts.getValue().length === 0)) {
const headers = new Headers(); const headers = new Headers();
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.buildJson(sort, 0))
.subscribe(response => {
if (sort === 'NEW') {
this.newPosts.next(this.renderAllPosts(response.json()));
} else if (sort === 'TOP') {
this.mostLikedPosts.next(this.renderAllPosts(response.json()));
}
this.setPost(sort);
});
} this.setPost(sort);
}
this.http.post(url, this.getBodyForGetAllPosts()) public getNextPosts() {
.subscribe(response => { if (this.activePostList === 'NEW' && this.newPostsAvailable) {
this.posts = this.renderAllPosts(response.json()); this.newOffset += 10;
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.buildJson(this.activePostList, this.newOffset))
.subscribe(response => {
let updatedposts = this.newPosts.getValue();
updatedposts = updatedposts.concat(this.renderAllPosts(response.json()));
if (this.renderAllPosts(response.json()).length < 1) {
this.newPostsAvailable.next(false);
}
this.newPosts.next(updatedposts);
this.setPost('NEW');
});
} else if (this.activePostList === 'TOP' && this.topPostsAvailable) {
this.mostLikedOffset += 10;
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.buildJson(this.activePostList, this.mostLikedOffset))
.subscribe(response => {
let updatedposts = this.mostLikedPosts.getValue();
updatedposts = updatedposts.concat(this.renderAllPosts(response.json()));
if (this.renderAllPosts(response.json()).length < 1) {
this.topPostsAvailable.next(false);
}
this.mostLikedPosts.next(updatedposts);
this.setPost('TOP');
}); });
return this.posts; }
} }
public getAllPostsRaw(): any { setPost(sort: string) {
const headers = new Headers(); this.activePostList = sort;
headers.set('Content-Type', 'application/json'); if (sort === 'NEW') {
return this.http.post(environment.graphQLUrl, this.getBodyForGetAllPosts()); this.posts.next(this.newPosts.getValue());
} else if (sort === 'TOP') {
this.posts.next(this.mostLikedPosts.getValue());
}
} }
getBodyForGetAllPosts() { buildJson(sort: string, offset: number) {
const body = {query: `{ const body = {query: `query($offset: Int, $sort: SortType){
getPosts (first: 1000, offset: 0) { getPosts (first: 10, offset: $offset, sort: $sort) {
id, id,
content, content,
htmlContent, htmlContent,
upvotes, upvotes,
downvotes, downvotes,
userVote, userVote,
deletable deletable,
activity{
id
name
description
points
},
author{ author{
name, name,
handle, handle,
profilePicture,
id}, id},
createdAt} createdAt}
}`, variables: { }`, variables: {
offset,
sort
}}; }};
return body; return body;
} }
public renderPost(response: any): Post {
const post = response.data.createPost;
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;
let profilePicture: string;
if (post.author.profilePicture) {
profilePicture = environment.greenvironmentUrl + post.author.profilePicture;
} else {
profilePicture = 'assets/images/account_circle-24px.svg';
}
const author = new Author(post.author.id, post.author.name, post.author.handle, profilePicture);
const temp = new Date(Number(post.createdAt));
const date = temp.toLocaleString('en-GB');
let activity: Activity;
if (post.activity) {
activity = new Activity(
post.activity.id,
post.activity.name,
post.activity.description,
post.activity.points);
} else { activity = null; }
return new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author, activity);
}
public renderAllPosts(pResponse: any): Array<Post> { public renderAllPosts(pResponse: any): Array<Post> {
const posts = new Array<Post>(); const posts = new Array<Post>();
// let options = {year: 'numeric', month: 'short', day: 'numeric', hour: '' } // let options = {year: 'numeric', month: 'short', day: 'numeric', hour: '' }
@ -121,11 +267,24 @@ export class FeedService {
const downvotes: number = post.downvotes; const downvotes: number = post.downvotes;
const userVote: string = post.userVote; const userVote: string = post.userVote;
const deletable: boolean = post.deletable; const deletable: boolean = post.deletable;
const author = new Author(post.author.id, post.author.name, post.author.handle); let profilePicture: string;
if (post.author.profilePicture) {
profilePicture = environment.greenvironmentUrl + post.author.profilePicture;
} else {
profilePicture = 'assets/images/account_circle-24px.svg';
}
const author = new Author(post.author.id, post.author.name, post.author.handle, profilePicture);
const temp = new Date(Number(post.createdAt)); const temp = new Date(Number(post.createdAt));
const date = temp.toLocaleString('en-GB'); const date = temp.toLocaleString('en-GB');
let activity: Activity;
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author)); if (post.activity) {
activity = new Activity(
post.activity.id,
post.activity.name,
post.activity.description,
post.activity.points);
} else { activity = null; }
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author, activity));
} }
return posts; return posts;
} }

@ -5,6 +5,7 @@ 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 { Observable, Subject } from 'rxjs';
import { Activity } from 'src/app/models/activity';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -49,9 +50,16 @@ export class ProfileService {
downvotes, downvotes,
userVote, userVote,
deletable, deletable,
activity{
id
name
description
points
},
author{ author{
name, name,
handle, handle,
profilePicture
id}, id},
createdAt createdAt
} }
@ -74,6 +82,11 @@ export class ProfileService {
profile.level = response.data.getUser.level; profile.level = response.data.getUser.level;
profile.friendCount = response.data.getUser.friendCount; profile.friendCount = response.data.getUser.friendCount;
profile.groupCount = response.data.getUser.groupCount; profile.groupCount = response.data.getUser.groupCount;
if (response.data.getUser.profilePicture) {
profile.profilePicture = environment.greenvironmentUrl + response.data.getUser.profilePicture;
} else {
profile.profilePicture = 'assets/images/account_circle-24px.svg';
}
const temp = new Date(Number(response.data.getUser.joinedAt)); const temp = new Date(Number(response.data.getUser.joinedAt));
const date = temp.toLocaleString('en-GB'); const date = temp.toLocaleString('en-GB');
profile.joinedAt = date; profile.joinedAt = date;
@ -85,10 +98,26 @@ export class ProfileService {
const downvotes: number = post.downvotes; const downvotes: number = post.downvotes;
const userVote: string = post.userVote; const userVote: string = post.userVote;
const deletable: boolean = post.deletable; const deletable: boolean = post.deletable;
const author = new Author(post.author.id, post.author.name, post.author.handle); let profilePicture: string;
if (post.author.profilePicture) {
profilePicture = environment.greenvironmentUrl + post.author.profilePicture;
} else {
profilePicture = 'assets/images/account_circle-24px.svg';
}
const author = new Author(post.author.id, post.author.name, post.author.handle, profilePicture);
const ptemp = new Date(Number(post.createdAt)); const ptemp = new Date(Number(post.createdAt));
const pdate = ptemp.toLocaleString('en-GB'); const pdate = ptemp.toLocaleString('en-GB');
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, pdate, author)); let activity: Activity;
if (post.activity) {
activity = new Activity(
post.activity.id,
post.activity.name,
post.activity.description,
post.activity.points);
} else { activity = null; }
// tslint:disable-next-line: max-line-length
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, pdate, author, activity));
} }
profile.posts = posts; profile.posts = posts;
return profile; return profile;

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
viewBox="0 0 24 24"
version="1.1"
id="svg6"
sodipodi:docname="account_circle-24px.svg"
inkscape:version="0.92.4 5da689c313, 2019-01-14">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1000"
id="namedview8"
showgrid="false"
inkscape:zoom="19.666667"
inkscape:cx="3.495666"
inkscape:cy="8.6464111"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="Layer 1"
style="display:inline">
<path
inkscape:connector-curvature="0"
style="opacity:0.98999999;fill:#f9f9f9;fill-opacity:0.99607843"
id="path2-3"
d="m 12.160208,1.9088359 c -5.5200001,0 -9.9999991,4.4800002 -9.9999991,10.0000001 0,5.520001 4.479999,10.000001 9.9999991,10.000001 5.52,0 10.000001,-4.48 10.000001,-10.000001 0,-5.5199999 -4.480001,-10.0000001 -10.000001,-10.0000001 z"
sodipodi:nodetypes="sssss" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2"
sodipodi:insensitive="true">
<a
transform="translate(0.16020778,-0.09116412)"
id="a822">
<path
inkscape:connector-curvature="0"
style="fill:#000000;fill-opacity:1"
id="path2"
d="M 12,2 C 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22 17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 Z m 0,3 c 1.66,0 3,1.34 3,3 0,1.66 -1.34,3 -3,3 C 10.34,11 9,9.66 9,8 9,6.34 10.34,5 12,5 Z m 0,14.2 c -2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22 z" />
</a>
</g>
<path
d="M0 0h24v24H0z"
fill="none"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -1,4 +1,5 @@
export const environment = { export const environment = {
production: true, production: true,
graphQLUrl: '/graphql' graphQLUrl: '/graphql',
greenvironmentUrl: '',
}; };

@ -4,7 +4,8 @@
export const environment = { export const environment = {
production: false, production: false,
graphQLUrl: 'https://greenvironment.net/graphql' graphQLUrl: 'https://greenvironment.net/graphql',
greenvironmentUrl: 'https://greenvironment.net/',
}; };
/* /*

Loading…
Cancel
Save