backoffice updates

This commit is contained in:
henrydays 2018-09-11 20:19:04 +01:00
parent 4827fdb1b9
commit 83f705ae7c
22 changed files with 436 additions and 10 deletions

View File

@ -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");
}
}
}

View File

@ -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();

View File

@ -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;}

View File

@ -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;}
}
}

View File

@ -12,9 +12,11 @@ namespace api.Helpers
CreateMap<User,UserForListDto>();
CreateMap<User, UserForDetailedDto>();
CreateMap<Photo,PhotosForDetailedDto>();
CreateMap<UserForUpdateDto,User>();
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
9ade57420cf6be893d4ff0d490f78cfa807f3a03
869d82264c4b3d49130c20e3bded0690a264c567

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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;
}
}

View File

@ -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',

View File

@ -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);
}
}

View File

@ -0,0 +1,10 @@
.qr_code
{
width: 60%;
margin: 0 auto;
margin-bottom: 5%;
}
.qr_code img{
width:100%;
}

View File

@ -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>

View File

@ -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();
});
});

View File

@ -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);
}
);
}
}

View File

@ -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>

View File

@ -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>