Skip to content
Snippets Groups Projects
Commit 09d40eb7 authored by Hanna Pelsholen Busterud's avatar Hanna Pelsholen Busterud
Browse files

Issue: Lagt til redigering for brukerprofil (#13)

parent dcf4c795
No related branches found
No related tags found
No related merge requests found
Showing
with 1750 additions and 19919 deletions
This diff is collapsed.
...@@ -20,16 +20,16 @@ ...@@ -20,16 +20,16 @@
"@angular/platform-browser-dynamic": "~11.1.1", "@angular/platform-browser-dynamic": "~11.1.1",
"@angular/router": "~11.1.1", "@angular/router": "~11.1.1",
"@auth0/angular-jwt": "^5.0.2", "@auth0/angular-jwt": "^5.0.2",
"rxjs": "~6.6.0", "rxjs": "^6.6.6",
"tslib": "^2.0.0", "tslib": "^2.0.0",
"zone.js": "~0.11.3" "zone.js": "^0.11.4"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.1101.2", "@angular-devkit/build-angular": "^0.1101.4",
"@angular/cli": "~11.1.2", "@angular/cli": "^11.1.4",
"@angular/compiler-cli": "~11.1.1", "@angular/compiler-cli": "~11.1.1",
"@types/jasmine": "~3.6.0", "@types/jasmine": "^3.6.6",
"@types/node": "^12.11.1", "@types/node": "^12.20.5",
"codelyzer": "^6.0.0", "codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0", "jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0", "jasmine-spec-reporter": "~5.0.0",
...@@ -41,6 +41,6 @@ ...@@ -41,6 +41,6 @@
"protractor": "~7.0.0", "protractor": "~7.0.0",
"ts-node": "~8.3.0", "ts-node": "~8.3.0",
"tslint": "~6.1.0", "tslint": "~6.1.0",
"typescript": "~4.1.2" "typescript": "^4.1.5"
} }
} }
...@@ -6,6 +6,8 @@ import { PostListComponent } from './posts/post-list/post-list.component'; ...@@ -6,6 +6,8 @@ import { PostListComponent } from './posts/post-list/post-list.component';
import { UserRegistrationFormComponent } from './users/user-registration-form/user-registration-form.component'; import { UserRegistrationFormComponent } from './users/user-registration-form/user-registration-form.component';
import { UserLoginFormComponent } from './users/user-login-form/user-login-form.component'; import { UserLoginFormComponent } from './users/user-login-form/user-login-form.component';
import { UserProfileComponent } from './users/user-profile/user-profile.component'; import { UserProfileComponent } from './users/user-profile/user-profile.component';
import { UserProfileEditFormComponent } from './users/user-profile-edit-form/user-profile-edit-form.component';
const routes: Routes = [ const routes: Routes = [
{ path: 'annonse/ny', component: PostFormComponent }, { path: 'annonse/ny', component: PostFormComponent },
...@@ -13,7 +15,8 @@ const routes: Routes = [ ...@@ -13,7 +15,8 @@ const routes: Routes = [
{ path: 'annonse', component: PostListComponent }, { path: 'annonse', component: PostListComponent },
{ path: 'annonse/:id', component: PostDetailsComponent }, { path: 'annonse/:id', component: PostDetailsComponent },
{ path: 'profile', component: UserProfileComponent }, { path: 'profil', component: UserProfileComponent },
{ path: 'profil/rediger', component: UserProfileEditFormComponent},
{ path: 'register', component: UserRegistrationFormComponent }, { path: 'register', component: UserRegistrationFormComponent },
{ path: 'login', component: UserLoginFormComponent } { path: 'login', component: UserLoginFormComponent }
]; ];
......
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
<a href="/annonse/ny">/annonse/ny</a> <a href="/annonse/ny">/annonse/ny</a>
<a href="/register">/register</a> <a href="/register">/register</a>
<a href="/login">/login</a> <a href="/login">/login</a>
<a href="/profile">/profile</a> <a href="/profil">/profil</a>
<a href="/logout">/logout</a> <a href="/logout">/logout</a>
</nav> </nav>
</div> </div>
<div class="splash"> <div class="splash">
<div class="title"><h1>SELLPOINT</h1></div> <div class="title">
<h1>SELLPOINT</h1>
</div>
<div class="wave"> <div class="wave">
<div class="waveImg"></div> <div class="waveImg"></div>
<div class="categoryWrapper"> <div class="categoryWrapper">
...@@ -21,7 +23,8 @@ ...@@ -21,7 +23,8 @@
</div> </div>
<div class="cta"> <div class="cta">
<h2>Lorem Ipsum</h2> <h2>Lorem Ipsum</h2>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.
<div class="buttons"> <div class="buttons">
<a href="/register" class="btn">Register deg!</a> <a href="/register" class="btn">Register deg!</a>
<a href="javascript:void(0)" class="btn pink">Les mer</a> <a href="javascript:void(0)" class="btn pink">Les mer</a>
...@@ -36,7 +39,9 @@ ...@@ -36,7 +39,9 @@
</div> </div>
<div class="footer"> <div class="footer">
<div class="logo"><h1>SELLPOINT LOGO</h1></div> <div class="logo">
<h1>SELLPOINT LOGO</h1>
</div>
<div class="info"> <div class="info">
<div class="bedrift"> <div class="bedrift">
<h3>Lorem ipsum</h3> <h3>Lorem ipsum</h3>
......
<div class="registrationForm">
<h3>Rediger bruker</h3>
<app-text-input [(inputModel)]="username" label="Brukernavn" (blur)="checkForm()"></app-text-input>
<app-text-input [(inputModel)]="email" label="Epost" (blur)="checkForm()"></app-text-input>
<app-password-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-password-input>
<app-password-input [(inputModel)]="confirm_password" label="Bekreft passord" (blur)="checkForm()">
</app-password-input>
<p>{{statusMessage}}</p>
<app-button (click)="updateUser()" text="Lagre endringer"></app-button>
</div>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UserProfileEditFormComponent } from './user-profile-edit-form.component';
describe('UserProfileEditFormComponent', () => {
let component: UserProfileEditFormComponent;
let fixture: ComponentFixture<UserProfileEditFormComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ UserProfileEditFormComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(UserProfileEditFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/authentication/auth.service';
import { User } from 'src/app/models/user.model';
import { UserService } from '../user.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-user-profile-edit-form',
templateUrl: './user-profile-edit-form.component.html',
styleUrls: ['./user-profile-edit-form.component.scss']
})
export class UserProfileEditFormComponent implements OnInit {
constructor(private userService: UserService, private authService: AuthService, private router: Router) { }
user: User = new User();
username: string = "";
email: string = "";
password: string = "";
confirm_password: string = "";
statusMessage: string = "";
ngOnInit(): void {
// Check for token expiration
if (this.authService.checkTokenExpiration()) { // redirects to "/" if token is expired
// Get user data from JWT token
const token = localStorage.getItem('token');
const user_data = JSON.parse(atob(token.split(".")[1])).data[0];
// Gets all user information and displays them in the component
this.userService.getUser(user_data.userId).then(user => {
this.user = user;
// todo:
this.username = user.getUsername;
this.email = user.getEmail;
this.password = user.getPassword;
this.confirm_password = user.getPassword;
}).catch (error => {
console.log("Error getting user: " + error);
});
}
console.log(this.user);
}
/**
* Validates the form
*/
checkForm(): boolean {
if (this.username == "") {
this.setStatusMessage("Brukernavn kan ikke være tom");
return false;
}
else if (this.email == "") {
this.setStatusMessage("Eposten kan ikke være tom");
return false;
}
else if (this.password == "") {
this.setStatusMessage("Passordet kan ikke være tom");
return false;
}
else if (this.confirm_password == "") {
this.setStatusMessage("Passordet kan ikke være tom");
return false;
}
else if (this.confirm_password !== this.password) {
this.setStatusMessage("Passordene gitt samsvarer ikke");
return false;
}
this.setStatusMessage("");
return true;
}
/**
* Updates the user if given arguments are valid
*/
updateUser() {
if (this.checkForm()) {
const updatedUser = new User({
username: this.username,
email: this.email,
password: this.password,
});
//
// Updates user in database and redirects to the profile page afterwards
this.userService.updateUser(updatedUser,this.user.getUserId).then(status => {
console.log("User was updated: " + JSON.stringify(status));
this.router.navigateByUrl("/profil");
}).catch(error => {
console.log("Error updating user: " + error);
});
}
}
/**
* Sets the status message for user feedback on form submit
*/
setStatusMessage(message: string) {
this.statusMessage = message;
}
}
<p>user-profile works!</p> <p>user-profile works!</p>
<p>Userid: {{user.getUserId}}</p> <p>Userid: {{user.getUserId}}</p>
<p>username: {{user.getUsername}}</p> <p>username: {{user.getUsername}}</p>
<p>email: {{user.getEmail}}</p> <p>email: {{user.getEmail}}</p>
\ No newline at end of file <!-- <app-button (click)="editUser()" text="Rediger"></app-button> -->
<a href="/profil/rediger">
<app-button text="Rediger"></app-button>
</a>
\ No newline at end of file
...@@ -18,7 +18,7 @@ export class UserProfileComponent implements OnInit { ...@@ -18,7 +18,7 @@ export class UserProfileComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
// Check for token expiration // Check for token expiration
if (this.authService.checkTokenExpiration()) { // redirects to "/" if token is expired if (this.authService.checkTokenExpiration()) { // redirects to "/" if token is expired
// Get user data from JWT token // Get user data from JWT token
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
const user_data = JSON.parse(atob(token.split(".")[1])).data[0]; const user_data = JSON.parse(atob(token.split(".")[1])).data[0];
...@@ -29,6 +29,7 @@ export class UserProfileComponent implements OnInit { ...@@ -29,6 +29,7 @@ export class UserProfileComponent implements OnInit {
console.log("Error getting user: " + error); console.log("Error getting user: " + error);
}); });
} }
console.log(this.user);
} }
} }
...@@ -7,9 +7,10 @@ ...@@ -7,9 +7,10 @@
<app-password-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-password-input> <app-password-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-password-input>
<app-password-input [(inputModel)]="confirm_password" label="Bekreft passord" (blur)="checkForm()"></app-password-input> <app-password-input [(inputModel)]="confirm_password" label="Bekreft passord" (blur)="checkForm()">
</app-password-input>
<p>{{statusMessage}}</p> <p>{{statusMessage}}</p>
<app-button (click)="registerUser()" text="Register"></app-button> <app-button (click)="registerUser()" text="Rediger"></app-button>
</div> </div>
\ No newline at end of file
...@@ -6,6 +6,7 @@ import { UserRegistrationFormComponent } from './user-registration-form/user-reg ...@@ -6,6 +6,7 @@ import { UserRegistrationFormComponent } from './user-registration-form/user-reg
import { UserProfileComponent } from './user-profile/user-profile.component'; import { UserProfileComponent } from './user-profile/user-profile.component';
import { UserLoginFormComponent } from './user-login-form/user-login-form.component'; import { UserLoginFormComponent } from './user-login-form/user-login-form.component';
import { UserLogoutComponent } from './user-logout/user-logout.component'; import { UserLogoutComponent } from './user-logout/user-logout.component';
import { UserProfileEditFormComponent } from './user-profile-edit-form/user-profile-edit-form.component';
...@@ -14,7 +15,8 @@ import { UserLogoutComponent } from './user-logout/user-logout.component'; ...@@ -14,7 +15,8 @@ import { UserLogoutComponent } from './user-logout/user-logout.component';
UserRegistrationFormComponent, UserRegistrationFormComponent,
UserProfileComponent, UserProfileComponent,
UserLoginFormComponent, UserLoginFormComponent,
UserLogoutComponent UserLogoutComponent,
UserProfileEditFormComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,
......
...@@ -76,4 +76,25 @@ export class UserService { ...@@ -76,4 +76,25 @@ export class UserService {
private get_all_users() { private get_all_users() {
return this.http.get(this.userUrl); return this.http.get(this.userUrl);
} }
// /api/user/:userId
updateUser(user: User, userId: number): Promise<string> {
return new Promise<string>(
(resolve, reject) => {
this.update_user(user, userId).subscribe((data: any) => {
try {
resolve(data.data);
} catch (err: any) {
reject(err);
}
},
(err: any) => {
console.log(err.message);
reject(err);
});
}
);
}
private update_user(user: User, userId: number) {
return this.http.put(this.userUrl + userId, user.serialize());
}
} }
...@@ -10,11 +10,11 @@ ...@@ -10,11 +10,11 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@types/cors": "^2.8.9", "@types/cors": "^2.8.10",
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"@types/express-jwt": "^6.0.1", "@types/express-jwt": "^6.0.1",
"@types/jest": "^26.0.20", "@types/jest": "^26.0.20",
"@types/mysql": "^2.15.17", "@types/mysql": "^2.15.18",
"@types/supertest": "^2.0.10", "@types/supertest": "^2.0.10",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cors": "^2.8.5", "cors": "^2.8.5",
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
"mysql": "^2.18.1", "mysql": "^2.18.1",
"mysql2": "^2.2.5", "mysql2": "^2.2.5",
"supertest": "^6.1.3", "supertest": "^6.1.3",
"ts-jest": "^26.5.1" "ts-jest": "^26.5.3"
}, },
"devDependencies": { "devDependencies": {
"@types/jsonwebtoken": "^8.5.0", "@types/jsonwebtoken": "^8.5.0",
"nodemon": "^2.0.7", "nodemon": "^2.0.7",
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
"typescript": "^4.1.3" "typescript": "^4.2.3"
} }
} }
...@@ -47,14 +47,15 @@ router.route('/:userId').get(authenticateToken, async (request: Request, respons ...@@ -47,14 +47,15 @@ router.route('/:userId').get(authenticateToken, async (request: Request, respons
}); });
/* ============================= UPDATE ============================= */ /* ============================= UPDATE ============================= */
// Update user from id `/api/user/:id` // Update user from id `/api/user/:userId`
router.route('/:userId').put(async (request: Request, response: Response) => { router.route('/:userId').put(async (request: Request, response: Response) => {
const userId = request.params.userId; const userId = parseInt(request.params.userId);
const {username, email, password} = request.body; const {username, email, password} = request.body;
try { try {
const input = `UPDATE user SET username=?, email=?, password=? WHERE userId=?);`; const input = `UPDATE user SET username=?, email=?, password=? WHERE userId=?;`;
response.status(200).json(await query(input,[username, email, password, userId])); response.status(200).json(await query(input,[username, email, password, userId]));
} catch (error) { } catch (error) {
console.error(error);
response.status(400).send("Bad Request"); response.status(400).send("Bad Request");
} }
}); });
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment