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

master
Julius 5 years ago committed by Gitea
commit e93d07f5a6

@ -27,6 +27,7 @@
"src/assets" "src/assets"
], ],
"styles": [ "styles": [
"src/styles/greenvironment-material-theme.scss",
"src/styles.sass" "src/styles.sass"
], ],
"scripts": [] "scripts": []
@ -83,6 +84,7 @@
"tsConfig": "src/tsconfig.spec.json", "tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js", "karmaConfig": "src/karma.conf.js",
"styles": [ "styles": [
"src/styles/greenvironment-material-theme.scss",
"src/styles.sass" "src/styles.sass"
], ],
"scripts": [], "scripts": [],

8350
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -11,17 +11,18 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular-devkit/build-angular": "^0.13.0", "@angular/animations": "^8.2.14",
"@angular/animations": "~7.0.0", "@angular/cdk": "8.2.3",
"@angular/cdk": "^7.0.3", "@angular/common": "~8.2.14",
"@angular/common": "~7.0.0", "@angular/compiler": "~8.2.14",
"@angular/compiler": "~7.0.0", "@angular/core": "^8.2.14",
"@angular/core": "^7.0.4", "@angular/flex-layout": "^8.0.0-beta.27",
"@angular/forms": "~7.0.0", "@angular/forms": "~7.0.0",
"@angular/http": "~7.0.0", "@angular/http": "~7.0.0",
"@angular/platform-browser": "~7.0.0", "@angular/material": "^8.2.3",
"@angular/platform-browser-dynamic": "~7.0.0", "@angular/platform-browser": "8.2.14",
"@angular/router": "~7.0.0", "@angular/platform-browser-dynamic": "^8.2.14",
"@angular/router": "~8.2.14",
"apollo-angular": "^1.7.0", "apollo-angular": "^1.7.0",
"apollo-angular-link-http": "^1.6.0", "apollo-angular-link-http": "^1.6.0",
"apollo-cache-inmemory": "^1.3.2", "apollo-cache-inmemory": "^1.3.2",
@ -30,15 +31,18 @@
"core-js": "^2.5.4", "core-js": "^2.5.4",
"graphql": "^14.3.1", "graphql": "^14.3.1",
"graphql-tag": "^2.10.0", "graphql-tag": "^2.10.0",
"hammerjs": "^2.0.8",
"js-sha512": "^0.8.0", "js-sha512": "^0.8.0",
"ngx-socket-io": "^2.0.0", "ngx-socket-io": "^2.0.0",
"node-sass": "^4.13.0",
"rxjs": "~6.3.3", "rxjs": "~6.3.3",
"ts-md5": "^1.2.7", "ts-md5": "^1.2.7",
"zone.js": "~0.8.26" "zone.js": "~0.8.26"
}, },
"devDependencies": { "devDependencies": {
"@angular/cli": "~7.0.4", "@angular-devkit/build-angular": "^0.803.20",
"@angular/compiler-cli": "~7.0.0", "@angular/cli": "^8.3.20",
"@angular/compiler-cli": "^8.2.14",
"@angular/language-service": "~7.0.0", "@angular/language-service": "~7.0.0",
"@types/jasmine": "~2.8.8", "@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3", "@types/jasminewd2": "~2.0.3",
@ -46,7 +50,7 @@
"codelyzer": "~4.5.0", "codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1", "jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1", "jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0", "karma": "^4.4.1",
"karma-chrome-launcher": "~2.2.0", "karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1", "karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2", "karma-jasmine": "~1.1.2",
@ -54,6 +58,6 @@
"protractor": "~5.4.0", "protractor": "~5.4.0",
"ts-node": "~7.0.0", "ts-node": "~7.0.0",
"tslint": "~5.11.0", "tslint": "~5.11.0",
"typescript": "~3.1.1" "typescript": "~3.5.0"
} }
} }

@ -1,2 +1 @@
<app-scaffold id="headerbar"></app-scaffold> <app-main-navigation></app-main-navigation>
<router-outlet></router-outlet>

@ -1,45 +1,12 @@
@import '../styles/mixins.sass' @import '../styles/mixins.sass'
@import '../styles/vars.sass' @import '../styles/vars.sass'
/*
#content
grid-template: 7.5% 92.5% / 25% 50% 25%
display: grid
min-height: 100vh
max-height: 100vh*/
#imprint html, body
background-color: $cSecondaryBackground margin: 0
grid-template: 15% 70% 15% / 15% 70% 15% height: 100%
display: grid
min-height: 100vh
max-height: 100vh
#about
background-color: $cSecondaryBackground
grid-template: 15% 70% 15% / 15% 70% 15%
display: grid
min-height: 100vh
max-height: 100vh
#login
background-color: $cSecondaryBackground
grid-template: 15% 70% 15% / 15% 70% 15%
display: grid
min-height: 100vh
max-height: 100vh
#register
background-color: $cSecondaryBackground
grid-template: 15% 70% 15% / 15% 70% 15%
display: grid
min-height: 100vh
max-height: 100vh
#headerbar
height: 10vh
@include gridPosition(1, 1, 1, 4)
display: grid
grid-template: 100% /30% 10% 10% 10% 10% 10% 15% 5%
background-color: $cHeadPrimaryBackground
color: $cHeadFontColor

@ -9,6 +9,7 @@ import { SelfService } from './services/selfservice/self.service';
styleUrls: ['./app.component.sass'] styleUrls: ['./app.component.sass']
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
constructor(private data: DatasharingService, private selfservice: SelfService) { } constructor(private data: DatasharingService, private selfservice: SelfService) { }
userInfo: User userInfo: User
@ -37,4 +38,5 @@ export class AppComponent implements OnInit {
this.selfservice.checkIfLoggedIn(); this.selfservice.checkIfLoggedIn();
} }
} }
} }

@ -26,6 +26,33 @@ import { ProfileComponent } from './components/profile/profile.component';
import { ImprintComponent } from './components/imprint/imprint.component'; import { ImprintComponent } from './components/imprint/imprint.component';
import { AboutComponent } from './components/about/about.component'; 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 {MatTableModule} from '@angular/material/table';
import { MatSliderModule } from '@angular/material/slider';
import { MatFormFieldModule } from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
import { ReactiveFormsModule} from '@angular/forms';
import {MatIconModule} from '@angular/material/icon';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatTabsModule} from '@angular/material/tabs';
import {MatCardModule} from '@angular/material/card';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {MatSelectModule} from '@angular/material/select';
import {MatCheckboxModule} from '@angular/material/checkbox';
import { OverlayModule} from '@angular/cdk/overlay';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatMenuModule} from '@angular/material/menu';
import {MatRippleModule} from '@angular/material/core';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MainNavigationComponent } from './components/main-navigation/main-navigation.component';
import { LayoutModule } from '@angular/cdk/layout';
import { MatButtonModule } from '@angular/material/button';
import { MatListModule } from '@angular/material/list';
import {MatSortModule} from '@angular/material/sort';
const config: SocketIoConfig = { url: 'http://localhost:4444', options: {} }; const config: SocketIoConfig = { url: 'http://localhost:4444', options: {} };
@ -58,7 +85,8 @@ const appRoutes: Routes = [
PostlistComponent, PostlistComponent,
ImprintComponent, ImprintComponent,
AboutComponent, AboutComponent,
ProfileComponent ProfileComponent,
MainNavigationComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -69,7 +97,30 @@ const appRoutes: Routes = [
HttpClientModule, HttpClientModule,
RouterModule.forRoot( RouterModule.forRoot(
appRoutes appRoutes
) ),
MatIconModule,
BrowserAnimationsModule,
MatSliderModule,
MatFormFieldModule ,
MatInputModule,
ReactiveFormsModule,
MatToolbarModule,
MatSidenavModule,
FlexLayoutModule,
MatTabsModule,
LayoutModule,
MatButtonModule,
MatListModule,
MatCardModule,
MatButtonToggleModule,
MatSelectModule,
MatCheckboxModule,
OverlayModule,
MatSlideToggleModule,
MatMenuModule,
MatRippleModule,
MatTableModule,
MatSortModule
], ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent]

