diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 10631d8..595c8f7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -17,6 +17,7 @@ import { HomeComponent } from './components/home/home.component'; import { SocialComponent } from './components/social/social.component'; import { GroupsComponent } from './components/social/groups/groups.component'; import { DialogCreateGroupComponent } from './components/social/groups/groups.component'; +import { DialogCreateEventComponent } from './components/group/group.component'; import { ChatmanagerComponent } from './components/chatmanager/chatmanager.component'; import { ChatlistComponent } from './components/chatlist/chatlist.component'; import { PostlistComponent } from './components/feed/postlist/postlist.component'; @@ -61,6 +62,8 @@ import {MatIconRegistry} from '@angular/material/icon'; import {MatDialogModule} from '@angular/material/dialog'; import {MatTooltipModule} from '@angular/material/tooltip'; import {MatExpansionModule} from '@angular/material/expansion'; +import {MatDatepickerModule} from '@angular/material/datepicker'; +import {MatNativeDateModule} from '@angular/material/'; // import logo from 'src/assets/gv-new-logo.svg'; import logo from '!!raw-loader!./gv-new-logo-white.svg'; @@ -101,7 +104,8 @@ const appRoutes: Routes = [ MainNavigationComponent, SearchComponent, DialogCreateGroupComponent, - GroupComponent + GroupComponent, + DialogCreateEventComponent ], imports: [ BrowserModule, @@ -110,6 +114,8 @@ const appRoutes: Routes = [ SocketIoModule.forRoot(config), GraphQLModule, HttpClientModule, + MatDatepickerModule, + MatNativeDateModule, RouterModule.forRoot( appRoutes ), @@ -140,9 +146,10 @@ const appRoutes: Routes = [ MatProgressSpinnerModule, MatDialogModule, MatTooltipModule, - MatExpansionModule + MatExpansionModule, + MatDatepickerModule ], - entryComponents: [ DialogCreateGroupComponent ], + entryComponents: [ DialogCreateGroupComponent, DialogCreateEventComponent ], providers: [], bootstrap: [AppComponent] }) diff --git a/src/app/components/feed/postlist/postlist.component.ts b/src/app/components/feed/postlist/postlist.component.ts index c5e4f52..bcb3afe 100644 --- a/src/app/components/feed/postlist/postlist.component.ts +++ b/src/app/components/feed/postlist/postlist.component.ts @@ -21,12 +21,16 @@ export class PostlistComponent implements OnInit { voteUp(pPost: Post) { this.feedService.upvote(pPost.id).subscribe(response => { - this.voteEvent.emit(true); }); + // this.voteEvent.emit(true); + pPost.userVote = response.json().data.vote; + }); } voteDown(pPost: Post) { this.feedService.downvote(pPost.id).subscribe(response => { - this.voteEvent.emit(true); }); + // this.voteEvent.emit(true); + pPost.userVote = response.json().data.vote; + }); } deletePost(pPost: Post) { diff --git a/src/app/components/group/dialog.html b/src/app/components/group/dialog.html new file mode 100644 index 0000000..80b4cff --- /dev/null +++ b/src/app/components/group/dialog.html @@ -0,0 +1,15 @@ +

Create a new event!

+
+ + + + + + + + +
+
+ + +
diff --git a/src/app/components/group/group.component.html b/src/app/components/group/group.component.html index 55dfe65..764d2a4 100644 --- a/src/app/components/group/group.component.html +++ b/src/app/components/group/group.component.html @@ -1,23 +1,110 @@
- + +
{{groupProfile.name}} - created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}} - +
+ + +
+
+ +
+ created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}} +
+
+ +
+ {{groupProfile.members.length}} member(s) +
+
+
+ + + +
+ {{groupProfile.name}} + created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}} +
+ + +
-
+
{{groupProfile.members.length}} member(s)
+ + + + + Events + + +
+ + + {{event.name}} + {{event.date}} + + + +
+
+ + + + Members + + +
+ + +
+ {{user.username}} + {{user.handle}} +
+ +
+
+
+
+
+

