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"
],
"styles": [
"src/styles/greenvironment-material-theme.scss",
"src/styles.sass"
],
"scripts": []
@ -83,6 +84,7 @@
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles/greenvironment-material-theme.scss",
"src/styles.sass"
],
"scripts": [],

8360
package-lock.json generated

File diff suppressed because it is too large Load Diff

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

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

@ -1,45 +1,12 @@
@import '../styles/mixins.sass'
@import '../styles/vars.sass'
/*
#content
grid-template: 7.5% 92.5% / 25% 50% 25%
display: grid
min-height: 100vh
max-height: 100vh*/
#imprint
background-color: $cSecondaryBackground
grid-template: 15% 70% 15% / 15% 70% 15%
display: grid
min-height: 100vh
max-height: 100vh
html, body
margin: 0
height: 100%
#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']
})
export class AppComponent implements OnInit {
constructor(private data: DatasharingService, private selfservice: SelfService) { }
userInfo: User
@ -37,4 +38,5 @@ export class AppComponent implements OnInit {
this.selfservice.checkIfLoggedIn();
}
}
}

@ -26,6 +26,33 @@ import { ProfileComponent } from './components/profile/profile.component';
import { ImprintComponent } from './components/imprint/imprint.component';
import { AboutComponent } from './components/about/about.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: {} };
@ -58,7 +85,8 @@ const appRoutes: Routes = [
PostlistComponent,
ImprintComponent,
AboutComponent,
ProfileComponent
ProfileComponent,
MainNavigationComponent
],
imports: [
BrowserModule,
@ -69,7 +97,30 @@ const appRoutes: Routes = [
HttpClientModule,
RouterModule.forRoot(
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: [],
bootstrap: [AppComponent]

@ -1,9 +1,19 @@
<div id="about">
<div id="aboutcontainer">
<h1>What's Greenvironment?</h1>
<h2>Hello!</h2>
<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>
<p>We believe, that together we can do amazing things to protect our environment and keep it clean and green.</p>
<a href="/register">You aren't part of greenvironment yet? - join us here</a>
</div>
</div>
<div id="text0" style="text-align: center;">
<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>
<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>
</div>
<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">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>

@ -1,22 +1,24 @@
@import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass'
@import '~@angular/material/theming'
@import '../../../styles/greenvironment-material-theme.scss'
#about
background-color: $cSecondaryBackground
grid-template: 15% 70% 15% / 15% 70% 15%
display: grid
min-height: 90vh
max-height: 90vh
#text0, #text2
padding: 2em
max-width: 100%
min-height: 50%
background-color: mat-color($primary)
#text1
padding: 2em
min-height: 50%
max-width: 100%
#aboutcontainer
@include gridPosition(2, 2,2,2)
background-color: $cPrimaryBackground
padding: 1em
overflow: auto
.big-icon
//color: white
transform: scale(2)
input
margin: 0.25em
#header
@include gridPosition(1, 2, 1, 2)
a
color: $cHeadPrimaryBackground
.link-button
width: 100%
max-width: 30em
margin-bottom: 1em

@ -1,8 +1,9 @@
<div id='chatlist'>
<div id="header">
<!--<div id="header">
<span class="title">Chats</span>
<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 class="chatitem" *ngFor="let chat of childChats"
[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>
<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>
</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 id='completeFeed'>
<div id='feedchooser'>
<div id="complete-feed">
<!--<div id='feedchooser'>
<button id="new" (click)="showNew()">New</button>
<button id='mostliked' (click)="showMostLiked()">Most Liked</button>
</div>
</div>-->
<div id="feedlist">
<div *ngIf = "viewNew">
<feed-postlist (voteEvent)="refresh($event)" [childPostList]="parentSelectedPostList"></feed-postlist>
@ -17,3 +49,4 @@
</div>
</div>
</div>
</div>

@ -1,82 +1,37 @@
@import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass'
#postinput
@include gridPosition(1, 2, 1, 2)
margin: 0.5em
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
@include gridPosition(2, 3, 1, 2)
display: grid
grid-template: 5% 95% /100%
overflow: auto
background-color: $cFontWhite
#home
width: 100%
height: 100%
#complete-feed
box-sizing: border-box
display: flex
width: 100%
padding: 0.5em
#feedlist
width: 100%
#feedchooser
@include gridPosition(1, 2, 1, 2)
display: grid
grid-template: 100% /50% 50%
background-color: $cFontWhite
padding: 0
#input
width: 100%
padding-left: 0.5em
padding-right: 0.5em
#action-chooser
width: 100%
padding-left: 0.5em
padding-right: 0.5em
#check
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)
padding-left: 0.5em
#feedlist
@include gridPosition(2, 3, 1, 2)
overflow: auto
#post-button
width: 100%
height: 100%
.feeditemPicture
background-color: $cFeedItemBackground
min-height: 2em
margin: 0.5em
padding: 0.25em
border-radius: 0.25em
.itemhead
align-items: flex-start
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 { Post } from 'src/app/models/post';
import { FeedService } from 'src/app/services/feed/feed.service';
import { Actionlist } from 'src/app/models/actionlist';
@Component({
selector: 'home-feed',
@ -17,6 +18,8 @@ export class FeedComponent implements OnInit {
parentSelectedPostList: Array<Post>
actionlist: Actionlist = new Actionlist();
constructor(private feedService: FeedService) { }
ngOnInit() {
@ -24,6 +27,7 @@ export class FeedComponent implements OnInit {
this.feedNew = this.feedService.renderAllPosts(response.json())
this.parentSelectedPostList = this.feedNew
this.feedMostLiked = this.feedNew
console.log(this.feedNew)
})
}
@ -37,6 +41,7 @@ export class FeedComponent implements OnInit {
}
showNew() {
console.log("showNew()")
this.feedService.getAllPostsRaw().subscribe(response => {
this.feedNew = this.feedService.renderAllPosts(response.json())
this.parentSelectedPostList = this.feedNew})
@ -45,6 +50,7 @@ export class FeedComponent implements OnInit {
}
showMostLiked() {
console.log("showMostLiked()")
this.feedService.getAllPostsRaw().subscribe(response => {
this.feedMostLiked = this.feedService.renderAllPosts(response.json())
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="usertag">
<span class="title">{{post.author.name}}</span>
@ -17,4 +17,33 @@
<span id="upvotes">{{post.upvotes}}</span>
</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/vars.sass'
.feeditem
background-color: $cFeedItemBackground
min-height: 2em
//max-heigth: 5em
margin: 0.5em
padding: 0.25em
border-radius: 0.25em
.post
box-sizing: border-box
width: 100%
margin-top: 0.5em
::ng-deep .mat-card-header-text
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">
<home-chatmanager id="chatcontainer" *ngIf="loggedIn"></home-chatmanager>
<home-feed id="feedcontainer"></home-feed>
<home-social id="socialcontainer" *ngIf="loggedIn"></home-social>
</div>
<div id="content" fxShow="true" fxHide.lt-md="true">
<div id="chat"><home-chatmanager id="chatcontainer" *ngIf="!loggedIn"></home-chatmanager></div>
<div id="feed"><home-feed id="feedcontainer"></home-feed></div>
<div id="social"><home-social id="socialcontainer" *ngIf="!loggedIn"></home-social></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'
#content
grid-template: 100%/ 25% 50% 25%
display: grid
min-height: 90vh
max-height: 90vh
background-color: $cFontWhite
#chatcontainer
@include gridPosition(1, 3, 1, 2)
background-color: $cBoxBodyBackground
overflow: auto
#feedcontainer
@include gridPosition(1, 3, 2, 3)
display: grid
grid-template: 10% 90% /100%
background-color: $cFontWhite
overflow: auto
#socialcontainer
@include gridPosition(1, 3, 3, 4)
display: grid
grid-template: 50% 50% /100%
background-color: $cBoxBodyBackground
overflow: auto
position: fixed
width: 100%
height: calc(100% - 56px)
#chat
box-sizing: content-box
height: 100%
width: 25%
float: left
overflow-y: auto
#feed
box-sizing: content-box
height: 100%
width: 50%
float: left
overflow-y: auto
#social
box-sizing: content-box
height: 100%
width: 25%
float: left
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="imprintcontainer">
<h1>Imprint</h1>
<p>The greenvironment network is being developed by the greenvironment team</p>
<h2>Contact</h2>
<p>Email: nick.derkoenig@greenvironment.net</p>
</div>
<p>The greenvironment network is being developed by the greenvironment team</p>
<h2>Contact</h2>
<p>Email: nick.derkoenig@greenvironment.net</p>
</div>

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

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

@ -2,21 +2,40 @@
@import '../../../styles/vars.sass'
#login
background-color: $cSecondaryBackground
grid-template: 8% 77% 15% / 15% 70% 15%
display: grid
height: 90vh
#logincontainer
@include gridPosition(2, 2,2,2)
background-color: $cPrimaryBackground
padding: 1em
overflow: auto
input
padding: 2em
max-width: 35em
margin: 0 auto
.example-container
display: flex
flex-direction: column
.example-container > *
width: 100%
.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
.mat-stroked-button
width: 100%
a
color: $cHeadPrimaryBackground

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import {FormControl, Validators} from '@angular/forms';
import { Login } from 'src/app/models/login';
import { LoginService } from 'src/app/services/login/login.service';
import {Router} from '@angular/router';
@ -11,6 +12,7 @@ import * as sha512 from 'js-sha512';
})
export class LoginComponent implements OnInit {
login: Login
hide = true;
errorOccurred: boolean = false;
errorMessage: string;
@ -18,6 +20,10 @@ export class LoginComponent implements OnInit {
this.login = {passwordHash: null, email: null};
}
public getErrorMessage(){
return this.errorMessage;
}
public loginError(error : any){
console.log(error.errors[0].message);
this.errorOccurred = true;
@ -36,6 +42,7 @@ export class LoginComponent implements OnInit {
this.loginService.login(this.login, error => this.loginError(error.json()));
}
email = new FormControl('', [Validators.required, Validators.email]);
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="profilecontainer" *ngIf="profileNotFound == false">
<h1>Profile</h1>
<table style="width:100%">
<tr>
<td>name: </td>
<td>{{user.username}}</td>
</tr>
<tr>
<td>handle: </td>
<td>{{user.handle}}</td>
</tr>
<tr>
<td>profile ID: </td>
<td>{{user.userID}}</td>
</tr>
<tr>
<td>points: </td>
<td>{{user.points}}</td>
<tr>
<td>level: </td>
<td>{{user.level}} ({{rankname}})</td>
</tr>
</table>
<h2>What does the level mean?</h2>
<div id="profilecontainer" [hidden]="profileNotFound">
<div id="profile-card-container">
<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>
<div class="mat-header-cell">name: </div>
<td>{{user.username}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">handle: </div>
<td>{{user.handle}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">profileID: </div>
<td>{{user.userID}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">points: </div>
<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>
<div class="mat-header-cell">level name: </div>
<td>{{rankname}}</td>
</tr>
</table>
</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.
Collect 100 points to level up! The levels are called:
</p>
<ol start="0">
<li *ngFor= "let level of levellist.levels">
{{level.name}}
</li>
</ol>
<h2>How to level up?</h2>
<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 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>
<th>points </th>
<th>action</th>
@ -48,7 +96,7 @@
<td>{{action.points}}</td>
<td>{{action.name}}</td>
</tr>
</table>
</table>-->
</div>
<div id="profilecontainer" *ngIf="profileNotFound">
<h1>Profile not found :(</h1>

@ -1,20 +1,38 @@
@import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass'
#profile
background-color: $cSecondaryBackground
grid-template: 3% 94% 3% / 10% 80% 10%
display: grid
min-height: 90vh
max-height: 90vh
#profile
padding: 2em
max-width: 1200px
margin: 0 auto
#profilecontainer
@include gridPosition(2, 2,2,2)
//grid-template: 15% 15% 15% 15% 15% 15% / 100%
background-color: $cPrimaryBackground
padding: 1em
overflow: auto
#profile-card-container
margin: 0 auto
width: 100%
max-width: 690px
th
text-align: left
.mat-table
width: 100%
max-width: 690px
margin: 0 auto
.mat-header-cell
padding-right: 0.5em
.profile-picture
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 {Http, URLSearchParams, Headers} from '@angular/http';
import { User } from 'src/app/models/user';
import { Actionlist } from 'src/app/models/actionlist';
import { Levellist } from 'src/app/models/levellist';
import { environment } from 'src/environments/environment';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.sass']
})
export class ProfileComponent implements OnInit {
actionlist: Actionlist = new Actionlist();
levellist: Levellist = new Levellist();
actionlist: Actionlist = new Actionlist()
levellist: Levellist = new Levellist()
user: User = new User()
id : string
rankname: string;
profileNotFound : boolean = false;
rankname: string
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) { }
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() {
this.dataSource.sort = this.sort;
this.id = this.router.url.substr(this.router.url.lastIndexOf("/") + 1);
//let url = './graphql'
let url = environment.graphQLUrl

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

@ -2,20 +2,36 @@
@import '../../../styles/vars.sass'
#register
background-color: $cSecondaryBackground
grid-template: 8% 77% 15% / 15% 70% 15%
display: grid
min-height: 90vh
max-height: 90vh
#registercontainer
@include gridPosition(2, 2,2,2)
grid-template: 15% 15% 15% 15% 15% 15% / 100%
background-color: $cPrimaryBackground
padding: 1em
overflow: auto
input
margin: 0.25em
a
color: $cHeadPrimaryBackground
padding: 2em
max-width: 35em
margin: 0 auto
.example-container
display: flex
flex-direction: column
.example-container > *
width: 100%
.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
.mat-stroked-button
width: 100%

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

@ -1,12 +1,23 @@
<div id="header">
<!--<div id="header">
<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="invitations" type="submit"><span><i class="fa fa-envelope-o fa-3x" aria-hidden="true"></i></span></button>
</div>
<div id="friendslist">
<div class="frienditem" *ngFor="let friend of friends"
</div>-->
<mat-toolbar><span>Friends</span></mat-toolbar>
<div id="friendlist">
<!--<div class="frienditem" *ngFor="let friend of friends"
[class.selected]="friend === selectedFriend" (click)="showFriendProfile(friend)">
<div class="picture">Pic</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>

@ -2,31 +2,18 @@
@import '../../../../styles/vars.sass'
@import '../social.component.sass'
#friendslist
overflow: auto
@include gridPosition(2, 3, 1, 2)
div:hover
background-color: darken($cPrimaryBackground, 10%)
cursor: pointer
.frienditem
background-color: $cPrimaryBackground
height: 3em
margin: 0.2em
padding: 0.25em
border-radius: 0.25em
//border: solid
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%
#friendlist
padding: 0.5em
.friend-card
box-sizing: border-box
width: 100%
margin-top: 0.5em
cursor: pointer
.mat-card-subtitle
margin: 0
.profile-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
background-size: cover

@ -35,13 +35,14 @@ export class FriendsComponent implements OnInit {
}
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 {
const body = {query: `query($userId: ID) {
getUser(userId:$userId) {
name
level
}
}`, variables: {
userId: pId

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

@ -2,31 +2,16 @@
@import '../../../../styles/vars.sass'
@import '../social.component.sass'
#groupslist
overflow: auto
@include gridPosition(2, 3, 1, 2)
div:hover
background-color: darken($cPrimaryBackground, 10%)
cursor: pointer
.groupitem
background-color: $cPrimaryBackground
height: 3em
margin: 0.2em
padding: 0.25em
border-radius: 0.25em
//border: solid
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%
#grouplist
padding: 0.5em
.group-card
box-sizing: border-box
width: 100%
margin-top: 0.5em
.mat-card-subtitle
margin: 0
.group-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
background-size: cover

@ -2,43 +2,13 @@
@import '../../../styles/vars.sass'
#friendscontainer
@include gridPosition(1, 2, 1, 2)
display: grid
grid-template: 15% 85% /100%
box-sizing: content-box
height: 50%
width: 100%
overflow: auto
#groupscontainer
@include gridPosition(2, 3, 1, 2)
display: grid
grid-template: 15% 85% /100%
#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)
box-sizing: content-box
height: 50%
width: 100%
overflow: auto

@ -1,5 +1,13 @@
export interface Action {
id: number
name: string;
points: number;
}
export class Actionlist{
actions: { id: number, name: string, points: number}[] = [
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 },
@ -9,7 +17,7 @@ export class Actionlist{
{ 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: 9, name: "buy a fair trade / local product", points: 1 },
{ 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 {
levellist: Levellist = new Levellist();
id: number
name: string
rankname: string
constructor(pId: number, pName: string) {
constructor(pId: number, pName: string, pLevel: number) {
this.id = pId
this.name = pName
this.rankname = this.levellist.getLevelName(pLevel);
}
}

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

@ -7,14 +7,16 @@ export class Post {
date: string
upvotes: number
downvotes: number
userVote: string
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.content = pContent
this.htmlContent = pHtmlContent
this.upvotes = pUpvotes
this.downvotes = pDownvotes
this.userVote = pUserVote
this.date = pDate
this.author = pAuthor
}

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

@ -97,7 +97,7 @@ export class FeedService {
getBodyForGetAllPosts() {
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 upvotes: number = post.upvotes
let downvotes: number = post.downvotes
let userVote: string = post.userVote
let author = new Author(post.author.id, post.author.name, post.author.handle)
let temp = new Date(Number(post.createdAt))
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
}

@ -7,6 +7,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<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>
<body>
<app-root></app-root>

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

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

@ -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
//Home -- Chat, Friends, Groups
$cFontWhite: #adffc1ee
$cFontWhite: #fff//#adffc1ee //this is also the background color lol
$cBoxHeaderBackground: #259145
$cBoxBodyBackground: #3deb71
$cBoxBodyBackground: #fff//#3deb71
$cMessageOwn: #cfe4c9
$cMessageForeign: #baca5d

Loading…
Cancel
Save