@ -1,9 +1,19 @@
<div id="about"> <div id="text0" style="text-align: center;">
<div id="aboutcontainer"> <h1>Greenvironment</h1>
<br> <br> <br> <br> <br>
<h1 class="mat-display-3">Keep it clean and green!</h1>
<button mat-icon-button>
<mat-icon class="big-icon">keyboard_arrow_down</mat-icon>
</button>
</div>
<div id="text1" style="text-align: center;">
<h1>What's Greenvironment?</h1> <h1>What's Greenvironment?</h1>
<h2>Hello!</h2> <p class="mat-display-1">We, the greenviroment team want to create a netwok 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 netwok for environmentalists who care for our nature and our planet as much as we do.</p> </div>
<p>We believe, that together we can do amazing things to protect our environment and keep it clean and green.</p> <div id="text2" style="text-align: center;">
<a href="/register">You aren't part of greenvironment yet? - join us here</a> <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>
</div> <p class="mat-display-1">You aren't part of greenvironment yet? - join us now!</p>
<a mat-raised-button class="link-button" routerLink="/register" >Register</a>
<br>
<a mat-raised-button class="link-button" routerLink="/login">Login</a>
</div> </div>

@ -1,22 +1,24 @@
@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 #text0, #text2
background-color: $cSecondaryBackground padding: 2em
grid-template: 15% 70% 15% / 15% 70% 15% max-width: 100%
display: grid min-height: 50%
min-height: 90vh background-color: mat-color($primary)
max-height: 90vh
#aboutcontainer #text1
@include gridPosition(2, 2,2,2) padding: 2em
background-color: $cPrimaryBackground min-height: 50%
padding: 1em max-width: 100%
overflow: auto
input .big-icon
margin: 0.25em //color: white
#header transform: scale(2)
@include gridPosition(1, 2, 1, 2)
a .link-button
color: $cHeadPrimaryBackground width: 100%
max-width: 30em
margin-bottom: 1em

@ -1,8 +1,9 @@
<div id='chatlist'> <div id='chatlist'>
<div id="header"> <!--<div id="header">
<span class="title">Chats</span> <span class="title">Chats</span>
<button id="newchat" (click)="newChat()"><span><i class="fa fa-plus fa-3x" aria-hidden="true"></i></span></button> <button id="newchat" (click)="newChat()"><span><i class="fa fa-plus fa-3x" aria-hidden="true"></i></span></button>
</div> </div>-->
<mat-toolbar><span>Chat</span></mat-toolbar>
<div id="chats"> <div id="chats">
<div class="chatitem" *ngFor="let chat of childChats" <div class="chatitem" *ngFor="let chat of childChats"
[class.selected]="chat === selectedChat" (click)="showChat(chat)"> [class.selected]="chat === selectedChat" (click)="showChat(chat)">

@ -1,13 +1,45 @@
<div id="postinput"> <!--<div id="postinput">
<textarea #content id='input' placeholder="Post something ..." rows='3' wrap="soft"></textarea> <textarea #content id='input' placeholder="Post something ..." rows='3' wrap="soft"></textarea>
<button id="attach" type='submit'><span><i class="fa fa-paperclip fa-2x" aria-hidden="true"></i></span></button> <button id="attach" type='submit'><span><i class="fa fa-paperclip fa-2x" aria-hidden="true"></i></span></button>
<button id="submit" type='submit' (click)=createPost(content)><span><i class="fa fa-send-o fa-2x" aria-hidden="true"></i></span></button> <button id="submit" type='submit' (click)=createPost(content)><span><i class="fa fa-send-o fa-2x" aria-hidden="true"></i></span></button>
</div>-->
<div id="home">
<mat-card >
<mat-card-content>
<mat-form-field id="input">
<textarea matInput #content type="text" mat-autosize="true" matAutosizeMaxRows="3" placeholder="post something"></textarea>
<button mat-button matSuffix mat-icon-button (click)="value=''">
<mat-icon>add</mat-icon>
</button>
</mat-form-field>
<p id="check">
<mat-checkbox color="primary" [(ngModel)]="checked">I protected the environment.</mat-checkbox>
</p>
<mat-form-field id="action-chooser" *ngIf="checked">
<mat-label>What did you do?</mat-label>
<mat-select [(ngModel)]="selectedValue" name="action">
<mat-option>nothing ;)</mat-option>
<mat-option *ngFor="let action of actionlist.Actions" [value]="action.points">
{{action.name}}
</mat-option>
</mat-select>
</mat-form-field>
<button mat-raised-button color="primary" id="post-button" (click)=createPost(content)>
POST
</button>
</mat-card-content>
</mat-card>
<div id="chooser-div" style="text-align: center; margin-top: 1em;">
<mat-button-toggle-group id="feedchooser" value="new">
<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-group>
</div> </div>
<div id='completeFeed'> <div id="complete-feed">
<div id='feedchooser'> <!--<div id='feedchooser'>
<button id="new" (click)="showNew()">New</button> <button id="new" (click)="showNew()">New</button>
<button id='mostliked' (click)="showMostLiked()">Most Liked</button> <button id='mostliked' (click)="showMostLiked()">Most Liked</button>
</div> </div>-->
<div id="feedlist"> <div id="feedlist">
<div *ngIf = "viewNew"> <div *ngIf = "viewNew">
<feed-postlist (voteEvent)="refresh($event)" [childPostList]="parentSelectedPostList"></feed-postlist> <feed-postlist (voteEvent)="refresh($event)" [childPostList]="parentSelectedPostList"></feed-postlist>
@ -17,3 +49,4 @@
</div> </div>
</div> </div>
</div> </div>
</div>

@ -1,82 +1,37 @@
@import '../../../styles/mixins.sass' @import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#postinput #home
@include gridPosition(1, 2, 1, 2) width: 100%
margin: 0.5em height: 100%
display: grid
grid-template: 100% /80% 10% 10%
#input
@include gridPosition(1, 2, 1, 2)
border-radius: 0.5em
padding: 0.125em
resize: none
#attach
@include gridPosition(1, 2, 2, 3)
#submit
@include gridPosition(1, 2, 3, 4)
button
background-color: $cFeedChooserBackground
color: $cFontWhite
border: none
border-radius: 0.5em
button:hover
background-color: lighten($cFeedChooserBackground, 10%)
cursor: pointer
#completeFeed #complete-feed
@include gridPosition(2, 3, 1, 2) box-sizing: border-box
display: grid display: flex
grid-template: 5% 95% /100% width: 100%
overflow: auto padding: 0.5em
background-color: $cFontWhite
#feedchooser #feedlist
@include gridPosition(1, 2, 1, 2) width: 100%
display: grid
grid-template: 100% /50% 50%
background-color: $cFontWhite
padding: 0
margin: 0
button
background-color: $cFeedChooserBackground
border: none
font-size: 1.5em
color: $cFontWhite
border-radius: 0.5em
button:hover
background-color: lighten($cFeedChooserBackground, 10%)
cursor: pointer
#new
@include gridPosition(1, 2, 1, 2)
#mostliked
@include gridPosition(1, 2, 2, 3)
#feedlist #input
@include gridPosition(2, 3, 1, 2)
overflow: auto
width: 100% width: 100%
height: 100% padding-left: 0.5em
padding-right: 0.5em
.feeditemPicture #action-chooser
background-color: $cFeedItemBackground width: 100%
min-height: 2em padding-left: 0.5em
margin: 0.5em padding-right: 0.5em
padding: 0.25em
border-radius: 0.25em #check
.itemhead margin: 0
align-items: flex-start padding-left: 0.5em
#post-button
width: 100%
padding-left: 0.5em
padding-right: 0.5em
margin-top: 0.5em
.title, .handle, .date
margin: 0.125em
.title
font-weight: bold
.handle, .date
color: $cInactiveText
.handle a
text-decoration: none
color: $cInactiveText
font-style: normal
.handle a:hover
text-decoration: underline

