Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • web-et-numerique/factory/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_client
1 result
Show changes
Commits on Source (19)
Showing
with 177 additions and 25 deletions
......@@ -253,13 +253,11 @@ export class FormComponent implements OnInit {
}
public onSubmitClaimWithAccount(): void {
this.structureService
.claimStructureWithAccount(this.structureId, this.profile.email)
.subscribe((structuresLinked) => {
this.profile.pendingStructuresLink = structuresLinked;
this.profileService.setProfile(this.profile);
this.closeEvent.emit(this.structureForm.value);
});
this.structureService.claimStructureWithAccount(this.structureId, this.profile).subscribe((structuresLinked) => {
this.profile.pendingStructuresLink = structuresLinked;
this.profileService.setProfile(this.profile);
this.closeEvent.emit(this.structureForm.value);
});
}
public onSubmit(structureForm: FormGroup): void {
if (structureForm.valid) {
......
......@@ -9,7 +9,7 @@
<span class="ico-menu"></span>
</div>
<div fxLayout="row" class="right-header" fxLayoutAlign="center center" fxLayoutGap="3vw">
<a routerLink="/home" [routerLinkActive]="'active'" i18n>Acteurs de la médiation numérique</a>
<a routerLink="/home" [routerLinkActive]="'active'" i18n>Les acteurs</a>
<!-- <a routerLink="/resources" [routerLinkActive]="'active'" i18n>Ressources</a>
<a routerLink="/projects" [routerLinkActive]="'active'" i18n>Projets</a> -->
<a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a>
......
......@@ -7,9 +7,7 @@
<div (click)="closeMenu()" class="ico-close-details"></div>
</div>
<div fxLayout="column" class="right-header" fxLayoutGap="3vw">
<a routerLink="/home" [routerLinkActive]="'active'" (click)="closeMenu()" i18n
>Acteurs de la médiation numérique</a
>
<a routerLink="/home" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Les acteurs</a>
<!-- <a routerLink="/resources" [routerLinkActive]="'active'" i18n>Ressources</a>
<a routerLink="/projects" [routerLinkActive]="'active'" i18n>Projets</a> -->
<a routerLink="/about" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Qui sommes-nous ?</a>
......
......@@ -25,7 +25,7 @@
right: 0;
width: 100%;
height: 100%;
z-index: $modal-menu-phone-z-index;
z-index: $menu-phone-z-index;
animation: slideMenu 0.5s;
.contentMenu {
background-color: $white;
......
import { Equipment } from '../structure-list/enum/equipment.enum';
import { typeStructureEnum } from '../shared/enum/typeStructure.enum';
import { Weekday } from '../structure-list/enum/weekday.enum';
import { Address } from './address.model';
......@@ -111,6 +112,13 @@ export class Structure {
return false;
}
/**
* Check if a structure has pass Numeric label
*/
public hasPassNumeric(): boolean {
return this.labelsQualifications.includes('passNumerique');
}
/**
* Return a range, according to the distance, between [1,3] to get a distance reference.
* - [0,5km] => 1
......@@ -140,4 +148,38 @@ export class Structure {
public getLon(): number {
return this.coord[0];
}
public getEquipmentsIcon(equipment: Equipment): string {
switch (equipment) {
case Equipment.wifi:
return 'wifi';
case Equipment.bornes:
return 'borne';
case Equipment.printer:
return 'print';
case Equipment.tablet:
return 'tablet';
case Equipment.computer:
return 'computer';
default:
return null;
}
}
public getEquipmentsTitle(equipment: Equipment): string {
switch (equipment) {
case Equipment.wifi:
return 'Wifi';
case Equipment.bornes:
return 'Bornes';
case Equipment.printer:
return 'Imprimantes';
case Equipment.tablet:
return 'Tablettes';
case Equipment.computer:
return 'Ordinateurs';
default:
return null;
}
}
}
......@@ -4,6 +4,7 @@ import { Observable } from 'rxjs';
import { User } from '../../models/user.model';
import decode from 'jwt-decode';
import { UserRole } from '../../shared/enum/userRole.enum';
import { AuthService } from '../../services/auth.service';
@Injectable({
providedIn: 'root',
......@@ -11,7 +12,7 @@ import { UserRole } from '../../shared/enum/userRole.enum';
export class ProfileService {
private readonly baseUrl = 'api/users';
private currentProfile: User = null;
constructor(private http: HttpClient) {
constructor(private http: HttpClient, private authService: AuthService) {
this.getProfile();
}
......@@ -45,14 +46,15 @@ export class ProfileService {
}
public isAdmin(): boolean {
const user = JSON.parse(localStorage.getItem('user'));
if (user) {
if (this.authService.isLoggedIn()) {
const user = this.authService.userValue;
const token = user.accessToken;
// decode the token to get its payload
const tokenPayload: User = decode(token);
if (tokenPayload.role == UserRole.admin) {
return true;
}
return false;
}
return false;
}
......
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { DateTime } from 'luxon';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
......@@ -12,7 +13,7 @@ export class AuthService {
private userSubject: BehaviorSubject<UserAuth>;
public user: Observable<UserAuth>;
constructor(private http: HttpClient) {
constructor(private http: HttpClient, private router: Router) {
this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user')));
this.user = this.userSubject.asObservable();
}
......@@ -31,6 +32,7 @@ export class AuthService {
public logout(): void {
localStorage.removeItem('user');
this.userSubject.next(null);
window.location.replace('/home');
}
public isLoggedIn(): boolean {
......
......@@ -35,8 +35,8 @@ export class StructureService {
return this.http.get(`${this.baseUrl}/${id}/isClaimed`);
}
public claimStructureWithAccount(id: string, email: string): Observable<string[]> {
return this.http.post<any>(`${this.baseUrl}/${id}/claim`, { email });
public claimStructureWithAccount(id: string, user: User): Observable<string[]> {
return this.http.post<any>(`${this.baseUrl}/${id}/claim`, user);
}
public getStructure(id: string): Observable<Structure> {
......
<div class="search-bar">
<div>
<input
id="search-address"
type="text"
placeholder="ex: 20 rue du lac, Lyon"
(input)="onSearchChange($event.target.value)"
class="form-input"
#searchAddress
/>
</div>
<div class="autocomplete-items">
<p *ngFor="let hit of data" (click)="selectedResult(hit)" class="autocomplete-item">
{{ parseHitToAddress(hit) }}
</p>
</div>
</div>
@import '../../../../assets/scss/color';
.search-bar {
display: flex;
flex-direction: column;
}
.autocomplete-items {
border: 0.0625rem solid #d4d4d4;
border-top: none;
border-bottom: none;
z-index: 99;
background-color: #fff;
cursor: pointer;
}
.autocomplete-item {
margin: 0;
padding: 1em 0;
}
.autocomplete-item:hover {
background-color: #dee6ee;
cursor: pointer;
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AddressAutocompleteComponent } from './address-autocomplete.component';
describe('AddressAutocompleteComponent', () => {
let component: AddressAutocompleteComponent;
let fixture: ComponentFixture<AddressAutocompleteComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AddressAutocompleteComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AddressAutocompleteComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, ElementRef, EventEmitter, Output, ViewChild } from '@angular/core';
import { AddressService } from '../../service/address.service';
@Component({
selector: 'app-address-autocomplete',
templateUrl: './address-autocomplete.component.html',
styleUrls: ['./address-autocomplete.component.scss'],
})
export class AddressAutocompleteComponent {
public readonly AUTOCOMPLETE_NBR = 5;
public data = [];
@ViewChild('searchAddress', { static: true }) searchAddress: ElementRef;
@Output() selectedAddress: EventEmitter<string> = new EventEmitter<string>();
constructor(private addressService: AddressService) {}
public onSearchChange(searchString: string) {
this.addressService.searchAddress(searchString).subscribe((data) => {
this.data = data.hits.hits.slice(0, this.AUTOCOMPLETE_NBR);
});
}
public selectedResult(hit: any): void {
const value = this.parseHitToAddress(hit);
// Set input value
this.searchAddress.nativeElement.value = value;
// Reset autocomplete
this.data = [];
// Emit choosen value
this.selectedAddress.emit(value);
}
public parseHitToAddress(hit: any): string {
return `${hit._source['data-fr'].properties.numero_str} ${hit._source['data-fr'].properties.voie_str} ${hit._source['data-fr'].properties.commune_str}`;
}
}
......@@ -8,7 +8,13 @@
fxLayoutAlign="space-between center"
fxLayoutGap="13px"
>
<app-svg-icon style="height: 100%" [type]="'ico'" [iconClass]="'icon-32'" [icon]="iconBtn"></app-svg-icon>
<app-svg-icon
style="height: 100%"
[type]="'ico'"
[iconClass]="'icon-32'"
[icon]="iconBtn"
[iconColor]="'currentColor'"
></app-svg-icon>
{{ text }}
</div>
</button>
......
......@@ -6,6 +6,7 @@ import { SignInModalComponent } from './signin-modal/signin-modal.component';
import { SvgIconComponent } from './svg-icon/svg-icon.component';
import { ValidatorFormComponent } from './validator-form/validator-form.component';
import { CreateAccountFormComponent } from './create-account-form/create-account-form.component';
import { AddressAutocompleteComponent } from './address-autocomplete/address-autocomplete.component';
// tslint:disable-next-line: max-line-length
export {
......@@ -17,6 +18,7 @@ export {
SignUpModalComponent,
SignInModalComponent,
CreateAccountFormComponent,
AddressAutocompleteComponent,
};
// tslint:disable-next-line:variable-name
......@@ -29,4 +31,5 @@ export const SharedComponents = [
SignUpModalComponent,
SignInModalComponent,
CreateAccountFormComponent,
AddressAutocompleteComponent,
];
......@@ -13,7 +13,7 @@ p {
div {
border: 1px solid $grey-4;
box-sizing: border-box;
border-radius: 4px;
border-radius: 16px;
margin-bottom: 24px;
padding: 16px 25px;
max-width: 172px;
......
......@@ -5,7 +5,7 @@
@import '../../../../assets/scss/hyperlink';
.cModal {
position: fixed;
z-index: $modal-add-structure-z-index;
z-index: $modal-z-index;
top: 0;
right: 0;
bottom: 0;
......
......@@ -5,7 +5,7 @@
@import '../../../../assets/scss/hyperlink';
.cModal {
position: fixed;
z-index: $modal-add-structure-z-index;
z-index: $modal-z-index;
top: 0;
right: 0;
bottom: 0;
......
......@@ -7,7 +7,7 @@
<div class="card-body">
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="username">Identifiant</label>
<label for="username">Email</label>
<input
type="text"
formControlName="username"
......
......@@ -5,7 +5,7 @@
@import '../../../../assets/scss/hyperlink';
.cModal {
position: fixed;
z-index: $modal-add-structure-z-index;
z-index: $modal-z-index;
top: 0;
right: 0;
bottom: 0;
......
<svg aria-hidden="true" class="icon" [ngClass]="iconClass" [attr.fill]="iconColor ? iconColor : 'none'">
<svg aria-hidden="true" class="icon" [ngClass]="iconClass" [attr.fill]="iconColor" [attr.stroke]="iconColor">
<title *ngIf="title">{{ title }}</title>
<use [attr.xlink:href]="'assets/' + type + '/sprite.svg#' + icon"></use>
</svg>