Group not found :(

diff --git a/src/app/components/group/group.component.sass b/src/app/components/group/group.component.sass index 335d7d1..649f40c 100644 --- a/src/app/components/group/group.component.sass +++ b/src/app/components/group/group.component.sass @@ -6,12 +6,14 @@ width: 100% height: calc(100% - 56px) overflow: scroll + overflow-x: hidden #profile padding: 2em max-width: 1200px margin: 0 auto +$mat-card-header-size: 100px !default #profile-card-container margin: 0 auto width: 100% @@ -19,15 +21,16 @@ .icon-box text-align: right width: 100% +.button-box + width: 100% + text-align: right .request-button - margin-top: 0.5em - margin-bottom: 0.5em - margin-left: auto + margin: auto 0 #toolbar margin-top: 32px .mat-toolbar-row max-height: 40px - #info-box + .info-box font-size: 14px margin-left: calc(100px + 0.5em) .info @@ -36,30 +39,45 @@ margin: 0 0.5em #handle font-size: 14px + .profile-picture + background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg) + height: $mat-card-header-size + width: $mat-card-header-size + border-radius: 50% + flex-shrink: 0 + background-size: cover + // Makes `` tags behave like `background-size: cover`. Not supported + // in IE, but we're using it as a progressive enhancement. + object-fit: cover - -.mat-table +.card + box-sizing: border-box width: 100% - max-width: 690px - margin: 0 auto -.mat-header-cell - padding-right: 0.5em - -$mat-card-header-size: 100px !default -.profile-picture - background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg) - height: $mat-card-header-size - width: $mat-card-header-size - border-radius: 50% - flex-shrink: 0 - background-size: cover - // Makes `` tags behave like `background-size: cover`. Not supported - // in IE, but we're using it as a progressive enhancement. - object-fit: cover - - - -#postlist - margin: 0.5em auto - padding: 0 - max-width: 690px \ No newline at end of file + margin-top: 0.5em + outline: none + user-select: none + /deep/ .mat-card-header-text + width: 1000% + margin: 0 + margin-left: 16px + .mat-card-subtitle + margin: 0 + word-break: break-all + .mat-card-title + margin: 0 + word-break: break-all + .request-button + margin-top: 0.5em + margin-bottom: 0.5em + .profile-picture + background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg) + background-size: cover + .profile-picture:hover + cursor: pointer +.pointer + cursor: pointer + +/deep/ .mat-expansion-panel + background: #e6e6e6 +/deep/.dark-theme .mat-expansion-panel + background: #121212 \ No newline at end of file diff --git a/src/app/components/group/group.component.ts b/src/app/components/group/group.component.ts index 3fe5209..6d42205 100644 --- a/src/app/components/group/group.component.ts +++ b/src/app/components/group/group.component.ts @@ -6,7 +6,38 @@ import { RequestService } from 'src/app/services/request/request.service'; import { DatasharingService } from '../../services/datasharing.service'; import { GroupService } from 'src/app/services/group/group.service'; import { Group } from 'src/app/models/group'; +import {MatDialog, MatDialogRef} from '@angular/material/dialog'; +// DIALOG COMPONENT to create events +@Component({ + selector: 'dialog-overview-example-dialog', + templateUrl: 'dialog.html', +}) +export class DialogCreateEventComponent { + groupId: string; + + constructor( + public dialogRef: MatDialogRef, + private group: GroupService, + private router: Router) { + this.groupId = this.router.url.substr(this.router.url.lastIndexOf('/') + 1); + } + + onNoClick(): void { + this.dialogRef.close(); + } + + createEvent(name: string, date: string) { + name = name.trim(); + if (name && date) { + this.group.createEvent(name, (new Date(date)).getTime().toString(), this.groupId); + this.dialogRef.close(); + } + } + +} + +// GROUP COMPONENT @Component({ selector: 'app-profile', templateUrl: './group.component.html', @@ -17,12 +48,14 @@ export class GroupComponent implements OnInit { groupProfile: Group = new Group(); self: User; id: string; + isAdmin = false; groupNotFound = false; loading = false; constructor( private router: Router, + public dialog: MatDialog, private requestService: RequestService, private data: DatasharingService, private groupService: GroupService) { @@ -48,17 +81,41 @@ export class GroupComponent implements OnInit { }); this.groupService.getGroupData(this.id); this.groupService.group.subscribe(response => { - if (response) { - this.groupProfile = response; - // tslint:disable-next-line:max-line-length - this.groupProfile.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(this.groupProfile.id, this.self); - } else { this.groupNotFound = true; } - this.loading = false; - }); + this.isAdmin = false; + if (response) { + this.groupProfile = response; + // tslint:disable-next-line:max-line-length + this.groupProfile.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(this.groupProfile.id, this.self); + for (const admin of this.groupProfile.admins) { + if (admin.userID === this.self.userID) { + this.isAdmin = true; + } + } + for (const member of this.groupProfile.members) { + member.allowedToSendRequest = this.requestService.isAllowedToSendRequest(member.userID, this.self); + } + } else { this.groupNotFound = true; } + this.loading = false; + }); + } + + openDialog(): void { + const dialogRef = this.dialog.open(DialogCreateEventComponent, { + width: '250px' + }); } public joinGroup(group: Group) { group.allowedToJoinGroup = false; this.requestService.joinGroup(group); } + + public showUserProfile(user: User) { + this.router.navigate(['profile/' + user.userID]); + } + + public sendFriendRequest(user: User) { + user.allowedToSendRequest = false; + this.requestService.sendFriendRequest(user); + } } diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html index b791d85..12bad54 100644 --- a/src/app/components/profile/profile.component.html +++ b/src/app/components/profile/profile.component.html @@ -1,6 +1,41 @@
- + + + +
+ {{userProfile.username}} + +
+ +
+ @{{userProfile.handle}} +
+
+ +
+ {{rankname}} ({{userProfile.points}} points) +
+
+ +
+ {{userProfile.friendCount}} friends + {{userProfile.groupCount}} groups +
+
+ +
+ joined on {{userProfile.joinedAt}} +
+
+
+ +
{{userProfile.username}} @@ -13,7 +48,7 @@
-
+
{{rankname}} ({{userProfile.points}} points) {{userProfile.friendCount}} friends {{userProfile.groupCount}} groups diff --git a/src/app/components/profile/profile.component.sass b/src/app/components/profile/profile.component.sass index 335d7d1..9acedb2 100644 --- a/src/app/components/profile/profile.component.sass +++ b/src/app/components/profile/profile.component.sass @@ -6,6 +6,7 @@ width: 100% height: calc(100% - 56px) overflow: scroll + overflow-x: hidden #profile padding: 2em @@ -27,11 +28,12 @@ margin-top: 32px .mat-toolbar-row max-height: 40px - #info-box + .info-box font-size: 14px margin-left: calc(100px + 0.5em) - .info - margin-right: 3em + .info + margin-right: 1em + font-size: 14px #username margin: 0 0.5em #handle diff --git a/src/app/models/event.ts b/src/app/models/event.ts new file mode 100644 index 0000000..95d9151 --- /dev/null +++ b/src/app/models/event.ts @@ -0,0 +1,11 @@ +export class Event { + id: number; + name: string; + date: string; + + constructor(pId: number, pName: string, pdate: string) { + this.id = pId; + this.name = pName; + this.date = pdate; + } +} diff --git a/src/app/models/group.ts b/src/app/models/group.ts index 27b5b75..0395207 100644 --- a/src/app/models/group.ts +++ b/src/app/models/group.ts @@ -1,4 +1,5 @@ import { User } from 'src/app/models/user'; +import { Event } from 'src/app/models/event'; export class Group { id: number; @@ -7,5 +8,6 @@ export class Group { creator: User = new User(); members: User[] = new Array(); admins: User[] = new Array(); + events: Event[] = new Array(); allowedToJoinGroup = false; } diff --git a/src/app/services/group/group.service.ts b/src/app/services/group/group.service.ts index 6a0adea..0f064ba 100644 --- a/src/app/services/group/group.service.ts +++ b/src/app/services/group/group.service.ts @@ -3,7 +3,8 @@ import { Http } from '@angular/http'; import { Author } from 'src/app/models/author'; import { environment } from 'src/environments/environment'; import { User } from 'src/app/models/user'; -import { Observable, Subject } from 'rxjs'; +import { Event } from 'src/app/models/event'; +import { Observable, BehaviorSubject } from 'rxjs'; import { Group } from 'src/app/models/group'; @Injectable({ @@ -11,7 +12,7 @@ import { Group } from 'src/app/models/group'; }) export class GroupService { - public group: Subject = new Subject(); + public group: BehaviorSubject = new BehaviorSubject(new Group()); constructor(private http: Http) { } @@ -34,6 +35,7 @@ export class GroupService { creator{id name handle} admins{id name handle} members{id name handle} + events{id name dueDate} } }`, variables: { groupId: id @@ -44,8 +46,6 @@ export class GroupService { public renderGroup(response: any): Group { const group = new Group(); - const members: User[] = new Array(); - const admins: User[] = new Array(); if (response.data.getGroup != null) { group.id = response.data.getGroup.id; group.name = response.data.getGroup.name; @@ -57,19 +57,45 @@ export class GroupService { user.userID = member.id; user.username = member.name; user.handle = member.handle; - members.push(user); + group.members.push(user); } - group.members = members; for (const admin of response.data.getGroup.admins) { const user = new User(); user.userID = admin.id; user.username = admin.name; user.handle = admin.handle; - admins.push(user); + group.admins.push(user); + } + for (const event of response.data.getGroup.events) { + const temp = new Date(Number(event.dueDate)); + const date = temp.toLocaleString('en-GB'); + group.events.push(new Event(event.id, event.name, date)); } - group.admins = admins; return group; } return null; } + + public createEvent(name: string, date: string, groupId: string) { + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + const body = {query: `mutation($groupId: ID!, $name: String, $date: String) { + createEvent(name: $name, dueDate: $date, groupId: $groupId) { + id + name + dueDate + } + }`, variables: { + name: name, + date: date, + groupId: groupId + }}; + + this.http.post(environment.graphQLUrl, body).subscribe(response => { + const event = response.json().data.createEvent; + const temp = new Date(Number(event.dueDate)); + const pdate = temp.toLocaleString('en-GB'); + this.group.next(this.renderGroup(this.group.getValue().events.push(new Event(event.id, event.name, pdate)))); + }); + } }