@ -1,6 +1,7 @@
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';
@Component({ @Component({
selector: 'home-feed', selector: 'home-feed',
@ -17,6 +18,8 @@ export class FeedComponent implements OnInit {
parentSelectedPostList: Array<Post> parentSelectedPostList: Array<Post>
actionlist: Actionlist = new Actionlist();
constructor(private feedService: FeedService) { } constructor(private feedService: FeedService) { }
ngOnInit() { ngOnInit() {
@ -24,6 +27,7 @@ export class FeedComponent implements OnInit {
this.feedNew = this.feedService.renderAllPosts(response.json()) this.feedNew = this.feedService.renderAllPosts(response.json())
this.parentSelectedPostList = this.feedNew this.parentSelectedPostList = this.feedNew
this.feedMostLiked = this.feedNew this.feedMostLiked = this.feedNew
console.log(this.feedNew)
}) })
} }
@ -37,6 +41,7 @@ export class FeedComponent implements OnInit {
} }
showNew() { showNew() {
console.log("showNew()")
this.feedService.getAllPostsRaw().subscribe(response => { this.feedService.getAllPostsRaw().subscribe(response => {
this.feedNew = this.feedService.renderAllPosts(response.json()) this.feedNew = this.feedService.renderAllPosts(response.json())
this.parentSelectedPostList = this.feedNew}) this.parentSelectedPostList = this.feedNew})
@ -45,6 +50,7 @@ export class FeedComponent implements OnInit {
} }
showMostLiked() { showMostLiked() {
console.log("showMostLiked()")
this.feedService.getAllPostsRaw().subscribe(response => { this.feedService.getAllPostsRaw().subscribe(response => {
this.feedMostLiked = this.feedService.renderAllPosts(response.json()) this.feedMostLiked = this.feedService.renderAllPosts(response.json())
this.parentSelectedPostList = this.feedMostLiked}) this.parentSelectedPostList = this.feedMostLiked})

@ -1,4 +1,4 @@
<div class="feeditem" *ngFor = "let post of childPostList" [class.selected]="post === selectedPost"> <!--<div class="feeditem" *ngFor = "let post of childPostList" [class.selected]="post === selectedPost">
<div class="itemhead"> <div class="itemhead">
<div class="usertag"> <div class="usertag">
<span class="title">{{post.author.name}}</span> <span class="title">{{post.author.name}}</span>
@ -17,4 +17,33 @@
<span id="upvotes">{{post.upvotes}}</span> <span id="upvotes">{{post.upvotes}}</span>
</div> </div>
</div> </div>
</div> </div>-->
<mat-card class="post" *ngFor = "let post of childPostList" [class.selected]="post === selectedPost" tabindex="0">
<mat-card-header>
<!-- <div mat-card-avatar class="example-header-image"></div> -->
<mat-card-title>
{{post.author.name}}
<a mat-button class="handle" routerLink="/profile/{{post.author.id}}">@{{post.author.handle}}</a>
</mat-card-title>
<mat-card-subtitle>
<p>{{post.date}}</p>
</mat-card-subtitle>
</mat-card-header>
<!--<img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">-->
<mat-card-content>
<p [innerHTML]="post.htmlContent"></p>
</mat-card-content>
<mat-card-actions>
<button mat-button>
<mat-icon aria-hidden="false" color="primary" *ngIf="post.userVote == 'UPVOTE'">keyboard_arrow_up</mat-icon>
<mat-icon aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'DOWNVOTE'">keyboard_arrow_up</mat-icon>
</button>
{{post.upvotes}}
<button mat-button>
<mat-icon aria-hidden="false" color="primary" *ngIf="post.userVote == 'DOWNVOTE'">keyboard_arrow_down</mat-icon>
<mat-icon aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">keyboard_arrow_down</mat-icon>
</button>
{{post.downvotes}}
</mat-card-actions>
</mat-card>

@ -1,67 +1,12 @@
@import '../../../../styles/mixins.sass' @import '../../../../styles/mixins.sass'
@import '../../../../styles/vars.sass' @import '../../../../styles/vars.sass'
.feeditem .post
background-color: $cFeedItemBackground box-sizing: border-box
min-height: 2em width: 100%
//max-heigth: 5em margin-top: 0.5em
margin: 0.5em
padding: 0.25em ::ng-deep .mat-card-header-text
border-radius: 0.25em margin: 0px
.itemhead
display: grid
grid-template: 100% /70% 30%
.usertag
@include gridPosition(1, 2, 1, 2)
.title, .handle, .date
margin: 0.125em
.title
font-weight: bold
.date
@include gridPosition(1, 2, 2, 3)
text-align: right
.handle, .date
color: $cInactiveText
.handle a
text-decoration: none
color: $cInactiveText
font-style: normal
.handle a:hover
text-decoration: underline
.itembody
display: grid
grid-template: 100% /85% 15%
.text
@include gridPosition(1, 2, 1, 2)
overflow-x: hidden
::ng-deep img
max-width: 100%
height: auto
.vote
@include gridPosition(1, 2, 2, 3)
display: grid
grid-template: 70% 30% /50% 50%
height: 3em
button
background-color: $cFeedItemBackground
border: none
button:hover
cursor: pointer
#up
@include gridPosition(1, 2, 2, 3)
color: $cFeedUpVote
#up:hover
color: darken($cFeedUpVote, 10%)
#down
@include gridPosition(1, 2, 1, 2)
color: $cFeedDownVote
#down:hover
color: darken($cFeedDownVote, 10%)
#downvotes
@include gridPosition(2, 3, 1, 2)
text-align: center
#upvotes
@include gridPosition(2, 3, 2, 3)
text-align: center

@ -1,5 +1,36 @@
<div id="content"> <div id="content" fxShow="true" fxHide.lt-md="true">
<home-chatmanager id="chatcontainer" *ngIf="loggedIn"></home-chatmanager> <div id="chat"><home-chatmanager id="chatcontainer" *ngIf="!loggedIn"></home-chatmanager></div>
<home-feed id="feedcontainer"></home-feed> <div id="feed"><home-feed id="feedcontainer"></home-feed></div>
<home-social id="socialcontainer" *ngIf="loggedIn"></home-social> <div id="social"><home-social id="socialcontainer" *ngIf="!loggedIn"></home-social></div>
</div> </div>
<!--
<mat-tab-group headerPosition="below" position="0" id="bottom-menu" fxShow="true" fxHide.gt-sm="true">
<mat-tab label="First"> <home-chatmanager ></home-chatmanager></mat-tab>
<mat-tab label="Second"><home-feed id="feed"></home-feed></mat-tab>
<mat-tab label="Third"> <home-social ></home-social></mat-tab>
</mat-tab-group>
-->
<div class="bottom-menu" fxShow="true" fxHide.gt-sm="true">
<mat-tab-group id="tab-group" selectedIndex="1" mat-stretch-tabs headerPosition="below">
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>chat</mat-icon>
</ng-template>
<home-chatmanager class="tab-content"></home-chatmanager>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>home</mat-icon>
</ng-template>
<home-feed class="tab-content"></home-feed>
</mat-tab>
<mat-tab >
<ng-template mat-tab-label>
<mat-icon>people</mat-icon>
</ng-template>
<home-social class="tab-content"></home-social>
</mat-tab>
</mat-tab-group>
</div>

@ -2,27 +2,51 @@
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#content #content
grid-template: 100%/ 25% 50% 25% position: fixed
display: grid width: 100%
min-height: 90vh height: calc(100% - 56px)
max-height: 90vh
background-color: $cFontWhite #chat
box-sizing: content-box
#chatcontainer height: 100%
@include gridPosition(1, 3, 1, 2) width: 25%
background-color: $cBoxBodyBackground float: left
overflow: auto overflow-y: auto
#feedcontainer #feed
@include gridPosition(1, 3, 2, 3) box-sizing: content-box
display: grid height: 100%
grid-template: 10% 90% /100% width: 50%
background-color: $cFontWhite float: left
overflow: auto overflow-y: auto
#socialcontainer #social
@include gridPosition(1, 3, 3, 4) box-sizing: content-box
display: grid height: 100%
grid-template: 50% 50% /100% width: 25%
background-color: $cBoxBodyBackground float: left
overflow: auto overflow-y: auto
.mat-toolbar.mat-primary
width: 100%
position: sticky
top: 0
z-index: 1
/deep/ .mat-tab-body-wrapper
height: 100%
.bottom-menu
position: fixed
width: 100%
height: calc(100% - 56px)
#tab-group
height: 100%
.tab-content
height: 50%
width: 100%

@ -1,8 +1,6 @@
<mat-toolbar color="primary">Imprint</mat-toolbar>
<div id="imprint"> <div id="imprint">
<div id="imprintcontainer">
<h1>Imprint</h1>
<p>The greenvironment network is being developed by the greenvironment team</p> <p>The greenvironment network is being developed by the greenvironment team</p>
<h2>Contact</h2> <h2>Contact</h2>
<p>Email: nick.derkoenig@greenvironment.net</p> <p>Email: nick.derkoenig@greenvironment.net</p>
</div>
</div> </div>

@ -1,19 +1,15 @@
@import '../../../styles/mixins.sass' @import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#imprint #imprint
background-color: $cSecondaryBackground padding: 2em
grid-template: 15% 70% 15% / 15% 70% 15% max-width: 35em
display: grid margin: 0 auto
height: 90vh
h1.mat-display-1
margin: 0
#imprintcontainer
@include gridPosition(2, 2,2,2)
background-color: $cPrimaryBackground
padding: 1em
overflow: auto
input
margin: 0.25em
#header
@include gridPosition(1, 2, 1, 2)

@ -1,22 +1,24 @@
<div id="login"> <div id="login">
<div id="logincontainer"> <mat-card style="text-align: center;" >
<h1>Login</h1> <mat-card-title>
<table style="width:100%" (keyup.enter)="onClickSubmit(email.value,password.value)"> Login
<tr> </mat-card-title>
<td>email: </td> <mat-card-content>
<td><input #email type="text" name="email"><br></td> <div class="example-container" (keyup.enter)="onClickSubmit(email.value,password.value)">
</tr> <mat-error *ngIf="errorOccurred">{{getErrorMessage()}}</mat-error>
<tr> <mat-form-field>
<td>password:</td> <input matInput placeholder="Enter your email" #email >
<td> <input #password type="password" name="password"><br></td> </mat-form-field>
</tr> <mat-form-field>
</table> <input matInput placeholder="Enter your password" [type]="hide ? 'password' : 'text'" #password>
<button type="loginbutton" (click)="onClickSubmit(email.value,password.value)">Login</button> <button mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
<p *ngIf="errorOccurred">{{errorMessage}}</p> <mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
<br> </button>
<br> </mat-form-field>
<a href="/register">You aren't part of greenvironment yet? - join us here</a>
</div> </div>
<button mat-raised-button color="primary" (click)="onClickSubmit(email.value,password.value)">Login</button>
<p>You aren't part of greenvironment yet?</p>
<a mat-stroked-button color="primary" routerLink="/register">Register</a>
</mat-card-content>
</mat-card>
</div> </div>

@ -2,21 +2,40 @@
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#login #login
background-color: $cSecondaryBackground padding: 2em
grid-template: 8% 77% 15% / 15% 70% 15% max-width: 35em
display: grid margin: 0 auto
height: 90vh
.example-container
#logincontainer display: flex
@include gridPosition(2, 2,2,2) flex-direction: column
background-color: $cPrimaryBackground
padding: 1em .example-container > *
overflow: auto width: 100%
input .example-right-align
text-align: right
input.example-right-align::-webkit-outer-spin-button,
input.example-right-align::-webkit-inner-spin-button
display: none
input.example-right-align
-moz-appearance: textfield
.mat-error
margin-bottom: 0.25em
.mat-raised-button
margin: 0.25em
width: 100%
.mat-button
margin: 0.25em margin: 0.25em
a .mat-stroked-button
color: $cHeadPrimaryBackground width: 100%

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {FormControl, Validators} from '@angular/forms';
import { Login } from 'src/app/models/login'; import { Login } from 'src/app/models/login';
import { LoginService } from 'src/app/services/login/login.service'; import { LoginService } from 'src/app/services/login/login.service';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
@ -11,6 +12,7 @@ import * as sha512 from 'js-sha512';
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
login: Login login: Login
hide = true;
errorOccurred: boolean = false; errorOccurred: boolean = false;
errorMessage: string; errorMessage: string;
@ -18,6 +20,10 @@ export class LoginComponent implements OnInit {
this.login = {passwordHash: null, email: null}; this.login = {passwordHash: null, email: null};
} }
public getErrorMessage(){
return this.errorMessage;
}
public loginError(error : any){ public loginError(error : any){
console.log(error.errors[0].message); console.log(error.errors[0].message);
this.errorOccurred = true; this.errorOccurred = true;
@ -36,6 +42,7 @@ export class LoginComponent implements OnInit {
this.loginService.login(this.login, error => this.loginError(error.json())); this.loginService.login(this.login, error => this.loginError(error.json()));
} }
email = new FormControl('', [Validators.required, Validators.email]);
ngOnInit() {} ngOnInit() {}
} }

@ -0,0 +1,77 @@
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<mat-sidenav-container class="sidenav-container" class="mat-typography">
<mat-sidenav #drawer class="sidenav"
fxShow="true" fxHide.gt-sm="true"
fixedInViewport="false"
autoFocus="false"
>
<mat-toolbar>Menu</mat-toolbar>
<mat-nav-list>
<a mat-list-item routerLink="" (click)="drawer.close()">Home</a>
<a mat-list-item *ngIf="loggedIn" routerLink={{profileUrl}} (click)="drawer.close()">Profile</a>
<a mat-list-item routerLink="/about" (click)="drawer.close()">About</a>
<a mat-list-item routerLink="/imprint" (click)="drawer.close()">Imprint</a>
<mat-divider></mat-divider>
<div id="link-box">
<a mat-stroked-button *ngIf="!loggedIn" class="link-button" routerLink="/register" (click)="drawer.close()">Register</a>
<a mat-stroked-button *ngIf="!loggedIn" class="link-button" routerLink="/login" (click)="drawer.toggle()">Login</a>
<a mat-stroked-button *ngIf="loggedIn" class="link-button" (click)="logout()" (click)="drawer.toggle()">log out</a>
</div>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<mat-toolbar color="primary" class="mat-elevation-z4">
<button
type="button"
aria-label="Toggle sidenav"
mat-icon-button
(click)="drawer.toggle()"
fxShow="true" fxHide.gt-sm="true">
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
<span>Greenvironment</span>
<!--The following menu items will be hidden on both SM and XS screen sizes -->
<nav mat-tab-nav-bar backgroundColor="primary" fxShow="true" fxHide.lt-md="true">
<div *ngIf="loggedIn">
<a mat-tab-link class="link"
*ngFor="let link of navLinksLoggedIn"
[routerLink]="link.path"
(click)="activeLink = link"
routerLinkActive #rla="routerLinkActive"
[routerLinkActiveOptions]="{exact:true}"
[active]="activeLink == link">
{{link.label}}
</a>
<a mat-tab-link (click)="logout()" >log out</a>
</div>
<div *ngIf="!loggedIn">
<a mat-tab-link class="link"
*ngFor="let link of navLinks"
[routerLink]="link.path"
(click)="activeLink = link"
routerLinkActive #rla="routerLinkActive"
[routerLinkActiveOptions]="{exact:true}"
[active]="rla.isActive">
{{link.label}}
</a>
</div>
</nav>
<div id="menu-button-box">
<button mat-icon-button [matMenuTriggerFor]="menu" id="menu-button">
<mat-icon>more_vert</mat-icon>
</button>
</div>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="$event.stopPropagation();">
<mat-slide-toggle
color="primary"
class="theme-button"
(change)="toggleTheme()"><!--stays white when dragged-->
dark mode
</mat-slide-toggle>
</button>
</mat-menu>
</mat-toolbar>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>

@ -0,0 +1,47 @@
.sidenav-container
height: 100%
.mat-sidenav-container
height: 100%
.mat-sidenav-content
height: 100vh
.sidenav
width: 200px
.sidenav .mat-toolbar
background: inherit
.mat-toolbar.mat-primary
height: 56px
position: sticky
top: 0
z-index: 1000
.mat-tab-nav-bar
width: 70%
height: 56px
.mat-tab-links
height: 56px
.mat-tab-link
height: 56px
#link-box
padding: 0.5em
.link-button
width: 100%
margin-bottom: 0.5em
/deep/ .mat-tab-link
min-width: 5em!important
#menu-button-box
text-align: right
width: 100%

@ -0,0 +1,40 @@
import { LayoutModule } from '@angular/cdk/layout';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MainNavigationComponent } from './main-navigation.component';
describe('MainNavigationComponent', () => {
let component: MainNavigationComponent;
let fixture: ComponentFixture<MainNavigationComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MainNavigationComponent],
imports: [
NoopAnimationsModule,
LayoutModule,
MatButtonModule,
MatIconModule,
MatListModule,
MatSidenavModule,
MatToolbarModule,
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MainNavigationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should compile', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,104 @@
import { Component, OnInit, HostBinding } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
import { DatasharingService } from '../../services/datasharing.service';
import { SelfService } from '../../services/selfservice/self.service';
import { environment } from 'src/environments/environment';
import { Levellist } from 'src/app/models/levellist';
import { Http } from '@angular/http';
import { Router } from '@angular/router';
import { User } from 'src/app/models/user';
import { OverlayContainer} from '@angular/cdk/overlay';
@Component({
selector: 'app-main-navigation',
templateUrl: './main-navigation.component.html',
styleUrls: ['./main-navigation.component.sass']
})
export class MainNavigationComponent implements OnInit {
loggedIn: boolean = false
userId: number
username: string
user: User
levellist: Levellist = new Levellist()
level: string
points: number
profileUrl: string
lighttheme : boolean = true
overlay;
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches),
shareReplay()
);
constructor(public overlayContainer: OverlayContainer, private data: DatasharingService,private selfservice: SelfService,private breakpointObserver: BreakpointObserver, private http: Http, private router: Router) {
this.overlay = overlayContainer.getContainerElement();
}
ngOnInit() {
this.data.currentUserInfo.subscribe(user => {
this.user = user
this.loggedIn = user.loggedIn;
this.userId = user.userID;
this.username = user.username
this.level = this.levellist.getLevelName(user.level)
this.points = user.points
this.profileUrl = '/profile/' + this.userId;
})
}
navLinksLoggedIn = [
{ path: '', label: 'Home' },
{ path: 'profile/1', label: 'Profile' },
{ path: '/about', label: 'About' },
{ path: '/imprint', label: 'Imprint' },
];
navLinks = [
{ path: '', label: 'Home' },
{ path: '/about', label: 'About' },
{ path: '/imprint', label: 'Imprint' },
{ path: '/login', label: 'Login' },
{ path: '/register', label: 'Register' },
];
toggleTheme() {
if (this.overlay.classList.contains("dark-theme")) {
this.overlay.classList.remove("dark-theme");
this.overlay.classList.add("light-theme");
this.onSetTheme("light-theme");
} else if (this.overlay.classList.contains("light-theme")) {
this.overlay.classList.remove("light-theme");
this.overlay.classList.add("dark-theme");
this.onSetTheme("dark-theme");
} else {
this.overlay.classList.add("dark-theme");
this.onSetTheme("dark-theme");
}
}
@HostBinding('class') componentCssClass;
onSetTheme(theme) {
this.overlayContainer.getContainerElement().classList.add(theme);
this.componentCssClass = theme;
}
logout() {
let url = environment.graphQLUrl
let headers = new Headers()
headers.set('Content-Type', 'application/json')
const body = {query: `mutation {
logout
}`}
this.http.post(url, body).subscribe(response => {
console.log(response.text())})
this.loggedIn = false
let user = new User()
user.loggedIn = false
this.data.changeUserInfo(user)
this.router.navigate(['login'])
}
}

@ -1,45 +1,93 @@
<mat-toolbar color="primary">Profile</mat-toolbar>
<div id="profile"> <div id="profile">
<div id="profilecontainer" *ngIf="profileNotFound == false"> <div id="profilecontainer" [hidden]="profileNotFound">
<h1>Profile</h1> <div id="profile-card-container">
<table style="width:100%"> <mat-card class="mat-elevation-z8">
<mat-card-header>
<div mat-card-avatar class="profile-picture"></div>
<mat-card-title>{{user.username}}</mat-card-title>
<mat-card-subtitle>{{user.handle}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<table id="profile-table">
<tr> <tr>
<td>name: </td> <div class="mat-header-cell">name: </div>
<td>{{user.username}}</td> <td>{{user.username}}</td>
</tr> </tr>
<mat-divider></mat-divider>
<tr> <tr>
<td>handle: </td> <div class="mat-header-cell">handle: </div>
<td>{{user.handle}}</td> <td>{{user.handle}}</td>
</tr> </tr>
<mat-divider></mat-divider>
<tr> <tr>
<td>profile ID: </td> <div class="mat-header-cell">profileID: </div>
<td>{{user.userID}}</td> <td>{{user.userID}}</td>
</tr> </tr>
<mat-divider></mat-divider>
<tr> <tr>
<td>points: </td> <div class="mat-header-cell">points: </div>
<td>{{user.points}}</td> <td>{{user.points}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">level: </div>
<td>{{user.level}}</td>
</tr>
<mat-divider></mat-divider>
<tr> <tr>
<td>level: </td> <div class="mat-header-cell">level name: </div>
<td>{{user.level}} ({{rankname}})</td> <td>{{rankname}}</td>
</tr> </tr>
</table> </table>
<h2>What does the level mean?</h2> </mat-card-content>
</mat-card>
</div>
<br>
<h1>What does the level mean?</h1>
<p>There are different levels you can reach through green behaviour. <p>There are different levels you can reach through green behaviour.
Collect 100 points to level up! The levels are called: Collect 100 points to level up! The levels are called:
</p> </p>
<ol start="0"> <table mat-table [dataSource]="levelSource" class="mat-elevation-z8">
<li *ngFor= "let level of levellist.levels"> <ng-container matColumnDef="level">
{{level.name}} <th mat-header-cell *matHeaderCellDef> level </th>
</li> <td mat-cell *matCellDef="let level"> {{level.level}} </td>
</ol> </ng-container>
<h2>How to level up?</h2> <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, <p>There is an always growing list of things you can do,
to support your environment to support your environment
and earn points to level up at the same time. and earn points to level up at the same time.
You can get a different amount of points You can get a different amount of points
for differnet actions you can see in the list below: for differnet actions you can see in the list below:
</p> </p>
<table style="width:100%"> <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%">
<tr> <tr>
<th>points </th> <th>points </th>
<th>action</th> <th>action</th>
@ -48,7 +96,7 @@
<td>{{action.points}}</td> <td>{{action.points}}</td>
<td>{{action.name}}</td> <td>{{action.name}}</td>
</tr> </tr>
</table> </table>-->
</div> </div>
<div id="profilecontainer" *ngIf="profileNotFound"> <div id="profilecontainer" *ngIf="profileNotFound">
<h1>Profile not found :(</h1> <h1>Profile not found :(</h1>

@ -2,19 +2,37 @@
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#profile #profile
background-color: $cSecondaryBackground padding: 2em
grid-template: 3% 94% 3% / 10% 80% 10% max-width: 1200px
display: grid margin: 0 auto
min-height: 90vh
max-height: 90vh
#profile-card-container
margin: 0 auto
width: 100%
max-width: 690px
#profilecontainer .mat-table
@include gridPosition(2, 2,2,2) width: 100%
//grid-template: 15% 15% 15% 15% 15% 15% / 100% max-width: 690px
background-color: $cPrimaryBackground margin: 0 auto
padding: 1em .mat-header-cell
overflow: auto padding-right: 0.5em
th .profile-picture
text-align: left background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
background-size: cover
#profile-table
width: 100%
.mat-table
display: block
.mat-cell,
.mat-header-cell
align-items: center
display: flex
min-height: 48px
padding: 0
flex: 1
overflow: hidden
word-wrap: break-word

@ -1,27 +1,36 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, ViewChild} from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {Http, URLSearchParams, Headers} from '@angular/http'; import {Http, URLSearchParams, Headers} from '@angular/http';
import { User } from 'src/app/models/user'; import { User } from 'src/app/models/user';
import { Actionlist } from 'src/app/models/actionlist'; import { Actionlist } from 'src/app/models/actionlist';
import { Levellist } from 'src/app/models/levellist'; import { Levellist } from 'src/app/models/levellist';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
@Component({ @Component({
selector: 'app-profile', selector: 'app-profile',
templateUrl: './profile.component.html', templateUrl: './profile.component.html',
styleUrls: ['./profile.component.sass'] styleUrls: ['./profile.component.sass']
}) })
export class ProfileComponent implements OnInit { export class ProfileComponent implements OnInit {
actionlist: Actionlist = new Actionlist(); actionlist: Actionlist = new Actionlist()
levellist: Levellist = new Levellist();
levellist: Levellist = new Levellist()
user: User = new User() user: User = new User()
id : string id : string
rankname: string; rankname: string
profileNotFound : boolean = false; profileNotFound : boolean = false
displayedColumns = ['points', 'name']
dataSource = new MatTableDataSource(this.actionlist.Actions)
displayedLevelColumns = ['level', 'name']
levelSource = this.levellist.levels
constructor(private router: Router,private http: Http) { } constructor(private router: Router,private http: Http) { }
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() { ngOnInit() {
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);
//let url = './graphql' //let url = './graphql'
let url = environment.graphQLUrl let url = environment.graphQLUrl

@ -1,28 +1,33 @@
<div id="register"> <div id="register">
<div id="registercontainer"> <mat-card style="text-align: center;" >
<h1>Register</h1> <mat-card-title>
<table style="width:100%" (keyup.enter)="onClickSubmit(username.value,email.value,password.value, repeatpassword.value)"> Register
<tr> </mat-card-title>
<td>username: </td> <mat-card-content>
<td><input #username type="text" name="username" username.value=''><br></td> <div class="example-container" (keyup.enter)="onClickSubmit(username.value,email.value,password.value, repeatpassword.value)">
</tr> <mat-error *ngIf="errorOccurred">{{errorMessage}}</mat-error>
<tr> <mat-form-field>
<td>email:</td> <input matInput placeholder="Enter your email" #email >
<td><input #email type="text" name="email"><br></td> </mat-form-field>
</tr> <mat-form-field>
<tr> <input matInput placeholder="Enter your username" #username >
<td>password:</td> </mat-form-field>
<td> <input #password type="password" name="password"><br></td> <mat-form-field>
</tr> <input matInput placeholder="Enter your password" [type]="hide1 ? 'password' : 'text'" #password>
<tr> <button mat-icon-button matSuffix (click)="hide1 = !hide1" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide1">
<td>repeat password:</td> <mat-icon>{{hide1 ? 'visibility_off' : 'visibility'}}</mat-icon>
<td> <input #repeatpassword type="password" name="repeatpassword"><br></td> </button>
</tr> </mat-form-field>
</table> <mat-form-field>
<button type="registerbutton" (click)="onClickSubmit(username.value,email.value,password.value, repeatpassword.value)">Register</button> <input matInput placeholder="Repeat your password" [type]="hide2 ? 'password' : 'text'" #repeatpassword>
<p *ngIf="errorOccurred">{{errorMessage}}</p> <button mat-icon-button matSuffix (click)="hide2 = !hide2" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide2">
<br> <mat-icon>{{hide2 ? 'visibility_off' : 'visibility'}}</mat-icon>
<br> </button>
<a href="/login">You are already part of greenvironment? - login</a> </mat-form-field>
</div>
<button mat-raised-button color="primary" (click)="onClickSubmit(username.value,email.value,password.value, repeatpassword.value)">Register</button>
<p>You are already part of greenvironment?</p>
<a mat-stroked-button color="primary" routerLink="/login">Login</a>
</mat-card-content>
</mat-card>
</div> </div>
</div>

@ -2,20 +2,36 @@
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#register #register
background-color: $cSecondaryBackground padding: 2em
grid-template: 8% 77% 15% / 15% 70% 15% max-width: 35em
display: grid margin: 0 auto
min-height: 90vh
max-height: 90vh .example-container
display: flex
#registercontainer flex-direction: column
@include gridPosition(2, 2,2,2)
grid-template: 15% 15% 15% 15% 15% 15% / 100% .example-container > *
background-color: $cPrimaryBackground width: 100%
padding: 1em
overflow: auto .example-right-align
input text-align: right
input.example-right-align::-webkit-outer-spin-button,
input.example-right-align::-webkit-inner-spin-button
display: none
input.example-right-align
-moz-appearance: textfield
.mat-error
margin-bottom: 0.25em
.mat-raised-button
margin: 0.25em
width: 100%
.mat-button
margin: 0.25em margin: 0.25em
a .mat-stroked-button
color: $cHeadPrimaryBackground width: 100%

@ -15,6 +15,8 @@ export class RegisterComponent implements OnInit {
registration: Registration registration: Registration
errorOccurred: boolean = false; errorOccurred: boolean = false;
errorMessage: string; errorMessage: string;
hide1 = true;
hide2 = true;
constructor(private registerService: RegisterService) { constructor(private registerService: RegisterService) {
this.registration = {username: null, passwordHash: null, email: null}; this.registration = {username: null, passwordHash: null, email: null};

@ -1,12 +1,23 @@
<div id="header"> <!--<div id="header">
<span class="title">Friends</span> <span class="title">Friends</span>
<button id="new" type="submit"><span><i class="fa fa-plus fa-3x" aria-hidden="true"></i></span></button> <button id="new" type="submit"><span><i class="fa fa-plus fa-3x" aria-hidden="true"></i></span></button>
<button id="invitations" type="submit"><span><i class="fa fa-envelope-o fa-3x" aria-hidden="true"></i></span></button> <button id="invitations" type="submit"><span><i class="fa fa-envelope-o fa-3x" aria-hidden="true"></i></span></button>
</div> </div>-->
<div id="friendslist"> <mat-toolbar><span>Friends</span></mat-toolbar>
<div class="frienditem" *ngFor="let friend of friends" <div id="friendlist">
<!--<div class="frienditem" *ngFor="let friend of friends"
[class.selected]="friend === selectedFriend" (click)="showFriendProfile(friend)"> [class.selected]="friend === selectedFriend" (click)="showFriendProfile(friend)">
<div class="picture">Pic</div> <div class="picture">Pic</div>
<div class="name"><span>{{friend.name}}</span></div> <div class="name"><span>{{friend.name}}</span></div>
</div> </div>-->
<mat-card class="friend-card" *ngFor="let friend of friends"
[class.selected]="friend === selectedFriend" (click)="showFriendProfile(friend)"
tabindex="0"
matRipple>
<mat-card-header>
<div mat-card-avatar class="profile-picture"></div>
<mat-card-title>{{friend.name}}</mat-card-title>
<mat-card-subtitle>{{friend.rankname}}</mat-card-subtitle>
</mat-card-header>
</mat-card>
</div> </div>

@ -2,31 +2,18 @@
@import '../../../../styles/vars.sass' @import '../../../../styles/vars.sass'
@import '../social.component.sass' @import '../social.component.sass'
#friendslist #friendlist
overflow: auto padding: 0.5em
@include gridPosition(2, 3, 1, 2)
div:hover .friend-card
background-color: darken($cPrimaryBackground, 10%) box-sizing: border-box
width: 100%
margin-top: 0.5em
cursor: pointer cursor: pointer
.frienditem
background-color: $cPrimaryBackground .mat-card-subtitle
height: 3em margin: 0
margin: 0.2em
padding: 0.25em .profile-picture
border-radius: 0.25em background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
//border: solid background-size: cover
display: grid
grid-template: 100% / 20% 60% 20%
.picture
@include gridPosition(1, 2, 1, 2)
border: solid
.name, .date
margin-top: auto
margin-bottom: auto
.name
@include gridPosition(1, 2, 2, 3)
font-weight: bold
text-align: left
padding-left: 0.5em
span
font-size: 125%

@ -35,13 +35,14 @@ export class FriendsComponent implements OnInit {
} }
readOutFriendsNames(pId: number, pResponse : any) { readOutFriendsNames(pId: number, pResponse : any) {
this.friends.push(new FriendInfo(pId, pResponse.data.getUser.name)) this.friends.push(new FriendInfo(pId, pResponse.data.getUser.name,pResponse.data.getUser.level ))
} }
buildJson(pId: number): any { buildJson(pId: number): any {
const body = {query: `query($userId: ID) { const body = {query: `query($userId: ID) {
getUser(userId:$userId) { getUser(userId:$userId) {
name name
level
} }
}`, variables: { }`, variables: {
userId: pId userId: pId

@ -1,12 +1,20 @@
<div id="header"> <!--<div id="header">
<span class="title">Groups</span> <span class="title">Groups</span>
<button id="new" type="submit"><span><i class="fa fa-plus fa-3x" aria-hidden="true"></i></span></button> <button id="new" type="submit"><span><i class="fa fa-plus fa-3x" aria-hidden="true"></i></span></button>
<button id="invitations" type="submit"><span><i class="fa fa-envelope-o fa-3x" aria-hidden="true"></i></span></button> <button id="invitations" type="submit"><span><i class="fa fa-envelope-o fa-3x" aria-hidden="true"></i></span></button>
</div> </div>-->
<div id="groupslist"> <mat-toolbar><span>Groups</span></mat-toolbar>
<div class="groupitem" *ngFor="let group of groups" <div id="grouplist">
<!--<div class="groupitem" *ngFor="let group of groups"
[class.selected]="group === selectedGroup" (click)="showGroup(group)"> [class.selected]="group === selectedGroup" (click)="showGroup(group)">
<div class="picture">Pic</div> <div class="picture">Pic</div>
<div class="name"><span>{{group.name}}</span></div> <div class="name"><span>{{group.name}}</span></div>
</div> </div>-->
<mat-card class="group-card" *ngFor="let group of groups"
[class.selected]="group === selectedGroup" (click)="showGroup(group)">
<mat-card-header>
<div mat-card-avatar class="group-picture"></div>
<mat-card-title>{{group.name}}</mat-card-title>
</mat-card-header>
</mat-card>
</div> </div>

@ -2,31 +2,16 @@
@import '../../../../styles/vars.sass' @import '../../../../styles/vars.sass'
@import '../social.component.sass' @import '../social.component.sass'
#groupslist #grouplist
overflow: auto padding: 0.5em
@include gridPosition(2, 3, 1, 2)
div:hover .group-card
background-color: darken($cPrimaryBackground, 10%) box-sizing: border-box
cursor: pointer width: 100%
.groupitem margin-top: 0.5em
background-color: $cPrimaryBackground .mat-card-subtitle
height: 3em margin: 0
margin: 0.2em
padding: 0.25em .group-picture
border-radius: 0.25em background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
//border: solid background-size: cover
display: grid
grid-template: 100% / 20% 60% 20%
.picture
@include gridPosition(1, 2, 1, 2)
border: solid
.name, .date
margin-top: auto
margin-bottom: auto
.name
@include gridPosition(1, 2, 2, 3)
font-weight: bold
text-align: left
padding-left: 0.5em
span
font-size: 125%

@ -2,43 +2,13 @@
@import '../../../styles/vars.sass' @import '../../../styles/vars.sass'
#friendscontainer #friendscontainer
@include gridPosition(1, 2, 1, 2) box-sizing: content-box
display: grid height: 50%
grid-template: 15% 85% /100% width: 100%
overflow: auto
#groupscontainer #groupscontainer
@include gridPosition(2, 3, 1, 2) box-sizing: content-box
display: grid height: 50%
grid-template: 15% 85% /100% width: 100%
overflow: auto
#header
@include gridPosition(1, 2, 1, 2)
background-color: $cBoxHeaderBackground
display: grid
grid-template: 100% /60% 20% 20%
span
color: $cFontWhite
span.title
@include gridPosition(1, 2, 1, 2)
margin-top: 0.25em
margin-left: 0.25em
line-height: 100%
font-size: 2em
button
background-color: $cBoxHeaderBackground
border: none
button:hover
background-color: lighten($cBoxHeaderBackground, 10%)
cursor: pointer
button:active
background-color: darken($cBoxHeaderBackground, 5%)
#new
@include gridPosition(1, 2, 2, 3)
#invitations
@include gridPosition(1, 2, 3, 4)

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

@ -1,9 +1,14 @@
import { Levellist } from 'src/app/models/levellist';
export class FriendInfo { export class FriendInfo {
levellist: Levellist = new Levellist();
id: number id: number
name: string name: string
rankname: string
constructor(pId: number, pName: string) { constructor(pId: number, pName: string, pLevel: number) {
this.id = pId this.id = pId
this.name = pName this.name = pName
this.rankname = this.levellist.getLevelName(pLevel);
} }
} }

@ -11,11 +11,8 @@ export class Levellist{
getLevelName(lev:number): any{ getLevelName(lev:number): any{
var name: string = 'not defined'; var name: string = 'not defined';
console.log(lev);
this.levels.forEach(rank => { this.levels.forEach(rank => {
console.log(rank.level);
if(lev == rank.level){ if(lev == rank.level){
console.log('found matching level');
name = rank.name; name = rank.name;
} }
}); });

@ -7,14 +7,16 @@ export class Post {
date: string date: string
upvotes: number upvotes: number
downvotes: number downvotes: number
userVote: string
author: Author author: Author
constructor(pId: number, pContent: string, pHtmlContent: string, pUpvotes: number, pDownvotes: number, pDate: string, pAuthor: Author) { constructor(pId: number, pContent: string, pHtmlContent: string, pUpvotes: number, pDownvotes: number, pUserVote: string, pDate: string, pAuthor: Author) {
this.id = pId this.id = pId
this.content = pContent this.content = pContent
this.htmlContent = pHtmlContent this.htmlContent = pHtmlContent
this.upvotes = pUpvotes this.upvotes = pUpvotes
this.downvotes = pDownvotes this.downvotes = pDownvotes
this.userVote = pUserVote
this.date = pDate this.date = pDate
this.author = pAuthor this.author = pAuthor
} }

@ -105,13 +105,15 @@ export class ChatService {
for(let chat of temp.data.getSelf.chats) { for(let chat of temp.data.getSelf.chats) {
let memberID: number let memberID: number
let memberName: string let memberName: string
let memberLevel: number
for(let member of chat.members) { for(let member of chat.members) {
if(member.id != this.ownID) { if(member.id != this.ownID) {
memberID = member.id memberID = member.id
memberName = member.name memberName = member.name
memberLevel = member.level
} }
} }
chatPartners.push(new FriendInfo(memberID, memberName)) chatPartners.push(new FriendInfo(memberID, memberName, memberLevel))
} }
return chatPartners return chatPartners
@ -221,7 +223,7 @@ export class ChatService {
getBodyForRequestOfAllChatPartners() { getBodyForRequestOfAllChatPartners() {
const body = {query: `query { const body = {query: `query {
getSelf { getSelf {
chats(first: 1000, offset: 0) {members{name, id}} chats(first: 1000, offset: 0) {members{name, id, level}}
}}` }}`
} }
@ -243,7 +245,7 @@ export class ChatService {
const body = {query: `query { const body = {query: `query {
getSelf { getSelf {
chats(first: 1000, offset: 0) { chats(first: 1000, offset: 0) {
id, members{name, id}, id, members{name, id, level},
messages(first: 1000, offset: 0) { messages(first: 1000, offset: 0) {
author {id}, createdAt, content author {id}, createdAt, content
} }
@ -256,7 +258,7 @@ export class ChatService {
getBodyForGetChatsByID(pChatID: number) { getBodyForGetChatsByID(pChatID: number) {
const body = {query: `query($chatID: ID!) { const body = {query: `query($chatID: ID!) {
getChat(chatId: $chatID) {id, members{name, id}, getChat(chatId: $chatID) {id, members{name, id, level},
messages(first: 1000, offset: 0) {author {id}, createdAt, content}} messages(first: 1000, offset: 0) {author {id}, createdAt, content}}
} }
}`, variables: { }`, variables: {

@ -97,7 +97,7 @@ export class FeedService {
getBodyForGetAllPosts() { getBodyForGetAllPosts() {
const body = {query: `query { const body = {query: `query {
getPosts (first: 1000, offset: 0) {id, content, htmlContent, upvotes, downvotes, author{name, handle, id}, createdAt} getPosts (first: 1000, offset: 0) {id, content, htmlContent, upvotes, downvotes, userVote, author{name, handle, id}, createdAt}
}` }`
} }
@ -113,11 +113,12 @@ export class FeedService {
let htmlContent: string = post.htmlContent let htmlContent: string = post.htmlContent
let upvotes: number = post.upvotes let upvotes: number = post.upvotes
let downvotes: number = post.downvotes let downvotes: number = post.downvotes
let userVote: string = post.userVote
let author = new Author(post.author.id, post.author.name, post.author.handle) let author = new Author(post.author.id, post.author.name, post.author.handle)
let temp = new Date(Number(post.createdAt)) let temp = new Date(Number(post.createdAt))
let date = temp.toLocaleString("en-GB") let date = temp.toLocaleString("en-GB")
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, date, author)) posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, date, author))
} }
return posts return posts
} }

@ -7,6 +7,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<script src="https://kit.fontawesome.com/84cf838715.js"></script> <script src="https://kit.fontawesome.com/84cf838715.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head> </head>
<body> <body>
<app-root></app-root> <app-root></app-root>

@ -1,3 +1,4 @@
import 'hammerjs';
import { enableProdMode } from '@angular/core'; import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

@ -2,9 +2,8 @@
@import 'styles/vars.sass' @import 'styles/vars.sass'
body body
font-family: Arial, serif font-family: Arial, sans-serif
margin: 0 margin: 0
padding: 0 padding: 0
min-height: 100vh height: 100%
max-height: 100vh

@ -0,0 +1,40 @@
@import '~@angular/material/theming';
// Plus imports for other components in your app.
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$primary: mat-palette($mat-green);
$accent: mat-palette($mat-pink, A200, A100, A400);
// The warn palette is optional (defaults to red).
$warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$light-theme: mat-light-theme($primary, $accent, $warn);
$dark-primary: mat-palette($mat-green);
$dark-accent: mat-palette($mat-pink, A200, A100, A400);
// The warn palette is optional (defaults to red).
$dark-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
.dark-theme {
@include angular-material-theme($dark-theme);
}
.light-theme {
@include angular-material-theme($light-theme)
}
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($light-theme);

@ -18,9 +18,9 @@ $cFeedUpVote: #2cb149
$cFeedDownVote: #ff5f5f $cFeedDownVote: #ff5f5f
//Home -- Chat, Friends, Groups //Home -- Chat, Friends, Groups
$cFontWhite: #adffc1ee $cFontWhite: #fff//#adffc1ee //this is also the background color lol
$cBoxHeaderBackground: #259145 $cBoxHeaderBackground: #259145
$cBoxBodyBackground: #3deb71 $cBoxBodyBackground: #fff//#3deb71
$cMessageOwn: #cfe4c9 $cMessageOwn: #cfe4c9
$cMessageForeign: #baca5d $cMessageForeign: #baca5d

Loading…
Cancel
Save