From 1a3284397930550e944698c6f808d494e394dc1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lukas=20Mau=C3=9F?= <lukas.mauss@mni.thm.de>
Date: Thu, 22 Aug 2019 14:30:17 +0200
Subject: [PATCH] Implement account deletion

---
 .../delete-account.component.html             | 11 +++++++
 .../delete-account.component.scss             |  0
 .../delete-account.component.spec.ts          | 25 +++++++++++++++
 .../delete-account.component.ts               | 21 +++++++++++++
 .../shared/header/header.component.ts         | 31 +++++++++++++++++--
 src/app/components/shared/shared.module.ts    |  7 +++--
 src/app/services/http/user.service.ts         | 10 ++++++
 src/assets/i18n/home/de.json                  |  7 ++++-
 src/assets/i18n/home/en.json                  |  7 ++++-
 9 files changed, 112 insertions(+), 7 deletions(-)
 create mode 100644 src/app/components/shared/_dialogs/delete-account/delete-account.component.html
 create mode 100644 src/app/components/shared/_dialogs/delete-account/delete-account.component.scss
 create mode 100644 src/app/components/shared/_dialogs/delete-account/delete-account.component.spec.ts
 create mode 100644 src/app/components/shared/_dialogs/delete-account/delete-account.component.ts

diff --git a/src/app/components/shared/_dialogs/delete-account/delete-account.component.html b/src/app/components/shared/_dialogs/delete-account/delete-account.component.html
new file mode 100644
index 000000000..08d64539e
--- /dev/null
+++ b/src/app/components/shared/_dialogs/delete-account/delete-account.component.html
@@ -0,0 +1,11 @@
+<h3>{{ 'header.sure' | translate }}</h3>
+<mat-divider></mat-divider>
+<p>{{ 'header.really-delete-account' | translate }}</p>
+<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="10px">
+  <button mat-raised-button class="abort" (click)="close('abort')">
+    {{ 'header.abort' | translate }}
+  </button>
+  <button mat-raised-button class="delete" (click)="close('delete')">
+    {{ 'header.delete' | translate }}
+  </button>
+</div>
diff --git a/src/app/components/shared/_dialogs/delete-account/delete-account.component.scss b/src/app/components/shared/_dialogs/delete-account/delete-account.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/app/components/shared/_dialogs/delete-account/delete-account.component.spec.ts b/src/app/components/shared/_dialogs/delete-account/delete-account.component.spec.ts
new file mode 100644
index 000000000..8bdd17349
--- /dev/null
+++ b/src/app/components/shared/_dialogs/delete-account/delete-account.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DeleteAccountComponent } from './delete-account.component';
+
+describe('DeleteAccountComponent', () => {
+  let component: DeleteAccountComponent;
+  let fixture: ComponentFixture<DeleteAccountComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ DeleteAccountComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DeleteAccountComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/components/shared/_dialogs/delete-account/delete-account.component.ts b/src/app/components/shared/_dialogs/delete-account/delete-account.component.ts
new file mode 100644
index 000000000..ff6d4af4e
--- /dev/null
+++ b/src/app/components/shared/_dialogs/delete-account/delete-account.component.ts
@@ -0,0 +1,21 @@
+import { Component, Inject, OnInit } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
+import { RoomEditComponent } from '../../../creator/_dialogs/room-edit/room-edit.component';
+
+@Component({
+  selector: 'app-delete-account',
+  templateUrl: './delete-account.component.html',
+  styleUrls: ['./delete-account.component.scss']
+})
+export class DeleteAccountComponent implements OnInit {
+
+  constructor(public dialogRef: MatDialogRef<RoomEditComponent>,
+              @Inject(MAT_DIALOG_DATA) public data: any) { }
+
+  ngOnInit() {
+  }
+
+  close(type: string): void {
+    this.dialogRef.close(type);
+  }
+}
diff --git a/src/app/components/shared/header/header.component.ts b/src/app/components/shared/header/header.component.ts
index e90ae9a8a..8005f9d13 100644
--- a/src/app/components/shared/header/header.component.ts
+++ b/src/app/components/shared/header/header.component.ts
@@ -8,6 +8,8 @@ import { Location } from '@angular/common';
 import { TranslateService } from '@ngx-translate/core';
 import { MatDialog } from '@angular/material';
 import { LoginComponent } from '../login/login.component';
+import { DeleteAccountComponent } from '../_dialogs/delete-account/delete-account.component';
+import { UserService } from '../../../services/http/user.service';
 
 @Component({
   selector: 'app-header',
@@ -26,7 +28,8 @@ export class HeaderComponent implements OnInit {
               private notificationService: NotificationService,
               public router: Router,
               private translationService: TranslateService,
-              public dialog: MatDialog
+              public dialog: MatDialog,
+              private userService: UserService
   ) {
   }
 
@@ -83,7 +86,7 @@ export class HeaderComponent implements OnInit {
     this.translationService.get('header.logged-out').subscribe(message => {
       this.notificationService.show(message);
     });
-    this.router.navigate(['/']);
+    this.navToHome();
   }
 
   goBack() {
@@ -98,8 +101,30 @@ export class HeaderComponent implements OnInit {
     dialogRef.componentInstance.isStandard = true;
   }
 
+  navToHome() {
+    this.router.navigate(['/']);
+  }
+
+  deleteAccount(id: string) {
+    this.userService.delete(id).subscribe();
+    this.translationService.get('header.account-deleted').subscribe(msg => {
+      this.notificationService.show(msg);
+    });
+    this.navToHome();
+  }
+
   openDeleteUserDialog() {
-    this.notificationService.show('Not implemented yet');
+    const dialogRef = this.dialog.open(DeleteAccountComponent, {
+      width: '600px'
+    });
+    dialogRef.afterClosed()
+      .subscribe(result => {
+        if (result === 'abort') {
+          return;
+        } else if (result === 'delete') {
+          this.deleteAccount(this.user.id);
+        }
+      });
   }
 
 }
diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts
index 98dde61d4..ed95e571c 100644
--- a/src/app/components/shared/shared.module.ts
+++ b/src/app/components/shared/shared.module.ts
@@ -24,6 +24,7 @@ import { StatisticHelpComponent } from './_dialogs/statistic-help/statistic-help
 import { CommentComponent } from './comment/comment.component';
 import { CreateCommentComponent } from './_dialogs/create-comment/create-comment.component';
 import { PresentCommentComponent } from './_dialogs/present-comment/present-comment.component';
+import { DeleteAccountComponent } from './_dialogs/delete-account/delete-account.component';
 
 @NgModule({
   imports: [
@@ -54,7 +55,8 @@ import { PresentCommentComponent } from './_dialogs/present-comment/present-comm
     StatisticHelpComponent,
     CommentComponent,
     CreateCommentComponent,
-    PresentCommentComponent
+    PresentCommentComponent,
+    DeleteAccountComponent
   ],
   exports: [
     RoomJoinComponent,
@@ -80,7 +82,8 @@ import { PresentCommentComponent } from './_dialogs/present-comment/present-comm
     LoginComponent,
     StatisticHelpComponent,
     CreateCommentComponent,
-    PresentCommentComponent
+    PresentCommentComponent,
+    DeleteAccountComponent
   ]
 })
 export class SharedModule {
diff --git a/src/app/services/http/user.service.ts b/src/app/services/http/user.service.ts
index a05b033d8..12d1abf33 100644
--- a/src/app/services/http/user.service.ts
+++ b/src/app/services/http/user.service.ts
@@ -2,6 +2,8 @@ import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs/Observable';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { BaseHttpService } from './base-http.service';
+import { User } from '../../models/user';
+import { catchError, tap } from 'rxjs/operators';
 
 const httpOptions = {
   headers: new HttpHeaders({})
@@ -26,4 +28,12 @@ export class UserService extends BaseHttpService {
     return this.http.post<string>(connectionUrl, {
       }, httpOptions);
   }
+
+  delete(id: string): Observable<User> {
+    const connectionUrl: string = this.apiUrl.base + this.apiUrl.user + '/' + id;
+    return this.http.delete<User>(connectionUrl, httpOptions).pipe(
+      tap(_ => ''),
+      catchError(this.handleError<User>('deleteUser'))
+    );
+  }
 }
diff --git a/src/assets/i18n/home/de.json b/src/assets/i18n/home/de.json
index 16ef0bbb5..cc91281ea 100644
--- a/src/assets/i18n/home/de.json
+++ b/src/assets/i18n/home/de.json
@@ -9,7 +9,12 @@
     "my-account": "Konto",
     "id": "ID",
 		"moderation-enabled": "Moderiert",
-		"delete-account": "Account löschen"
+		"delete-account": "Account löschen",
+		"sure": "Sind Sie sicher?",
+		"really-delete-account": "Wollen Sie ihr Konto wirklich löschen?",
+		"account-deleted": "Ihr Konto wurde erfolgreich gelöscht.",
+		"abort": "Abbrechen",
+		"delete": "Löschen"
 	},
 	"login-page": {
 		"creator": "Dozent/in",
diff --git a/src/assets/i18n/home/en.json b/src/assets/i18n/home/en.json
index 516c3c313..382fa00a7 100644
--- a/src/assets/i18n/home/en.json
+++ b/src/assets/i18n/home/en.json
@@ -9,7 +9,12 @@
     "my-account": "My account",
     "id": "ID",
 		"moderation-enabled": "Moderated",
-		"delete-account": "Delete account"
+		"delete-account": "Delete account",
+    "sure": "Are you sure?",
+    "really-delete-account": "Do you really want to delete your account?",
+    "account-deleted": "Your account has been deleted successfully.",
+    "abort": "Cancel",
+    "delete": "Delete"
 	},
 	"login-page": {
 		"creator": "Professor",
-- 
GitLab