backoffice updates
This commit is contained in:
parent
4827fdb1b9
commit
83f705ae7c
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using api.Data;
|
||||
using api.Dtos;
|
||||
|
@ -43,5 +44,22 @@ namespace api.Controllers
|
|||
|
||||
return Ok(userToReturn);
|
||||
}
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdateUser(int id, UserForUpdateDto userForUpdate){
|
||||
|
||||
if (id != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value));
|
||||
//return Unauthorized(); //garante que é o próprio pode aceder à sua informação
|
||||
|
||||
var userFromRepo = await _repo.GetUser(id);
|
||||
|
||||
_mapper.Map(userForUpdate, userFromRepo);
|
||||
|
||||
if(await _repo.SaveAll())
|
||||
return NoContent();
|
||||
|
||||
throw new System.Exception($"updating user {id} failed on save");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -32,8 +32,6 @@ namespace api.Data
|
|||
|
||||
public async Task<User> Register(User user, string Password)
|
||||
{
|
||||
byte[] passwordHash, passwordSalt;
|
||||
|
||||
await Context.Users.AddAsync(user);
|
||||
|
||||
await Context.SaveChangesAsync();
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace api.Dtos
|
|||
public class UserForDetailedDto
|
||||
{
|
||||
public string FullName {get;set;}
|
||||
|
||||
public int Id{get;set;}
|
||||
public string Username{get;set;}
|
||||
public string Gender {get;set;}
|
||||
public int Age{get;set;}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
namespace api.Dtos
|
||||
{
|
||||
public class UserForUpdateDto
|
||||
{
|
||||
public string about{get;set;}
|
||||
public string university{get;set;}
|
||||
public string degree{get;set;}
|
||||
}
|
||||
}
|
|
@ -12,9 +12,11 @@ namespace api.Helpers
|
|||
CreateMap<User,UserForListDto>();
|
||||
CreateMap<User, UserForDetailedDto>();
|
||||
CreateMap<Photo,PhotosForDetailedDto>();
|
||||
CreateMap<UserForUpdateDto,User>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
BIN
api/api.db
BIN
api/api.db
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
9ade57420cf6be893d4ff0d490f78cfa807f3a03
|
||||
869d82264c4b3d49130c20e3bded0690a264c567
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -23,6 +23,8 @@ import { UsersListComponent } from './users/usersList/usersList.component';
|
|||
import {User} from './models/user';
|
||||
import { UserComponent } from './users/user/user.component';
|
||||
import { FooterComponent } from './footer/footer.component';
|
||||
import { EditComponent } from './users/edit/edit.component';
|
||||
import { PreventUnsavedChanges } from './guards/prevent-unsaved-changes.guard';
|
||||
|
||||
|
||||
export function tokenGetter() {
|
||||
|
@ -41,7 +43,8 @@ export function tokenGetter() {
|
|||
HomeComponent,
|
||||
UsersListComponent,
|
||||
UserComponent,
|
||||
FooterComponent
|
||||
FooterComponent,
|
||||
EditComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -59,7 +62,8 @@ export function tokenGetter() {
|
|||
providers: [
|
||||
AuthService,
|
||||
AuthGuard,
|
||||
UserService
|
||||
UserService,
|
||||
PreventUnsavedChanges
|
||||
],
|
||||
bootstrap: [
|
||||
AppComponent
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import { CanDeactivate } from '@angular/router';
|
||||
import { EditComponent } from '../users/edit/edit.component';
|
||||
|
||||
@Injectable()
|
||||
|
||||
export class PreventUnsavedChanges implements CanDeactivate<EditComponent> {
|
||||
canDeactivate(component: EditComponent) {
|
||||
if (component.editForm.dirty) {
|
||||
return confirm('Tens a certeza que pretendes continuar sem guardar as modificações?');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,9 @@ import { AuthGuard } from './guards/auth.guard';
|
|||
import { HomeComponent } from './home/home.component';
|
||||
import { UsersListComponent } from './users/usersList/usersList.component';
|
||||
import { UserComponent } from './users/user/user.component';
|
||||
import { Component } from '@angular/core';
|
||||
import { EditComponent } from './users/edit/edit.component';
|
||||
import { PreventUnsavedChanges } from './guards/prevent-unsaved-changes.guard';
|
||||
|
||||
|
||||
|
||||
|
@ -27,6 +30,12 @@ export const appRoutes: Routes = [
|
|||
component: UserComponent,
|
||||
canActivate: [AuthGuard],
|
||||
|
||||
},
|
||||
{
|
||||
path: 'user/edit/:id',
|
||||
component: EditComponent,
|
||||
canDeactivate: [PreventUnsavedChanges],
|
||||
|
||||
},
|
||||
{
|
||||
path: 'login',
|
||||
|
|
|
@ -20,5 +20,10 @@ export class UserService {
|
|||
|
||||
return this.http.get<User>(this.baseUrl + 'users/' + id);
|
||||
}
|
||||
updateUser(id: number, user: User) {
|
||||
|
||||
return this.http.put(this.baseUrl + 'users/' + id, user);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
.qr_code
|
||||
{
|
||||
width: 60%;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 5%;
|
||||
}
|
||||
.qr_code img{
|
||||
width:100%;
|
||||
|
||||
}
|
|
@ -0,0 +1,286 @@
|
|||
<app-navigation></app-navigation>
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content Header (Page header) -->
|
||||
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
|
||||
<!-- Profile Image -->
|
||||
<div class="box box-primary">
|
||||
<div class="box-body box-profile">
|
||||
<img class="profile-user-img img-responsive img-circle" src="{{user?.profileIcon}}" alt="User profile picture">
|
||||
|
||||
<h3 class="profile-username text-center">{{user?.fullName}}</h3>
|
||||
|
||||
<p class="text-muted text-center">@{{user?.username}}</p>
|
||||
|
||||
<div class="qr_code box"> <img src="https://preview.ibb.co/kpNOH9/qr_code.png" alt=""></div>
|
||||
|
||||
|
||||
<a href="#" class="btn btn-primary btn-block"><b><i class="fa fa-pencil" aria-hidden="true"></i> Editar informações pessoais</b></a>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
|
||||
<!-- About Me Box -->
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Sobre min</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<strong><i class="fa fa-book margin-r-5"></i> Estudos</strong>
|
||||
|
||||
<p class="text-muted">
|
||||
<strong>{{user?.degree}}</strong>
|
||||
</p>
|
||||
<p>{{user?.university}}</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<strong><i class="fa fa-map-marker margin-r-5"></i> Origem </strong>
|
||||
|
||||
<p class="text-muted">{{user?.city}}, {{user?.country}}</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<strong><i class="fa fa-pencil margin-r-5"></i> Skills</strong>
|
||||
|
||||
<p>
|
||||
<span class="label label-danger">UI Design</span>
|
||||
<span class="label label-success">Coding</span>
|
||||
<span class="label label-info">Javascript</span>
|
||||
<span class="label label-warning">PHP</span>
|
||||
<span class="label label-primary">Node.js</span>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<strong><i class="fa fa-file-text-o margin-r-5"></i> Sobre min: </strong>
|
||||
|
||||
<p>{{user?.about}}</p>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
|
||||
<div class="col-md-9">
|
||||
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#publicos" data-toggle="tab">Dados Públicos</a></li>
|
||||
<li><a href="#teste" data-toggle="tab">Dados Pessoais</a></li>
|
||||
<li><a href="#passwords" data-toggle="tab">Passwords</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class=" active tab-pane" id="publicos">
|
||||
<form class="form-horizontal" #editForm="ngForm" (ngSubmit)="updateUser()">
|
||||
<div class="form-group">
|
||||
|
||||
<label for="inputName" class="col-sm-2 control-label">Universidade</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" name="university" [(ngModel)]="user.university">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
<label for="inputName" class="col-sm-2 control-label">Curso</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" name="degree" [(ngModel)]="user.degree">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label for="inputName" class="col-sm-2 control-label">Sobre min:</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" name="about" [(ngModel)]="user.about">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-danger">Atualizar</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- /.tab-pane -->
|
||||
<div class="tab-pane" id="pessoal">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="inputName" class="col-sm-2 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputName" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputEmail" class="col-sm-2 control-label">Email</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputEmail" placeholder="Email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputName" class="col-sm-2 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="inputName" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputExperience" class="col-sm-2 control-label">Experience</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" id="inputExperience" placeholder="Experience"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button [disabled]="!editForm.dirty" type="submit" class="btn btn-danger">Atualizar</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- /.tab-pane -->
|
||||
|
||||
<div class="tab-pane" id="passwords">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="inputName" class="col-sm-2 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputName" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputEmail" class="col-sm-2 control-label">Email</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputEmail" placeholder="Email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputName" class="col-sm-2 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="inputName" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputExperience" class="col-sm-2 control-label">Experience</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" id="inputExperience" placeholder="Experience"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputSkills" class="col-sm-2 control-label">Skills</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="inputSkills" placeholder="Skills">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox"> I agree to the <a href="#">terms and conditions</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-danger">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tab-pane" id="teste">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="inputName" class="col-sm-2 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputName" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputEmail" class="col-sm-2 control-label">Email</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="inputEmail" placeholder="Email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputName" class="col-sm-2 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="inputName" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputExperience" class="col-sm-2 control-label">Experience</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" id="inputExperience" placeholder="Experience"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputSkills" class="col-sm-2 control-label">Skills</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="inputSkills" placeholder="Skills">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox"> I agree to the <a href="#">terms and conditions</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-danger">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- /.tab-pane -->
|
||||
</div>
|
||||
<!-- /.tab-content -->
|
||||
</div>
|
||||
<div *ngIf= "editForm.dirty" class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa fa-ban"></i> Atenção!!!</h4>
|
||||
Não te esqueças de guardar a informação que atualizares!!
|
||||
</div>
|
||||
<!-- /.nav-tabs-custom -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
<app-footer></app-footer>
|
|
@ -0,0 +1,28 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { DebugElement } from '@angular/core';
|
||||
|
||||
import { EditComponent } from './edit.component';
|
||||
|
||||
describe('EditComponent', () => {
|
||||
let component: EditComponent;
|
||||
let fixture: ComponentFixture<EditComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ EditComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { User } from '../../models/user';
|
||||
import { UserService } from '../../services/user.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { NgForm } from '@angular/forms';
|
||||
import { AuthService } from '../../services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-edit',
|
||||
templateUrl: './edit.component.html',
|
||||
styleUrls: ['./edit.component.css']
|
||||
})
|
||||
export class EditComponent implements OnInit {
|
||||
|
||||
@ViewChild('editForm') editForm: NgForm;
|
||||
user: User;
|
||||
constructor(private userService: UserService, private route: ActivatedRoute, private authService: AuthService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.loadUser();
|
||||
}
|
||||
|
||||
// members/...
|
||||
loadUser() {
|
||||
// o mais é para garantir que a route retorna um inteiro
|
||||
this.userService.getUser(+this.route.snapshot.params['id']).subscribe((user: User) => {
|
||||
this.user = user;
|
||||
}, error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
updateUser() {
|
||||
console.log(this.user.id);
|
||||
this.userService.updateUser(this.user.id, this.user).subscribe(
|
||||
next => {
|
||||
console.log(this.user);
|
||||
this.editForm.reset(this.user);
|
||||
}, error => {
|
||||
console.log(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -13,11 +13,11 @@
|
|||
<!-- Profile Image -->
|
||||
<div class="box box-primary">
|
||||
<div class="box-body box-profile">
|
||||
<img class="profile-user-img img-responsive img-circle" src="{{user.profileIcon}}" alt="User profile picture">
|
||||
<img class="profile-user-img img-responsive img-circle" src="{{user?.profileIcon}}" alt="User profile picture">
|
||||
|
||||
<h3 class="profile-username text-center">{{user.fullName}}</h3>
|
||||
<h3 class="profile-username text-center">{{user?.fullName}}</h3>
|
||||
|
||||
<p class="text-muted text-center">@{{user.username}}</p>
|
||||
<p class="text-muted text-center">@{{user?.username}}</p>
|
||||
|
||||
<div class="qr_code box"> <img src="https://preview.ibb.co/kpNOH9/qr_code.png" alt=""></div>
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<td>{{user.age}}</td>
|
||||
<td>{{user.about}}</td>
|
||||
<th><button [routerLink]="['/user/',user.id]" class="btn btn-block btn-success btn-sm">Visualizar</button> </th>
|
||||
<th><button [routerLink]="['/user/',user.id]" class="btn btn-block btn-danger btn-sm">editar</button></th>
|
||||
<th><button [routerLink]="['/user/edit/',user.id]" class="btn btn-block btn-danger btn-sm">editar</button></th>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
|
Loading…
Reference in New Issue