Suppression de l'ancien frontend

This commit is contained in:
MiharyR 2021-12-21 12:56:16 +01:00 committed by GitHub
parent d62915bfe5
commit 427d837b35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
219 changed files with 0 additions and 12333 deletions

View file

@ -1,167 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<app-navbar-admin></app-navbar-admin><br><br>
<!-- filtre -->
<div class="filtersContainer mat-elevation-z8">
<!-- titre -->
<div style="font-weight: bold; margin-bottom: 10px;">
Filtre
</div>
<mat-divider></mat-divider>
<!-- filtre textuelle-->
<div style="margin: 10px 0px 20px 2%;">
<input class="textFilter" (keyup)="applyFilter($event)" placeholder="Rechercher par mots-clés...">
</div>
<!-- visible + interests + période -->
<div class="row myRow">
<!-- visible -->
<div class="col-2">
<mat-checkbox [(ngModel)]="visible" (change)="onFilter()">visible</mat-checkbox><br>
<mat-checkbox [(ngModel)]="noVisible" (change)="onFilter()">non visible</mat-checkbox>
</div>
<!-- subjects -->
<div class="col-4">
<mat-form-field appearance="fill">
<mat-label>Sujets</mat-label>
<mat-select [formControl]="formControlInterests" multiple>
<mat-select-trigger>
{{formControlInterests.value ? formControlInterests.value[0] : ''}}
<span *ngIf="formControlInterests.value?.length > 1">
(+{{formControlInterests.value.length - 1}} {{formControlInterests.value?.length === 2 ? 'autre' : 'autres'}})
</span>
</mat-select-trigger>
<mat-option *ngFor="let topping of allInterests" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
<button mat-icon-button (click)="onFilter()">
<mat-icon>keyboard_tab</mat-icon>
</button>
</div>
<!-- période -->
<div class="col-6" style="text-align: right;">
Période de création: &nbsp;
<mat-form-field appearance="fill" style="width: 140px; font-size: small;">
<mat-label>Date de début</mat-label>
<input matInput type="date"
style="font-size: small; width: 140px;"
[ngModel] ="startDate | date:'yyyy-MM-dd'"
(ngModelChange)="onNewStartDate($event); onFilter();">
</mat-form-field>
&nbsp; - &nbsp;
<mat-form-field appearance="fill" style="width: 140px; font-size: small;">
<mat-label>Date de fin</mat-label>
<input matInput type="date"
style="font-size: small; width: 140px;"
[ngModel] ="endDate | date:'yyyy-MM-dd'"
(ngModelChange)="onNewEndDate($event); onFilter();">
</mat-form-field>
</div>
</div>
</div>
<!-- table -->
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- Title Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Titre </th>
<td mat-cell *matCellDef="let advert">
{{advert.title}}
</td>
</ng-container>
<!-- Advertiser Column -->
<ng-container matColumnDef="company">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Entreprise </th>
<td mat-cell *matCellDef="let advert">
{{advert.company}}
</td>
</ng-container>
<!-- Tags Column -->
<ng-container matColumnDef="interests">
<th mat-header-cell *matHeaderCellDef> Sujets </th>
<td mat-cell *matCellDef="let advert">
<span *ngFor="let objectInterest of advert.interests; let isLast = last;">
<span *ngIf="!isLast"> {{objectInterest.interest}}, </span>
<span *ngIf="isLast"> {{objectInterest.interest}} </span>
</span>
</td>
</ng-container>
<!-- CreatedAt Column -->
<ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de création </th>
<td mat-cell *matCellDef="let advert">
{{ advert.createdAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</td>
</ng-container>
<!-- UpdatedAt Column -->
<ng-container matColumnDef="updatedAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Dernière modification </th>
<td mat-cell *matCellDef="let advert">
{{ advert.updatedAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</td>
</ng-container>
<!-- CountViews Column -->
<ng-container matColumnDef="countViews">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Vues </th>
<td mat-cell *matCellDef="let advert">
{{advert.countViews}}
</td>
</ng-container>
<!-- IsVisible Column -->
<ng-container matColumnDef="isVisible">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Visible </th>
<td mat-cell *matCellDef="let advert">
<span *ngIf="advert.isVisible"> <mat-icon>check</mat-icon> </span>
<span *ngIf="!advert.isVisible"></span>
</td>
</ng-container>
<!-- Actions Column -->
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let advert">
<button mat-icon-button (click)="onVisualizeImages(advert)">
<mat-icon> insert_photo</mat-icon>
</button>
<button mat-icon-button (click)="onDelete(advert)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<!-- Directives -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4"> Aucune vidéo ne correspond au filtre: "{{input.value}}" </td>
</tr>
</table>
<div style="width: 94%; margin: auto auto">
<mat-paginator [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons aria-label="Select page of periodic elements"></mat-paginator>
</div>
<br><br>
</div>
</div>

View file

@ -1,74 +0,0 @@
.myContainer {
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
font-size: small;
}
// ----------------------------------------------------------
.filtersContainer {
width: 80%;
background-color: white;
padding: 10px 10px 10px 10px;
margin: 20px 3% 20px 3%
}
.myRow {
margin-left: 1%;
}
.textFilter {
width: 50%;
font-size: medium;
border-radius: 5px;
}
// ----------------------------------------------------------
table {
margin: 0 auto;
width: 94%;
font-size: small;
}
.darkTheme table { border: solid 2px white; }
th.mat-sort-header-sorted {
color: black;
}
td {
font-size: small;
}
input {
width: 30%;
font-size: large;
border-radius: 5px;
}
// -------------------------------------------------------------------------
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
border: solid 1px black !important;
background-color: white !important;
}
::ng-deep .mat-pseudo-checkbox-checked {
background-color: black !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageAdListAdminComponent } from './page-ad-list-admin.component';
describe('PageAdListAdminComponent', () => {
let component: PageAdListAdminComponent;
let fixture: ComponentFixture<PageAdListAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageAdListAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageAdListAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,262 +0,0 @@
import {AfterViewInit, Component, ViewChild} from '@angular/core';
import {MatSort} from "@angular/material/sort";
import {MatPaginator} from "@angular/material/paginator";
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MatDialog} from "@angular/material/dialog";
import {MatSnackBar} from "@angular/material/snack-bar";
import {MatTableDataSource} from "@angular/material/table";
import {Advert} from "../../../utils/interfaces/advert";
import {PopupDeleteAdAdminComponent} from "../popup-delete-ad-admin/popup-delete-ad-admin.component";
import {PopupVisualizeImagesAdminComponent} from "../popup-visualize-images-admin/popup-visualize-images-admin.component";
import {FormControl} from "@angular/forms";
import {MessageService} from "../../../utils/services/message/message.service";
import {HttpParams} from "@angular/common/http";
export interface AdvertWithCountViewsAndCompany {
id: string,
userId: string,
company: string,
title: string,
url: string,
images: {
url: string,
description: string,
}[],
interests: string[],
comment: string,
views: Date[],
countViews: number,
isVisible: boolean,
isActive: boolean,
createdAt: Date,
updatedAt: Date,
}
@Component({
selector: 'app-page-ad-list-admin',
templateUrl: './page-ad-list-admin.component.html',
styleUrls: ['./page-ad-list-admin.component.scss']
})
export class PageAdListAdminComponent implements AfterViewInit
{
tabAdvertWithCountViews: AdvertWithCountViewsAndCompany[] = [];
tabAdvertiser: any[];
displayedColumns: string[] = [ 'title', 'company', 'interests', 'createdAt', 'updatedAt', 'countViews', 'isVisible', 'actions' ];
dataSource ;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
visible: boolean = true;
noVisible: boolean = true;
startDate: Date = null;
endDate: Date = null;
formControlInterests = new FormControl();
allInterests: string[] = [];
constructor( public themeService: ThemeService,
public dialog: MatDialog,
private snackBar: MatSnackBar,
private messageService: MessageService) { }
ngAfterViewInit(): void
{
// Ask for ads and then for advertiser
let params = new HttpParams();
params = params.append("isActive", true);
this.messageService
.get("ad/findAll", params)
.subscribe(ret => this.afterReceivingAds(ret), err => this.afterReceivingAds(err) );
// Ask for interest
this.messageService
.get("misc/getInterests")
.subscribe(ret => this.afterReceivingInterests(ret), err => this.afterReceivingInterests(err) );
}
afterReceivingAds(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
const tabAdvert = retour.data;
this.messageService
.get("user/findAll")
.subscribe(ret => this.afterReceivingAdvertiser(ret, tabAdvert), err => this.afterReceivingAdvertiser(err, tabAdvert) );
}
}
afterReceivingAdvertiser(retour: any, tabAdvert): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.tabAdvertiser = retour.data.filter(x => x.role.name === "advertiser");
for(let advert of tabAdvert) this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViewsAndCompany(advert));
this.dataSource = new MatTableDataSource<Advert>();
this.onFilter();
}
}
afterReceivingInterests(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.allInterests = retour.data.map(x => x.interest);
this.allInterests.sort();
}
}
applyFilter(event: Event): void
{
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
}
onVisualizeImages(advert: AdvertWithCountViewsAndCompany)
{
if(advert.images.length !== 0)
{
const config = {
width: '30%',
height: '90%',
data: { images: advert.images }
};
this.dialog
.open(PopupVisualizeImagesAdminComponent, config)
.afterClosed()
.subscribe(retour => {});
}
else {
const config = { duration: 2000, panelClass: "custom-class" };
const message = "Cette annonce ne contient aucune image" ;
this.snackBar.open( message, "", config);
}
}
onDelete(advert: AdvertWithCountViewsAndCompany): void
{
const config = {
data: { advert: advert }
};
this.dialog
.open(PopupDeleteAdAdminComponent, config)
.afterClosed()
.subscribe( retour => {
const config = { duration: 1000, panelClass: "custom-class" };
let message = "" ;
if((retour === undefined) || (retour === null)) {
message = "Opération annulée" ;
}
else {
const index = this.dataSource.data.findIndex( elt => (elt.id === advert.id));
this.dataSource.data.splice(index, 1);
this.dataSource.data = this.dataSource.data;
this.dataSource = this.dataSource;
message = advert.title + " a bien été supprimée ✔" ;
}
this.snackBar.open( message, "", config);
});
}
onFilter(): void
{
this.dataSource.data = [];
for(let advert of this.tabAdvertWithCountViews)
{
let valide: boolean = true;
if(advert.isVisible && this.visible) valide = true;
else if((!advert.isVisible) && this.noVisible) valide = true;
else valide = false;
if(valide)
{
if ((advert.createdAt === null) && (this.startDate !== null)) valide = false;
else if ((advert.createdAt === null) && (this.endDate !== null)) valide = false;
else if (this.startDate !== null)
{
if(this.startDate.getTime() > advert.createdAt.getTime()) valide = false;
else if (this.endDate !== null)
{
if(this.endDate.getTime() < advert.createdAt.getTime()) valide = false;
}
}
}
if(valide) {
if(this.formControlInterests.value !== null) {
for (let interest of this.formControlInterests.value) {
if (advert.interests.indexOf(interest) === -1) {
valide = false;
break;
}
}
}
}
if(valide) this.dataSource.data.push(advert);
}
this.dataSource = new MatTableDataSource(this.dataSource.data);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
}
onNewStartDate(event): void {
this.startDate = new Date(event);
}
onNewEndDate(event): void {
this.endDate = new Date(event);
}
advertToAdvertWithCountViewsAndCompany(advert): AdvertWithCountViewsAndCompany
{
let company0 = "company" ;
for(let advertiser of this.tabAdvertiser)
{
if(advert.userId === advertiser.id) {
company0 = advertiser.company;
break;
}
}
return {
id: advert.id,
userId: advert.userId,
title: advert.title,
company: company0,
url: advert.url,
images: advert.images,
interests: advert.interests,
comment: advert.comment,
views: advert.views,
countViews: advert.views.length,
isVisible: advert.isVisible,
isActive: advert.isActive,
createdAt: advert.createdAt,
updatedAt: advert.updatedAt,
}
}
}

View file

@ -1,8 +0,0 @@
<mat-dialog-content class="mat-typography">
Êtes-vous sûr de vouloir supprimer l'annonce <i>{{advert.title}}</i> ?
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close();">Annuler</button>
<button mat-button (click)="onValidate()" cdkFocusInitial>Valider</button>
</mat-dialog-actions>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupDeleteAdAdminComponent } from './popup-delete-ad-admin.component';
describe('PopupDeleteAdAdminComponent', () => {
let component: PopupDeleteAdAdminComponent;
let fixture: ComponentFixture<PopupDeleteAdAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupDeleteAdAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupDeleteAdAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,49 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-popup-delete-ad-admin',
templateUrl: './popup-delete-ad-admin.component.html',
styleUrls: ['./popup-delete-ad-admin.component.scss']
})
export class PopupDeleteAdAdminComponent implements OnInit
{
advert: any;
constructor( public dialogRef: MatDialogRef<PopupDeleteAdAdminComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService) { }
ngOnInit(): void
{
this.advert = this.data.advert;
}
onValidate(): void
{
this.messageService
.delete("ad/delete/"+this.advert.id)
.subscribe(ret => this.onValidateCallback(ret), err => this.onValidateCallback(err));
}
onValidateCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
this.dialogRef.close();
}
else {
console.log("suppr");
console.log(retour);
this.dialogRef.close(true);
}
}
}

View file

@ -1,20 +0,0 @@
<div mat-dialog-title class="dialog-title">
<h2></h2>
<button mat-icon-button aria-label="close dialog" mat-dialog-close>
<mat-icon>close</mat-icon>
</button>
</div>
<mat-grid-list cols="12" rowHeight="500">
<mat-grid-tile colspan="1" rowspan="1" (click)="onPrecedent()">
<button> < </button>
</mat-grid-tile>
<mat-grid-tile colspan="10" rowspan="1">
<img [src]="tabImages[index].base64" [alt]="tabImages[index].description">
</mat-grid-tile>
<mat-grid-tile colspan="1" rowspan="1" (click)="onSuivant()">
<button> > </button>
</mat-grid-tile>
</mat-grid-list>

View file

@ -1,14 +0,0 @@
carousel {
width: 100%;
margin: 0 auto;
text-align: center;
justify-content: center
}
.dialog-title {
display: flex;
justify-content: space-between;
align-items: center;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupVisualizeImagesAdminComponent } from './popup-visualize-images-admin.component';
describe('PopupVisualizeImagesAdminComponent', () => {
let component: PopupVisualizeImagesAdminComponent;
let fixture: ComponentFixture<PopupVisualizeImagesAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupVisualizeImagesAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupVisualizeImagesAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,38 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
@Component({
selector: 'app-popup-visualize-images-admin',
templateUrl: './popup-visualize-images-admin.component.html',
styleUrls: ['./popup-visualize-images-admin.component.scss']
})
export class PopupVisualizeImagesAdminComponent implements OnInit
{
tabImages = [];
index: number = 0;
nbImage: number = 0;
constructor( public dialogRef: MatDialogRef<PopupVisualizeImagesAdminComponent>,
@Inject(MAT_DIALOG_DATA) public data ) { }
ngOnInit(): void
{
this.tabImages = this.data.images;
this.nbImage = this.tabImages.length;
}
onPrecedent(): void
{
if(this.index !== 0) this.index -= 1;
}
onSuivant(): void
{
if(this.index !== (this.nbImage-1)) this.index += 1;
}
}

View file

@ -1,43 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- NavBar -->
<app-navbar-admin></app-navbar-admin>
<!-- Boite -->
<div class="boite">
<!-- Photo de profil -->
<div style="text-align: center">
<img [src]="admin.profileImageUrl"
onerror="this.onerror=null; this.src='assets/profil.png'">
</div>
<!-- login -->
<div class="row myRow">
<div class="col-6 myLabel">Pseudo:</div>
<div class="col-6 myValue"> {{admin.login}} </div>
</div>
<!-- email -->
<div class="row myRow">
<div class="col-6 myLabel">Mail:</div>
<div class="col-6 myValue"> {{admin.email}} </div>
</div>
<!-- createdAt -->
<div class="row myRow">
<div class="col-6 myLabel">Date de création:</div>
<div class="col-6 myValue">{{admin.createdAt | date:'dd/LL/YYYY'}}</div>
</div>
<!-- Modifier profil -->
<div class="btnContainer">
<button mat-button class="myBtn" (click)="onModifier()">Modifier profil</button>
</div>
</div>
</div>
</div>

View file

@ -1,61 +0,0 @@
.myContainer {
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
}
.boite {
margin-left: auto;
margin-right: auto;
width: 25%;
margin-top: 10vh;
border: solid 3px;
border-radius: 10px;
padding: 20px 40px 20px 40px;
background-color: #ffffff;
text-align: center;
box-shadow: 10px 5px 5px black;
}
.lightTheme .boite {
border-color: black;
}
.darkTheme .boite {
border-color: white;
}
img {
margin: 0px 0px 10px 0px;
width: 5vw;
height: 5vw;
border: solid 2px black;
border-radius: 50%;
font-size: xxx-large;
}
.myRow {
margin: 15px 0px 15px 0px;
}
.myLabel {
text-align: right;
padding: 0px 5px 0px 0px;
margin: 0px;
font-weight: bold;
}
.myValue {
text-align: left;
padding: 0px 0px 0px 5px;
margin: 0px;
}
.btnContainer {
text-align: center;
margin-top: 40px;
}
.myBtn {
border: solid 1px black;
background-color: white;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageProfilAdminComponent } from './page-profil-admin.component';
describe('PageProfilAdminComponent', () => {
let component: PageProfilAdminComponent;
let fixture: ComponentFixture<PageProfilAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageProfilAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageProfilAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,90 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {User} from "../../../utils/interfaces/user";
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MatDialog} from "@angular/material/dialog";
import {MatSnackBar} from "@angular/material/snack-bar";
import {PopupUpdateAdminComponent} from "../popup-update-admin/popup-update-admin.component";
import {MessageService} from "../../../utils/services/message/message.service";
import {ProfilService} from "../../../utils/services/profil/profil.service";
@Component({
selector: 'app-page-profil-admin',
templateUrl: './page-profil-admin.component.html',
styleUrls: ['./page-profil-admin.component.scss']
})
export class PageProfilAdminComponent implements OnInit
{
admin: User = {
_id: "",
login: "",
hashPass: "",
email: "",
role: {
name: "admin",
permission: 10,
isAccepted: true,
},
profileImageUrl: "",
dateOfBirth: null,
gender: "man",
interests: [],
company: "",
isActive: true,
createdAt: new Date(),
updatedAt: new Date(),
lastConnexion: null
};
constructor( public themeService: ThemeService,
public dialog: MatDialog,
private snackBar: MatSnackBar,
private messageService: MessageService,
private profilService: ProfilService ) { }
ngOnInit(): void
{
this.messageService
.get( "user/findOne/"+this.profilService.getId())
.subscribe( retour => this.ngOnInitCallback(retour), err => this.ngOnInitCallback(err) )
}
ngOnInitCallback(retour: any)
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.admin = retour.data;
}
}
onModifier()
{
const config = {
width: '25%',
data: { admin: this.admin }
};
this.dialog
.open(PopupUpdateAdminComponent, config)
.afterClosed()
.subscribe(retour => {
if((retour === null) || (retour === undefined))
{
const config = { duration: 1000, panelClass: "custom-class" };
this.snackBar.open( "Opération annulé", "", config);
}
else
{
this.admin = retour;
}
});
}
}

View file

@ -1,59 +0,0 @@
<div class="myContainer">
<div class="boite">
<!-- photo de profil -->
<div style="text-align: center">
<img [src]="adminCopy.profileImageUrl" onerror="this.onerror=null; this.src='assets/profil.png'"><br>
<input title="lien vers image" type="text" [(ngModel)]="adminCopy.profileImageUrl" style="width: 90%">
</div>
<!-- divider -->
<br><mat-divider></mat-divider><br>
<!-- login -->
<mat-form-field appearance="fill">
<mat-label>Pseudo</mat-label>
<input matInput type="text" [(ngModel)]="adminCopy.login">
</mat-form-field><br>
<!-- divider -->
<mat-divider></mat-divider><br>
<!-- Modifier mot de passe -->
<div>
Modifier mot de passe:
<mat-checkbox [(ngModel)]="changePassword"></mat-checkbox>
</div>
<!-- nouveau mot de passe -->
<div *ngIf="changePassword" style="margin-top: 10px">
<!-- Nouveau mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Nouveau mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="newPassword">
</mat-form-field>
<br>
<!-- Confirmation npuveau mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Confirmation nouveau mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="confirmNewPassword">
</mat-form-field>
</div>
<div *ngIf="!changePassword"><br></div>
<!-- divider -->
<mat-divider></mat-divider><br>
<!-- message d'erreur -->
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
<span class="mat-error">{{errorMessage}}</span>
</div>
<!-- boutons -->
<div style="width: 100%; text-align: right">
<button mat-button (click)="this.dialogRef.close(null)"> Annuler </button>
<button mat-button (click)="onValider()"> Enregistrer </button>
</div>
</div>
</div>

View file

@ -1,33 +0,0 @@
.boite {
font-size: small;
}
button {
font-size: small;
}
img {
margin: 0px 0px 10px 0px;
width: 5vw;
height: 5vw;
border: solid 2px black;
border-radius: 50%;
font-size: xxx-large;
}
// -------------------------------------------------------------------------
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
background-color: white !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupUpdateAdminComponent } from './popup-update-admin.component';
describe('PopupUpdateAdminComponent', () => {
let component: PopupUpdateAdminComponent;
let fixture: ComponentFixture<PopupUpdateAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupUpdateAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupUpdateAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,124 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {User} from "../../../utils/interfaces/user";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
import {ProfilService} from "../../../utils/services/profil/profil.service";
@Component({
selector: 'app-popup-update-admin',
templateUrl: './popup-update-admin.component.html',
styleUrls: ['./popup-update-admin.component.scss']
})
export class PopupUpdateAdminComponent implements OnInit
{
adminCopy: User;
newPassword: string = "";
confirmNewPassword: string = "" ;
changePassword: boolean = false ;
hasError: boolean = false;
errorMessage: string = "" ;
constructor( public dialogRef: MatDialogRef<PopupUpdateAdminComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService,
private profilService: ProfilService ) { }
ngOnInit(): void
{
const admin0 = this.data.admin;
this.adminCopy = {
_id: admin0._id,
login: admin0.login,
hashPass: admin0.hashPass,
email: admin0.email,
role: {
name: admin0.role.name,
permission: admin0.role.permission,
isAccepted: admin0.role.isAccepted,
},
profileImageUrl: admin0.profileImageUrl,
dateOfBirth: admin0.dateOfBirth,
gender: admin0.gender,
interests: [],
company: "",
isActive: admin0.isActive,
createdAt: admin0.createdAt,
updatedAt: admin0.updatedAt,
lastConnexion: admin0.lastConnexion
};
for(let interest of admin0.interests) this.adminCopy.interests.push(interest);
}
onValider()
{
this.checkField();
if(!this.hasError)
{
if(this.changePassword) this.adminCopy.hashPass = this.newPassword;
const data = {
login: this.adminCopy.login,
hashPass: this.adminCopy.hashPass,
email: this.adminCopy.email,
profileImageUrl: this.adminCopy.profileImageUrl,
};
this.messageService
.put("user/update/"+this.profilService.getId(), data)
.subscribe( ret => this.onValiderCallback(ret), err => this.onValiderCallback(err) );
}
}
onValiderCallback(retour: any)
{
if(retour.status !== "success") {
console.log(retour);
this.dialogRef.close(null);
}
else {
this.profilService.setProfileImageUrl(this.adminCopy.profileImageUrl);
this.dialogRef.close(this.adminCopy);
}
}
checkField()
{
if(this.adminCopy.login.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'pseudo'" ;
this.hasError = true;
}
else if(this.adminCopy.email.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'email'" ;
this.hasError = true;
}
else if(!this.isValidEmail(this.adminCopy.email)) {
this.errorMessage = "Email invalide" ;
this.hasError = true;
}
else if((this.changePassword) && (this.newPassword.length === 0)) {
this.errorMessage = "Veuillez remplir le champ 'mot de passe'" ;
this.hasError = true;
}
else if((this.changePassword) && (this.newPassword !== this.confirmNewPassword)) {
this.errorMessage = "Le mot de passe est différent de sa confirmation" ;
this.hasError = true;
}
else {
this.errorMessage = "" ;
this.hasError = false;
}
}
isValidEmail(email)
{
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
}

View file

@ -1,43 +0,0 @@
<mat-form-field class="example-chip-list" appearance="fill">
<!-- ------------------------------------------------------------------------------------ -->
<mat-label>Centres d'intérêt</mat-label>
<!-- ------------------------------------------------------------------------------------ -->
<mat-chip-list #chipList aria-label="Fruit selection">
<mat-chip
*ngFor="let interest of myInterests"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(interest)">
{{interest}}
<button matChipRemove *ngIf="removable">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
<input
placeholder="Tapez un centre d'intérêt et pressez 'Entrer' pour l'inserer"
#tagInput
[formControl]="formControl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)">
</mat-chip-list>
<!-- ------------------------------------------------------------------------------------ -->
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let interest of filteredInterests | async" [value]="interest">
{{interest}}
</mat-option>
</mat-autocomplete>
<!-- ------------------------------------------------------------------------------------ -->
</mat-form-field>

View file

@ -1,3 +0,0 @@
mat-form-field {
width: 100%;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { InputInterestsAdminComponent } from './input-interests-admin.component';
describe('InputInterestsAdminComponent', () => {
let component: InputInterestsAdminComponent;
let fixture: ComponentFixture<InputInterestsAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ InputInterestsAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(InputInterestsAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,121 +0,0 @@
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {COMMA, ENTER} from "@angular/cdk/keycodes";
import {FormControl} from "@angular/forms";
import {Observable} from "rxjs";
import {MessageService} from "../../../utils/services/message/message.service";
import {map, startWith} from "rxjs/operators";
import {MatChipInputEvent} from "@angular/material/chips";
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
@Component({
selector: 'app-input-interests-admin',
templateUrl: './input-interests-admin.component.html',
styleUrls: ['./input-interests-admin.component.scss']
})
export class InputInterestsAdminComponent implements OnInit
{
selectable = true;
removable = true;
separatorKeysCodes: number[] = [ENTER, COMMA];
formControl = new FormControl();
filteredInterests: Observable<string[]>;
@Input() myInterests: string[] = [];
allInterests: string[] = [];
@Output() eventEmitter = new EventEmitter<string[]>();
@ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement>;
interestsNotSelected: string[] = [];
constructor( private messageService: MessageService ) {}
ngOnInit(): void
{
this.filteredInterests = this.formControl.valueChanges.pipe(
startWith(null),
map((fruit: string | null) => fruit ? this._filter(fruit) : this.interestsNotSelected.slice()));
this.messageService
.get("misc/getInterests")
.subscribe( retour => {
if(retour.status !== "success") {
console.log(retour);
}
else {
this.allInterests = [];
for(let elt of retour.data)
{
this.allInterests.push(elt.interest);
this.interestsNotSelected.push(elt.interest);
}
}
});
}
add(event: MatChipInputEvent): void
{
const value = (event.value || '').trim();
const index = this.interestsNotSelected.indexOf(value);
if (value && (index !== -1) && (!this.myInterests.includes(value)))
{
this.myInterests.push(value);
event.chipInput!.clear();
this.formControl.setValue(null);
this.eventEmitter.emit(this.myInterests);
this.interestsNotSelected.splice(index, 1);
}
}
remove(interest: string): void
{
// supprimer 'interest' de 'myInterest'
const index = this.myInterests.indexOf(interest);
if (index >= 0) this.myInterests.splice(index, 1);
this.eventEmitter.emit(this.myInterests);
// remmettre 'interest' dans 'interestsNotSelected'
if(!this.interestsNotSelected.includes(interest))
{
const indexOfAutres = this.interestsNotSelected.indexOf("Autres");
if(indexOfAutres !== -1)
{
this.interestsNotSelected.splice(indexOfAutres, 1);
if(interest !== "Autres") this.interestsNotSelected.push(interest);
this.interestsNotSelected.sort();
this.interestsNotSelected.push("Autres");
}
else {
this.interestsNotSelected.push(interest);
if(interest !== "Autres") this.interestsNotSelected.sort();
}
}
}
selected(event: MatAutocompleteSelectedEvent): void
{
const value = event.option.viewValue;
if(!this.myInterests.includes(value))
{
this.myInterests.push(value);
const index = this.interestsNotSelected.indexOf(value);
this.interestsNotSelected.splice(index, 1);
}
this.tagInput.nativeElement.value = '';
this.formControl.setValue(null);
this.eventEmitter.emit(this.myInterests);
}
private _filter(value: string): string[]
{
const filterValue = value.toLowerCase();
return this.interestsNotSelected.filter(fruit => fruit.toLowerCase().includes(filterValue));
}
}

View file

@ -1,193 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<app-navbar-admin></app-navbar-admin><br><br>
<!-- filtre + btnAddUser -->
<div class="row" style="margin: 20px 3% 20px 3%">
<!-- filtre -->
<div class="col-9" style="padding: 0px 0px 0px 0px;">
<div class="filtersContainer mat-elevation-z8">
<!-- titre -->
<div style="font-weight: bold; margin-bottom: 10px;">
Filtre
</div>
<mat-divider></mat-divider>
<!-- filtre textuelle-->
<div style="margin: 10px 0px 20px 2%;">
<input class="textFilter" (keyup)="applyFilter($event)" placeholder="Rechercher par mots-clés...">
</div>
<!-- role + actif + période -->
<div class="row myRow">
<!-- choix role -->
<div class="col-2">
<mat-radio-group [(ngModel)]="roleName">
<mat-radio-button value="user" (click)="this.roleName = 'user'; onFilter()">
Utilisateur
</mat-radio-button><br>
<mat-radio-button value="advertiser" (click)="this.roleName = 'advertiser'; onFilter()">
Annonceur
</mat-radio-button><br>
<mat-radio-button value="admin" (click)="this.roleName = 'admin'; onFilter()">
Admin
</mat-radio-button>
</mat-radio-group>
</div>
<!-- actif -->
<div class="col-2">
<mat-checkbox [(ngModel)]="active" (change)="onFilter()">actif</mat-checkbox><br>
<mat-checkbox [(ngModel)]="noActive" (change)="onFilter()">non actif</mat-checkbox>
</div>
<!-- période -->
<div class="col-8" style="text-align: right;">
Période de dernière connexion: &nbsp;
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>Date de début</mat-label>
<input matInput type="date"
[ngModel] ="startDate | date:'yyyy-MM-dd'"
(ngModelChange)="onNewStartDate($event); onFilter();">
</mat-form-field>
&nbsp; - &nbsp;
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>Date de fin</mat-label>
<input matInput type="date"
[ngModel] ="endDate | date:'yyyy-MM-dd'"
(ngModelChange)="onNewEndDate($event); onFilter();">
</mat-form-field>
</div>
</div>
</div>
</div>
<!-- btnAddUser -->
<div class="col-3" style="text-align: right; position: relative;">
<button mat-button class="btnAjouter" (click)="onCreateUser()" style="position: absolute; bottom: 0; right: 0;">
<mat-icon>add_circle</mat-icon> Ajouter un utilisateur
</button>
</div>
</div>
<!-- Table -->
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- IsActive Column -->
<ng-container matColumnDef="isActive">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
<mat-icon>power_settings_new</mat-icon>
</th>
<td mat-cell *matCellDef="let user">
<mat-slide-toggle *ngIf="user.role.name !== 'superAdmin'" [(ngModel)]="user.isActive" (click)="onSliderIsActive(user)"></mat-slide-toggle>
<mat-slide-toggle *ngIf="user.role.name === 'superAdmin'" [(ngModel)]="user.isActive" disabled></mat-slide-toggle>
</td>
</ng-container>
<!-- Login Column -->
<ng-container matColumnDef="login">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Pseudo </th>
<td mat-cell *matCellDef="let user">
{{user.login}}
</td>
</ng-container>
<!-- Mail Column -->
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
<td mat-cell *matCellDef="let user">
{{user.email}}
</td>
</ng-container>
<!-- DateOfBirth Column -->
<ng-container matColumnDef="dateOfBirth">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de naissance </th>
<td mat-cell *matCellDef="let user">
<span *ngIf="((user.dateOfBirth === null) || (user.dateOfBirth === undefined)); else elseDateOfBirth"></span>
<ng-template #elseDateOfBirth> {{ user.dateOfBirth | date:'dd/LL/YYYY' }} </ng-template>
</td>
</ng-container>
<!-- Age Column -->
<ng-container matColumnDef="age">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Âge </th>
<td mat-cell *matCellDef="let user">
<span *ngIf="(user.age < 0) ; else elseAge"></span>
<ng-template #elseAge> {{user.age}} </ng-template>
</td>
</ng-container>
<!-- Sexe Column -->
<ng-container matColumnDef="sexe">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Sexe </th>
<td mat-cell *matCellDef="let user">
<span *ngIf="(user.gender === 'man') ; else elseSexe"> H </span>
<ng-template #elseSexe> F </ng-template>
</td>
</ng-container>
<!-- Interests Column -->
<ng-container matColumnDef="interests">
<th mat-header-cell *matHeaderCellDef> Centres d'intérêt </th>
<td mat-cell *matCellDef="let user">
<span *ngFor="let interest of user.interests; let isLast = last;">
<span *ngIf="!isLast ; else elseInterests"> {{interest}}, </span>
<ng-template #elseInterests> {{interest}} </ng-template>
</span>
</td>
</ng-container>
<!-- CreatedAt Column -->
<ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de création </th>
<td mat-cell *matCellDef="let user">
{{ user.createdAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</td>
</ng-container>
<!-- LastConnexion Column -->
<ng-container matColumnDef="lastConnexion">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Dernière connexion </th>
<td mat-cell *matCellDef="let user">
{{ user.lastConnexion | date:'dd/LL/YYYY à HH:mm:ss' }}
</td>
</ng-container>
<!-- IsAccepted Column -->
<ng-container matColumnDef="isAccepted">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Accepté </th>
<td mat-cell *matCellDef="let user">
<mat-slide-toggle [(ngModel)]="user.role.isAccepted" (click)="onSlideIsAccepted(user)"></mat-slide-toggle>
</td>
</ng-container>
<!-- Directives -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4"> Aucune vidéo ne correspond au filtre: "{{input.value}}" </td>
</tr>
</table>
<div style="width: 94%; margin: auto auto">
<mat-paginator [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons aria-label="Select page of periodic elements"></mat-paginator>
</div>
<br><br>
</div>
</div>

View file

@ -1,99 +0,0 @@
.myContainer {
min-height: 100vh;
font-size: small;
}
// ----------------------------------------------------------
.filtersContainer {
width: 90%;
background-color: white;
padding: 10px 10px 10px 10px;
}
.myRow {
margin-left: 1%;
}
.textFilter {
width: 50%;
font-size: medium;
border-radius: 5px;
}
.btnAjouter {
background-color: white;
border: solid 1px black;
}
// ----------------------------------------------------------
table {
margin: 0 auto;
width: 94%;
font-size: small;
}
.darkTheme table { border: solid 2px white; }
th.mat-sort-header-sorted {
color: black;
}
td {
font-size: small;
}
// -------------------------------------------------------------------------
::ng-deep .mat-radio-inner-circle {
color: black !important;
background-color: black !important;
}
::ng-deep .mat-radio-outer-circle{
color: black !important;
border: solid 1px gray !important;
}
// -------------------------------------------------------------------------
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
border: solid 1px black !important;
background-color: white !important;
}
// --------------------------------------------------------------------
// rong gauche
::ng-deep .mat-slide-toggle-thumb {
background-color: white !important;
}
// trait droite
::ng-deep .mat-slide-toggle-bar {
background-color: gray !important;
}
// rond droite
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
background-color: white !important;
}
// trait gauche
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
background-color: cornflowerblue !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageUserListComponent } from './page-user-list.component';
describe('PageUserListComponent', () => {
let component: PageUserListComponent;
let fixture: ComponentFixture<PageUserListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageUserListComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageUserListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,233 +0,0 @@
import {AfterViewInit, Component, ViewChild} from '@angular/core';
import {MatSort} from "@angular/material/sort";
import {MatPaginator} from "@angular/material/paginator";
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MatDialog} from "@angular/material/dialog";
import {MatSnackBar} from "@angular/material/snack-bar";
import {MatTableDataSource} from "@angular/material/table";
import {PopupDeleteUserComponent} from "../popup-delete-user/popup-delete-user.component";
import {PopupCreateUserComponent} from "../popup-create-user/popup-create-user.component";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-page-user-list',
templateUrl: './page-user-list.component.html',
styleUrls: ['./page-user-list.component.scss']
})
export class PageUserListComponent implements AfterViewInit
{
displayedColumns: string[];
displayedColumnsUser: string[] = [ 'isActive', 'login', 'email', 'dateOfBirth', 'age', 'sexe', 'interests', 'createdAt', 'lastConnexion' ];
displayedColumnsAdvertiser: string[] = [ 'isActive', 'login', 'email', 'createdAt', 'lastConnexion', 'isAccepted' ];
displayedColumnsAdmin: string[] = [ 'isActive', 'login', 'email', 'createdAt', 'lastConnexion' ];
tabUser: any[] = [];
tabAdvertiser: any[] = [];
tabAdmin: any[] = [];
roleName: string = "user" ;
dataSource ;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
active: boolean = true;
noActive: boolean = false;
startDate: Date = null;
endDate: Date = null;
constructor( public themeService: ThemeService,
public dialog: MatDialog,
private snackBar: MatSnackBar,
private messageService: MessageService ) { }
ngAfterViewInit(): void
{
this.messageService
.get("user/findAll")
.subscribe(ret => this.ngAfterViewInitCallback(ret), err => this.ngAfterViewInitCallback(err));
}
ngAfterViewInitCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
for(let person of retour.data)
{
if(person.role.name === "user") {
person["age"] = this.getAge(person.dateOfBirth);
this.tabUser.push(person);
}
else if(person.role.name === "advertiser") this.tabAdvertiser.push(person);
else this.tabAdmin.push(person);
}
this.onFilter();
}
}
applyFilter(event: Event): void
{
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
}
onDelete(user: any): void
{
const config = {
data: { user: user }
};
this.dialog
.open(PopupDeleteUserComponent, config)
.afterClosed()
.subscribe( retour => {
const config = { duration: 1000, panelClass: "custom-class" };
let message = "" ;
if((retour === undefined) || (retour === null)) {
message = "Opération annulée" ;
}
else {
const index = this.dataSource.data.findIndex( elt => (elt.id === user.id));
this.dataSource.data.splice(index, 1);
this.dataSource.data = this.dataSource.data;
this.dataSource = this.dataSource;
message = user.login + " a bien été supprimée ✔" ;
}
this.snackBar.open(message, "", config);
});
}
onCreateUser(): void
{
const config = { width: '50%' };
this.dialog
.open(PopupCreateUserComponent, config)
.afterClosed()
.subscribe( retour => {
const config = { duration: 1000, panelClass: "custom-class" };
if((retour === null) || (retour === undefined)) {
this.snackBar.open( "Opération annulée", "", config);
}
else {
this.snackBar.open( "L'utilisateur a bien été créé", "", config);
if(retour.role.name === "user") this.tabUser.push(retour);
else if(retour.role.name === "advertiser") this.tabAdvertiser.push(retour);
else if(retour.role.name === "admin") this.tabAdmin.push(retour);
this.onFilter();
}
});
}
onSliderIsActive(user: any): void
{
// il faut envoyer la négation de user.isActive
this.messageService
.put("user/update/"+user.id, { isActive: !user.isActive })
.subscribe(
ret => {},
err => {
console.log("onSliderIsActive");
console.log(err);
}
);
}
onSlideIsAccepted(user: any): void
{
// il faut envoyer la négation de user.role.isAccepted
const role0 = {
name: user.role.name,
permission: user.role.permission,
isAccepted: !user.role.isAccepted,
};
this.messageService
.put("user/update/"+user.id, {role: role0})
.subscribe(
ret => {},
err => {
console.log("onSlideIsAccepted");
console.log(err);
}
);
}
getAge(date: Date): number
{
if((date === null) || (date === undefined)) return -1;
else {
const diff = Date.now() - (new Date(date)).getTime();
const age = new Date(diff);
return Math.abs(age.getUTCFullYear() - 1970);
}
}
onFilter(): void
{
let tab1 = [];
if(this.roleName === "user") {
this.displayedColumns = this.displayedColumnsUser;
tab1 = this.tabUser;
}
else if(this.roleName === "advertiser") {
this.displayedColumns = this.displayedColumnsAdvertiser;
tab1 = this.tabAdvertiser;
}
else if(this.roleName === "admin") {
this.displayedColumns = this.displayedColumnsAdmin;
tab1 = this.tabAdmin;
}
let tab2 = [];
for(let user of tab1)
{
let valide: boolean = true;
if(user.isActive && this.active) valide = true;
else if((!user.isActive) && this.noActive) valide = true;
else valide = false;
if(valide)
{
if ((user.lastConnexion === null) && (this.startDate !== null)) valide = false;
else if ((user.lastConnexion === null) && (this.endDate !== null)) valide = false;
else if (this.startDate !== null)
{
if(this.startDate.getTime() > user.lastConnexion.getTime()) valide = false;
else if (this.endDate !== null)
{
if(this.endDate.getTime() < user.lastConnexion.getTime()) valide = false;
}
}
}
if(valide) tab2.push(user);
}
this.dataSource = new MatTableDataSource(tab2);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
}
onNewStartDate(event): void {
this.startDate = new Date(event);
}
onNewEndDate(event): void {
this.endDate = new Date(event);
}
}

View file

@ -1,160 +0,0 @@
<div class="myContainer">
<!-- Rôle -->
<div class="matRadioGroupContainer">
<mat-radio-group [(ngModel)]="user.role.name" (change)="hasError=false; errorMessage = '';">
<mat-radio-button value="user"> Utilisateur </mat-radio-button><br>
<mat-radio-button value="advertiser"> Annonceur </mat-radio-button><br>
<mat-radio-button value="admin"> Admin </mat-radio-button>
</mat-radio-group>
</div><br>
<!-- divider -->
<mat-divider></mat-divider><br>
<!-- userBlock or advertiserOrAdminBlock -->
<div *ngIf="user.role.name === 'user'; then userBlock"></div>
<div *ngIf="(user.role.name === 'advertiser' || user.role.name === 'admin'); then advertiserOrAdminBlock"></div>
<!-- divider -->
<mat-divider *ngIf="user.role.name !== ''" style="margin-top: 10px;"></mat-divider><br>
<!-- Error -->
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
<span class="mat-error">{{errorMessage}}</span>
</div>
<!-- Boutons -->
<div style="width: 100%; text-align: right">
<button mat-button (click)="this.dialogRef.close(null)"> Annuler </button>
<button mat-button (click)="onEnregistrer()" [disabled]="user.role.name === ''" > Enregistrer </button>
</div>
</div>
<!-- ------------------------------------------------------------------------------------------------------------------- -->
<!-- userBlock -->
<ng-template #userBlock>
<!-- photo de profil -->
<div style="text-align: center">
<img [src]="user.profileImageUrl" onerror="this.onerror=null; this.src='assets/profil.png'"><br>
<input title="lien vers image" type="text" [(ngModel)]="user.profileImageUrl" style="width: 90%">
</div><br>
<div class="row">
<!-- Colonne gauche -->
<div class="col-4 leftCol">
<!-- Email -->
<mat-form-field appearance="fill">
<mat-label>Email</mat-label>
<input matInput type="email" [(ngModel)]="user.email" required>
</mat-form-field><br>
<!-- Login -->
<mat-form-field appearance="fill">
<mat-label>Pseudo</mat-label>
<input matInput type="text" [(ngModel)]="user.login" required>
</mat-form-field><br>
<!-- Mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="password" required>
</mat-form-field><br>
<!-- Confirmation mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Confirmation mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="confirmPassword" required>
</mat-form-field>
</div>
<!-- Colonne droite -->
<div class="col-8">
<!-- dateOfBirth -->
<mat-form-field appearance="fill">
<mat-label>Date de naissance</mat-label>
<input matInput type="date"
[ngModel] ="user.dateOfBirth | date:'yyyy-MM-dd'"
(ngModelChange)="user.dateOfBirth = $event">
</mat-form-field><br>
<!-- gender -->
<mat-radio-group [(ngModel)]="user.gender">
<mat-radio-button value="man"> Homme </mat-radio-button>&nbsp; &nbsp;
<mat-radio-button value="woman"> Femme </mat-radio-button>
</mat-radio-group>
<br><br>
<!-- interests -->
<app-input-interests-admin
[myInterests]="user.interests"
(eventEmitter)="onEventInputInterests($event)"></app-input-interests-admin>
</div>
</div>
</ng-template>
<!-- ------------------------------------------------------------------------------------------------------------------- -->
<!-- advertiserOrAdminBlock -->
<ng-template #advertiserOrAdminBlock>
<!-- photo de profil -->
<div style="text-align: center">
<img [src]="user.profileImageUrl" onerror="this.onerror=null; this.src='assets/profil.png'"><br>
<input title="lien vers image" type="text" [(ngModel)]="user.profileImageUrl" style="width: 100%">
</div><br>
<!-- email + login + mdp + confirmation -->
<div class="row">
<!-- email + login -->
<div class="col-6">
<!-- email -->
<mat-form-field appearance="fill">
<mat-label>Email</mat-label>
<input matInput type="text" [(ngModel)]="user.email" required>
</mat-form-field><br>
<!-- login -->
<mat-form-field appearance="fill">
<mat-label>Pseudo</mat-label>
<input matInput type="text" [(ngModel)]="user.login" required>
</mat-form-field><br>
<!-- company -->
<mat-form-field appearance="fill" *ngIf="user.role.name === 'advertiser'">
<mat-label>Entreprise</mat-label>
<input matInput type="text" [(ngModel)]="user.company">
</mat-form-field><br *ngIf="user.role.name === 'advertiser'">
</div>
<!-- mdp + confirmation -->
<div class="col-6">
<!-- mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="password" required>
</mat-form-field><br>
<!-- confirmation mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Confirmation nouveau mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="confirmPassword" required>
</mat-form-field>
</div>
</div>
</ng-template>

View file

@ -1,16 +0,0 @@
.myContainer {
font-size: small;
}
img {
margin: 0px 0px 10px 0px;
width: 10%;
height: 10%;
border: solid 2px black;
border-radius: 50%;
font-size: xxx-large;
}
.leftCol {
border-right: solid 1px #dcdcdc;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupCreateUserComponent } from './popup-create-user.component';
describe('PopupCreateUserComponent', () => {
let component: PopupCreateUserComponent;
let fixture: ComponentFixture<PopupCreateUserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupCreateUserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupCreateUserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,127 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-popup-create-user',
templateUrl: './popup-create-user.component.html',
styleUrls: ['./popup-create-user.component.scss']
})
export class PopupCreateUserComponent implements OnInit
{
user: any;
hasError: boolean = false;
errorMessage: string = "";
password: string = "";
confirmPassword: string = "";
constructor( public dialogRef: MatDialogRef<PopupCreateUserComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService ) { }
// Initialise l'utilisateur qui va être créé
ngOnInit(): void
{
this.user = {
_id: "",
login: "",
hashPass: "",
email: "",
role: {
name: "",
permission: 0,
isAccepted: false,
},
profileImageUrl: "",
dateOfBirth: null,
gender: "man",
interests: [],
company: "",
isActive: false,
createdAt: new Date(),
updatedAt: new Date(),
lastConnexion: new Date()
};
}
// Crée le nouvel utilisateur
onEnregistrer(): void
{
this.checkField();
if(!this.hasError)
{
this.user.hashPass = this.password;
this.user.role = this.user.role.name;
this.messageService
.post("user/create", this.user)
.subscribe(ret => this.onEnregistrerCallback(ret), err => this.onEnregistrerCallback(err));
}
}
// Callback de 'onEnregistrer'
onEnregistrerCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.dialogRef.close(retour.data);
}
}
// Check les champs saisies par l'utilisateur
checkField(): void
{
if(this.user.login.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'pseudo'.";
this.hasError = true;
}
else if(this.user.email.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'email'.";
this.hasError = true;
}
else if(!this.isValidEmail(this.user.email)) {
this.errorMessage = "Email invalide.";
this.hasError = true;
}
else if(this.password.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'mot de passe'.";
this.hasError = true;
}
else if(this.password !== this.confirmPassword) {
this.errorMessage = "Le mot de passe est différent de sa confirmation.";
this.hasError = true;
}
else if((this.user.role.name === 'advertiser') && (this.user.company.length === 0)) {
this.errorMessage = "Veuillez remplir le champ 'entreprise'.";
this.hasError = true;
}
else {
this.errorMessage = "" ;
this.hasError = false;
}
}
// Indique si email a bien le format d'un email
isValidEmail(email): boolean
{
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
// Récupère la liste des centres d'intérets (car celle-ci est remplie à l'aide d'un component intermédiaire)
onEventInputInterests(myInterets: string[]): void
{
this.user.interests = myInterets;
}
}

View file

@ -1,8 +0,0 @@
<mat-dialog-content class="mat-typography">
Êtes-vous sûr de vouloir supprimer <i>{{user.login}}</i> ?
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close();">Annuler</button>
<button mat-button (click)="onValidate()" cdkFocusInitial>Valider</button>
</mat-dialog-actions>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupDeleteUserComponent } from './popup-delete-user.component';
describe('PopupDeleteUserComponent', () => {
let component: PopupDeleteUserComponent;
let fixture: ComponentFixture<PopupDeleteUserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupDeleteUserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupDeleteUserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,47 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-popup-delete-user',
templateUrl: './popup-delete-user.component.html',
styleUrls: ['./popup-delete-user.component.scss']
})
export class PopupDeleteUserComponent implements OnInit
{
user;
constructor( public dialogRef: MatDialogRef<PopupDeleteUserComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService ) { }
ngOnInit(): void
{
this.user = this.data.user;
}
onValidate(): void
{
// --- FAUX CODE ---
this.dialogRef.close(true);
// --- VRAI CODE ---
/*
this.messageService
.sendMessage("user/delete", {"advert": this.advert})
.subscribe( retour => {
if(retour.status === "error") {
console.log(retour);
this.dialogRef.close();
}
else {
this.dialogRef.close(true);
}
});
*/
}
}

View file

@ -1,37 +0,0 @@
<nav class="navbar navbar-expand-lg">
<!-- PolyNotFound -->
<a class="navbar-brand" routerLink="/admin/userList"> StreamNotFound </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- [userList] [adList] -->
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item active monLi">
<a *ngIf="(url !== routes[0]) && (url !== routes[1])" [routerLink]="routes[1]" class="nav-link">Liste des utillisateurs</a>
<a *ngIf="(url === routes[0]) || (url === routes[1])" [routerLink]="routes[1]" class="nav-link myActiveLink">Liste des utillisateurs</a>
</li>
<li class="nav-item active monLi">
<a *ngIf="url !== routes[2]" [routerLink]="routes[2]" class="nav-link">Liste des publicités</a>
<a *ngIf="url === routes[2]" [routerLink]="routes[2]" class="nav-link myActiveLink">Liste des publicités</a>
</li>
</ul>
</div>
<!-- Mon profil -->
<img [src]=profilService.getProfileImageUrl()
onerror="this.onerror=null; this.src='assets/profil.png'"
[routerLink]="routes[3]"
alt="">
<!-- Deconnexion -->
<button mat-button class="btnDeconnexion" (click)="onDeconnexion()" routerLink="/">
Déconnexion
</button>
</nav>

View file

@ -1,80 +0,0 @@
.navbar {
background-color: black;
height: 60px;
font-size: medium;
color: white;
}
.navbar-expand-lg {
border-bottom: solid;
border-color: white;
border-bottom-width: 2px;
}
// PolyNotFound
.navbar-brand {
font-family: cursive;
font-weight: bold;
font-size: x-large;
margin-left: 15px;
color: white;
}
.monLi {
margin: 0px 10px 0px 10px;
}
.nav-link {
color: white;
}
.nav-link:hover {
color: grey;
}
.myActiveLink {
text-decoration: underline;
}
.btnDeconnexion {
font-size: medium;
margin: 0px 10px 0px 10px
}
.btnDeconnexion:hover {
color: grey;
}
img {
border: solid 2px white;
border-radius: 50px;
margin: 0px 10px 0px 15px;
width: 40px;
height: 40px;
}
img:hover {
cursor: pointer;
}
// --------------------------------------------------------------------
::ng-deep .mat-slide-toggle-thumb {
background-color: #c8c8c8;
}
::ng-deep .mat-slide-toggle-bar {
background-color: #ffffff;
}
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
background-color: #ffffff;
}
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
background-color: #646464;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarAdminComponent } from './navbar-admin.component';
describe('NavbarAdminComponent', () => {
let component: NavbarAdminComponent;
let fixture: ComponentFixture<NavbarAdminComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavbarAdminComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(NavbarAdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,40 +0,0 @@
import {Component} from '@angular/core';
import {Router} from "@angular/router";
import {ProfilService} from "../../../utils/services/profil/profil.service";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-navbar-admin',
templateUrl: './navbar-admin.component.html',
styleUrls: ['./navbar-admin.component.scss']
})
export class NavbarAdminComponent
{
routes: string[] = [
"/admin", // 0
"/admin/userList", // 1
"/admin/adList", // 2
"/admin/myProfil", // 3
];
url = this.router.url;
constructor( private router: Router,
public profilService: ProfilService,
private messageService: MessageService ) { }
onDeconnexion(): void
{
this.messageService
.delete('user/logout')
.subscribe(retour => this.onDeconnexionCallback(retour), err => this.onDeconnexionCallback(err));
}
onDeconnexionCallback(retour: any): void
{
if(retour.status !== "success") console.log(retour);
}
}

View file

@ -1,33 +0,0 @@
<div title="bobo" class="container" appDragAndDrop (fileDropped)="onFileDropped($event)">
<input type="file" #fileDropRef id="fileDropRef" multiple (change)="fileBrowseHandler($event.target.files)" />
<div style="font-weight: bold">Images</div>
<img src="/assets/uploadFile.png" width="50" height="50" style="margin-top: 5px">
<div style="font-style: italic; margin-top: 10px">Glisser déposer</div>
<div style="font-style: italic">ou</div>
<div style="font-style: italic" for="fileDropRef">Cliquer pour selectionner</div>
</div>
<div style="text-align: center;">
<mat-icon [title]=info_image>info</mat-icon>
</div>
<div class="files-list">
<div class="single-file" *ngFor="let file of files; let i = index">
<img src="/assets/uploadFile.png" width="45px" alt="file">
<div class="info">
<h4 class="name">
{{ file?.name }}
</h4>
<p class="size">
{{ formatBytes(file?.size) }}
</p>
<div class="progress-cont">
<div class="progress" [style.width]="file?.progress + '%'">
</div>
</div>
</div>
<button mat-icon-button class="delete" width="20px" alt="file" (click)="deleteFile(i)">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>

View file

@ -1,135 +0,0 @@
.container {
width: 450px;
height: 180px;
padding: 20px 0px 20px 0px;
text-align: center;
border: dashed 1px #979797;
position: relative;
margin: 0 auto;
}
input {
opacity: 0;
position: absolute;
z-index: 2;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.fileover {
animation: shake 1s;
animation-iteration-count: infinite;
}
.files-list {
margin-top: 1.5rem;
.single-file {
display: flex;
padding: 0.5rem;
justify-content: space-between;
align-items: center;
border: dashed 1px #979797;
margin-bottom: 1rem;
img.delete {
margin-left: 0.5rem;
cursor: pointer;
align-self: flex-end;
}
display: flex;
flex-grow: 1;
.name {
font-size: 14px;
font-weight: 500;
color: #353f4a;
margin: 0;
}
.size {
font-size: 12px;
font-weight: 500;
color: #a4a4a4;
margin: 0;
margin-bottom: 0.25rem;
}
.info {
width: 100%
}
}
}
/* Shake animation */
@keyframes shake {
0% {
transform: translate(1px, 1px) rotate(0deg);
}
10% {
transform: translate(-1px, -2px) rotate(-1deg);
}
20% {
transform: translate(-3px, 0px) rotate(1deg);
}
30% {
transform: translate(3px, 2px) rotate(0deg);
}
40% {
transform: translate(1px, -1px) rotate(1deg);
}
50% {
transform: translate(-1px, 2px) rotate(-1deg);
}
60% {
transform: translate(-3px, 1px) rotate(0deg);
}
70% {
transform: translate(3px, 1px) rotate(-1deg);
}
80% {
transform: translate(-1px, -1px) rotate(1deg);
}
90% {
transform: translate(1px, 2px) rotate(0deg);
}
100% {
transform: translate(1px, -2px) rotate(-1deg);
}
}
.progress-cont {
height: 7px;
width: 100%;
border-radius: 4px;
background-color: #d0d0d0;
position: relative;
.progress {
width: 0;
height: 100%;
position: absolute;
z-index: 1;
top: 0;
left: 0;
border-radius: 4px;
background-color: #4c97cb;
transition: 0.5s all;
}
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DragAndDropComponent } from './drag-and-drop.component';
describe('DragAndDropComponent', () => {
let component: DragAndDropComponent;
let fixture: ComponentFixture<DragAndDropComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ DragAndDropComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DragAndDropComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,93 +0,0 @@
import {Component, ElementRef, EventEmitter, OnInit, Output, ViewChild} from '@angular/core';
@Component({
selector: 'app-drag-and-drop',
templateUrl: './drag-and-drop.component.html',
styleUrls: ['./drag-and-drop.component.scss']
})
export class DragAndDropComponent
{
@ViewChild("fileDropRef", { static: false }) fileDropEl: ElementRef;
info_image = "Vos annonces seront affichées dans un rectangle de rapport 1/5 avec: \n • 1 la largeur du rectangle \n • 5 la hauteur du rectangle" ;
files: any[] = [];
@Output() eventEmitter = new EventEmitter<any>();
/**
* on file drop handler
*/
onFileDropped($event) {
this.prepareFilesList($event);
this.eventEmitter.emit(this.files);
}
/**
* handle file from browsing
*/
fileBrowseHandler(files) {
this.prepareFilesList(files);
this.eventEmitter.emit(this.files);
}
/**
* Delete file from files list
* @param index (File index)
*/
deleteFile(index: number) {
if (this.files[index].progress < 100) {
console.log("Upload in progress.");
return;
}
this.files.splice(index, 1);
this.eventEmitter.emit(this.files);
}
/**
* Simulate the upload process
*/
uploadFilesSimulator(index: number) {
setTimeout(() => {
if (index === this.files.length) {
return;
} else {
const progressInterval = setInterval(() => {
if (this.files[index].progress === 100) {
clearInterval(progressInterval);
this.uploadFilesSimulator(index + 1);
} else {
this.files[index].progress += 5;
}
}, 200);
}
}, 1000);
}
/**
* Convert Files list to normal array list
* @param files (Files List)
*/
prepareFilesList(files: Array<any>) {
for (const item of files) {
item.progress = 0;
this.files.push(item);
}
this.fileDropEl.nativeElement.value = "";
this.uploadFilesSimulator(0);
}
/**
* format bytes
* @param bytes (File size in bytes)
* @param decimals (Decimals point)
*/
formatBytes(bytes, decimals = 2) {
if (bytes === 0) {
return "0 Bytes";
}
const k = 1024;
const dm = decimals <= 0 ? 0 : decimals;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
}
}

View file

@ -1,43 +0,0 @@
<mat-form-field class="example-chip-list" appearance="fill">
<!-- ------------------------------------------------------------------------------------ -->
<mat-label>Sujets</mat-label>
<!-- ------------------------------------------------------------------------------------ -->
<mat-chip-list #chipList aria-label="Fruit selection">
<mat-chip
*ngFor="let interest of myInterests"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(interest)">
{{interest}}
<button matChipRemove *ngIf="removable">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
<input
placeholder="Tapez un centre d'intérêt et pressez 'Entrer' pour l'inserer"
#tagInput
[formControl]="formControl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)">
</mat-chip-list>
<!-- ------------------------------------------------------------------------------------ -->
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let interest of filteredInterests | async" [value]="interest">
{{interest}}
</mat-option>
</mat-autocomplete>
<!-- ------------------------------------------------------------------------------------ -->
</mat-form-field>

View file

@ -1,16 +0,0 @@
mat-form-field {
width: 100%;
font-size: small;
}
mat-chip-list {
font-size: small;
}
mat-chip {
font-size: small;
}
input {
font-size: small;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { InputInterestsAdComponent } from './input-interests-ad.component';
describe('BarTagsComponent', () => {
let component: InputInterestsAdComponent;
let fixture: ComponentFixture<InputInterestsAdComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ InputInterestsAdComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(InputInterestsAdComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,121 +0,0 @@
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {COMMA, ENTER} from "@angular/cdk/keycodes";
import {FormControl} from "@angular/forms";
import {Observable} from "rxjs";
import {map, startWith} from "rxjs/operators";
import {MatChipInputEvent} from "@angular/material/chips";
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-input-interests-ad',
templateUrl: './input-interests-ad.component.html',
styleUrls: ['./input-interests-ad.component.scss']
})
export class InputInterestsAdComponent implements OnInit
{
selectable = true;
removable = true;
separatorKeysCodes: number[] = [ENTER, COMMA];
formControl = new FormControl();
filteredInterests: Observable<string[]>;
@Input() myInterests: string[] = [];
allInterests: string[] = [];
@Output() eventEmitter = new EventEmitter<string[]>();
@ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement>;
interestsNotSelected: string[] = [];
constructor( private messageService: MessageService ) {}
ngOnInit(): void
{
this.filteredInterests = this.formControl.valueChanges.pipe(
startWith(null),
map((fruit: string | null) => fruit ? this._filter(fruit) : this.interestsNotSelected.slice()));
this.messageService
.get("misc/getInterests")
.subscribe( retour => {
if(retour.status !== "success") {
console.log(retour);
}
else {
this.allInterests = [];
for(let elt of retour.data)
{
this.allInterests.push(elt.interest);
this.interestsNotSelected.push(elt.interest);
}
}
});
}
add(event: MatChipInputEvent): void
{
const value = (event.value || '').trim();
const index = this.interestsNotSelected.indexOf(value);
if (value && (index !== -1) && (!this.myInterests.includes(value)))
{
this.myInterests.push(value);
event.chipInput!.clear();
this.formControl.setValue(null);
this.eventEmitter.emit(this.myInterests);
this.interestsNotSelected.splice(index, 1);
}
}
remove(interest: string): void
{
// supprimer 'interest' de 'myInterest'
const index = this.myInterests.indexOf(interest);
if (index >= 0) this.myInterests.splice(index, 1);
this.eventEmitter.emit(this.myInterests);
// remmettre 'interest' dans 'interestsNotSelected'
if(!this.interestsNotSelected.includes(interest))
{
const indexOfAutres = this.interestsNotSelected.indexOf("Autres");
if(indexOfAutres !== -1)
{
this.interestsNotSelected.splice(indexOfAutres, 1);
if(interest !== "Autres") this.interestsNotSelected.push(interest);
this.interestsNotSelected.sort();
this.interestsNotSelected.push("Autres");
}
else {
this.interestsNotSelected.push(interest);
if(interest !== "Autres") this.interestsNotSelected.sort();
}
}
}
selected(event: MatAutocompleteSelectedEvent): void
{
const value = event.option.viewValue;
if(!this.myInterests.includes(value))
{
this.myInterests.push(value);
const index = this.interestsNotSelected.indexOf(value);
this.interestsNotSelected.splice(index, 1);
}
this.tagInput.nativeElement.value = '';
this.formControl.setValue(null);
this.eventEmitter.emit(this.myInterests);
}
private _filter(value: string): string[]
{
const filterValue = value.toLowerCase();
return this.interestsNotSelected.filter(fruit => fruit.toLowerCase().includes(filterValue));
}
}

View file

@ -1,185 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<app-navbar-advertiser></app-navbar-advertiser><br><br>
<!-- filtre + btnAddUser -->
<div class="row" style="margin: 20px 3% 20px 3%">
<!-- filtre -->
<div class="col-10" style="padding: 0px 0px 0px 0px;">
<div class="filtersContainer mat-elevation-z8">
<!-- titre -->
<div style="font-weight: bold; margin-bottom: 10px;">
Filtre
</div>
<mat-divider></mat-divider>
<!-- filtre textuelle-->
<div style="margin: 10px 0px 20px 2%;">
<input class="textFilter" (keyup)="applyFilter($event)" placeholder="filtre...">
</div>
<!-- role + actif + période -->
<div class="row myRow">
<!-- visible -->
<div class="col-2">
<mat-checkbox [(ngModel)]="visible" (change)="onFilter()">visible</mat-checkbox><br>
<mat-checkbox [(ngModel)]="noVisible" (change)="onFilter()">non visible</mat-checkbox>
</div>
<!-- sujets -->
<div class="col-4">
<mat-form-field appearance="fill">
<mat-label>Sujets</mat-label>
<mat-select [formControl]="formControlInterests" multiple>
<mat-select-trigger>
{{formControlInterests.value ? formControlInterests.value[0] : ''}}
<span *ngIf="formControlInterests.value?.length > 1">
(+{{formControlInterests.value.length - 1}} {{formControlInterests.value?.length === 2 ? 'autre' : 'autres'}})
</span>
</mat-select-trigger>
<mat-option *ngFor="let topping of allInterests" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
<button mat-icon-button (click)="onFilter()">
<mat-icon>keyboard_tab</mat-icon>
</button>
</div>
<!-- période -->
<div class="col-6" style="text-align: right;">
Période de création: &nbsp;
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>Date de début</mat-label>
<input matInput type="date"
style="font-size: small; width: 140px;"
[ngModel] ="startDate | date:'yyyy-MM-dd'"
(ngModelChange)="onNewStartDate($event); onFilter();">
</mat-form-field>
&nbsp; - &nbsp;
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>Date de fin</mat-label>
<input matInput type="date"
style="font-size: small; width: 140px;"
[ngModel] ="endDate | date:'yyyy-MM-dd'"
(ngModelChange)="onNewEndDate($event); onFilter();">
</mat-form-field>
</div>
</div>
</div>
</div>
<!-- btnAdd -->
<div class="col-2" style="text-align: right; position: relative;">
<button mat-button class="btnAjouter" (click)="onAdd()" style="position: absolute; bottom: 0; right: 0;">
<mat-icon>add_circle</mat-icon> Ajouter une annonce
</button>
</div>
</div>
<!-- Table -->
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- IsActive Column -->
<ng-container matColumnDef="isVisible">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
<mat-icon>power_settings_new</mat-icon>
</th>
<td mat-cell *matCellDef="let advert">
<mat-slide-toggle [(ngModel)]="advert.isVisible" (click)="onSliderIsVisible(advert)"></mat-slide-toggle>
</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Titre </th>
<td mat-cell *matCellDef="let advert">
{{advert.title}}
</td>
</ng-container>
<!-- Subject Column -->
<ng-container matColumnDef="interests">
<th mat-header-cell *matHeaderCellDef> Sujets </th>
<td mat-cell *matCellDef="let advert">
<span *ngFor="let interest of advert.interests; let isLast = last;">
<span *ngIf="!isLast"> {{interest}}, </span>
<span *ngIf="isLast"> {{interest}} </span>
</span>
</td>
</ng-container>
<!-- CreatedAt Column -->
<ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de création </th>
<td mat-cell *matCellDef="let advert">
{{ advert.createdAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</td>
</ng-container>
<!-- LastUpdate Column -->
<ng-container matColumnDef="updatedAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Dernière modification </th>
<td mat-cell *matCellDef="let advert">
{{ advert.updatedAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</td>
</ng-container>
<!-- Views Column -->
<ng-container matColumnDef="countViews">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Vues </th>
<td mat-cell *matCellDef="let advert">
{{advert.countViews}}
</td>
</ng-container>
<!-- Actions Column -->
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let advert">
<button mat-icon-button (click)="onVisualizeImages(advert)">
<mat-icon> insert_photo</mat-icon>
</button>
<button mat-icon-button (click)="onUpdate(advert)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="onDelete(advert)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<!-- Directives -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4"> Aucune vidéo ne correspond au filtre: "{{input.value}}" </td>
</tr>
</table>
<div style="width: 94%; margin: auto auto">
<mat-paginator [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons aria-label="Select page of periodic elements"></mat-paginator>
</div>
<br><br>
</div>
</div>

View file

@ -1,87 +0,0 @@
.myContainer {
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
font-size: small;
}
// ----------------------------------------------------------
.filtersContainer {
width: 95%;
background-color: white;
padding: 10px 10px 10px 10px;
}
.myRow {
margin-left: 1%;
}
.textFilter {
width: 50%;
font-size: medium;
border-radius: 5px;
}
.btnAjouter {
background-color: white;
border: solid 1px black;
}
// ----------------------------------------------------------
table {
margin: 0 auto;
width: 94%;
font-size: small;
}
.darkTheme table { border: solid 2px white; }
th.mat-sort-header-sorted {
color: black;
}
td {
font-size: small;
}
input {
width: 30%;
font-size: large;
border-radius: 5px;
}
// --------------------------------------------------------------------
// rong gauche
::ng-deep .mat-slide-toggle-thumb {
background-color: white !important;
}
// trait droite
::ng-deep .mat-slide-toggle-bar {
background-color: gray !important;
}
// rond droite
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
background-color: white !important;
}
// trait gauche
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
background-color: cornflowerblue !important;
}
// -------------------------------------------------------------------------
::ng-deep .mat-pseudo-checkbox-checked {
background-color: black !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageAdListAdvertiserComponent } from './page-ad-list-advertiser.component';
describe('PageAdvertiserComponent', () => {
let component: PageAdListAdvertiserComponent;
let fixture: ComponentFixture<PageAdListAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageAdListAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageAdListAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,309 +0,0 @@
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import {MatSort} from "@angular/material/sort";
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MatTableDataSource} from "@angular/material/table";
import {AdvertWithCountViews} from "../../../utils/interfaces/advert";
import {MatDialog} from "@angular/material/dialog";
import {PopupAddOrUpdateAdComponent} from "../popup-add-or-update-ad/popup-add-or-update-ad.component";
import {MatSnackBar} from "@angular/material/snack-bar";
import {PopupDeleteAdAdvertiserComponent} from "../popup-delete-ad-advertiser/popup-delete-ad-advertiser.component";
import {MatPaginator} from "@angular/material/paginator";
import {PopupVisualizeImagesAdvertiserComponent} from "../popup-visualize-images-advertiser/popup-visualize-images-advertiser.component";
import {FictitiousAdvertsService} from "../../../utils/services/fictitiousDatas/fictitiousAdverts/fictitious-adverts.service";
import {FormControl} from "@angular/forms";
import {FictitiousUtilsService} from "../../../utils/services/fictitiousDatas/fictitiousUtils/fictitious-utils.service";
import {MessageService} from "../../../utils/services/message/message.service";
import {HttpParams} from "@angular/common/http";
@Component({
selector: 'app-page-ad-list-advertiser',
templateUrl: './page-ad-list-advertiser.component.html',
styleUrls: ['./page-ad-list-advertiser.component.scss']
})
export class PageAdListAdvertiserComponent implements AfterViewInit
{
displayedColumns: string[] = [ 'isVisible', 'title', 'interests', 'createdAt', 'updatedAt', 'countViews', 'actions' ];
tabAdvertWithCountViews: AdvertWithCountViews[] = [];
dataSource;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
visible: boolean = true;
noVisible: boolean = true;
startDate: Date = null;
endDate: Date = null;
formControlInterests = new FormControl();
allVideoCategorie = [];
allInterests: string[] = [];
constructor( public themeService: ThemeService,
private fictitiousAdvertsService: FictitiousAdvertsService,
private fictitiousUtilsService: FictitiousUtilsService,
public dialog: MatDialog,
private snackBar: MatSnackBar,
private messageService: MessageService ) { }
ngAfterViewInit(): void
{
// Ask interests
this.messageService
.get("misc/getInterests")
.subscribe(ret => this.afterReceivingInterests(ret), err => this.afterReceivingInterests(err) );
// Ask ads
let params = new HttpParams();
params = params.append("isActive", true);
this.messageService
.get("ad/findAll", params)
.subscribe(ret => this.afterReceivingAds(ret), err => this.afterReceivingAds(err));
}
afterReceivingInterests(retour: any): void
{
if(retour.status !== "success") {
console.log("afterReceivingInterests");
console.log(retour);
}
else {
this.allVideoCategorie = retour.data;
this.allInterests = retour.data.map(x => x.interest);
this.allInterests.sort();
}
}
afterReceivingAds(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
if(retour.data.length !== 0)
{
for(let advert of retour.data) this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViews(advert));
this.dataSource = new MatTableDataSource<AdvertWithCountViews>();
this.onFilter();
}
}
}
applyFilter(event: Event): void
{
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
}
onVisualizeImages(advert: AdvertWithCountViews)
{
if(advert.images.length !== 0)
{
const config = {
width: '30%',
height: '90%',
data: { images: advert.images }
};
this.dialog
.open(PopupVisualizeImagesAdvertiserComponent, config)
.afterClosed()
.subscribe(retour => {});
}
else {
const config = { duration: 2000, panelClass: "custom-class" };
const message = "Cette annonce ne contient aucune image" ;
this.snackBar.open( message, "", config);
}
}
onAdd(): void
{
const config = {
width: '75%',
//height: '80%',
panelClass: 'custom-dialog-container',
data: {
action: "add",
advert: null,
allVideoCategorie: this.allVideoCategorie,
allTitle: this.tabAdvertWithCountViews.map(x => x.title)
}
};
this.dialog
.open(PopupAddOrUpdateAdComponent, config)
.afterClosed()
.subscribe( advertAdded => {
const config = { duration: 1000, panelClass: "custom-class" };
let message = "" ;
if((advertAdded === undefined) || (advertAdded === null)) {
message = "Opération annulée" ;
}
else {
this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViews(advertAdded));
this.onFilter();
message = "L'annonce a bien été ajoutée ✔" ;
}
this.snackBar.open( message, "", config);
});
}
onUpdate(advertToUpdate: AdvertWithCountViews): void
{
const config = {
width: '75%',
//height: '80%',
panelClass: 'custom-dialog-container',
data: {
action: "update",
advert: advertToUpdate,
allVideoCategorie: this.allVideoCategorie,
allTitle: this.tabAdvertWithCountViews.map(x => x.title)
}
};
this.dialog
.open(PopupAddOrUpdateAdComponent, config)
.afterClosed()
.subscribe( advertUpdated => {
const config = { duration: 1000, panelClass: "custom-class" };
let message = "" ;
if((advertUpdated === undefined) || (advertUpdated === null)) {
message = "Opération annulée" ;
}
else {
const index = this.tabAdvertWithCountViews.findIndex(elt => (elt.id === advertToUpdate.id));
this.tabAdvertWithCountViews.splice(index, 1, this.advertToAdvertWithCountViews(advertUpdated));
this.onFilter();
message = "L'annonce a bien été modifiée ✔" ;
}
this.snackBar.open( message, "", config);
});
}
onDelete(advert: AdvertWithCountViews): void
{
const config = {
data: { advert: advert }
};
this.dialog
.open(PopupDeleteAdAdvertiserComponent, config)
.afterClosed()
.subscribe( retour => {
const config = { duration: 1000, panelClass: "custom-class" };
let message = "" ;
if((retour === undefined) || (retour === null)) {
message = "Opération annulée" ;
}
else {
const index = this.dataSource.data.findIndex( elt => (elt.id === advert.id));
this.dataSource.data.splice(index, 1);
this.dataSource.data = this.dataSource.data;
this.dataSource = this.dataSource;
message = advert.title + " a bien été supprimée ✔" ;
}
this.snackBar.open( message, "", config);
});
}
onFilter(): void
{
if(this.dataSource === null || this.dataSource === undefined) this.dataSource = new MatTableDataSource();
this.dataSource.data = [];
for(let advert of this.tabAdvertWithCountViews)
{
let valide: boolean = true;
if(advert.isVisible && this.visible) valide = true;
else if((!advert.isVisible) && this.noVisible) valide = true;
else valide = false;
if(valide)
{
if ((advert.createdAt === null) && (this.startDate !== null)) valide = false;
else if ((advert.createdAt === null) && (this.endDate !== null)) valide = false;
else if (this.startDate !== null)
{
if(this.startDate.getTime() > advert.createdAt.getTime()) valide = false;
else if (this.endDate !== null)
{
if(this.endDate.getTime() < advert.createdAt.getTime()) valide = false;
}
}
}
if(valide) {
if(this.formControlInterests.value !== null) {
for (let interest of this.formControlInterests.value) {
if (advert.interests.indexOf(interest) === -1) {
valide = false;
break;
}
}
}
}
if(valide) this.dataSource.data.push(advert);
}
this.dataSource = new MatTableDataSource(this.dataSource.data);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
}
onNewStartDate(event): void {
this.startDate = new Date(event);
}
onNewEndDate(event): void {
this.endDate = new Date(event);
}
onSliderIsVisible(advert: any): void
{
// il faut envoyer la négation de user.isActive
this.messageService
.put("ad/update/"+advert.id, { isVisible: !advert.isVisible })
.subscribe(
ret => {},
err => {
console.log("onSliderIsVisible");
console.log(err);
}
);
}
advertToAdvertWithCountViews(advert): AdvertWithCountViews
{
return {
id: advert.id,
userId: advert.userId,
title: advert.title,
url: advert.url,
images: advert.images,
interests: advert.interests.map(x => x.interest),
comment: advert.comment,
views: advert.views,
countViews: advert.views.length,
isVisible: advert.isVisible,
isActive: advert.isActive,
createdAt: advert.createdAt,
updatedAt: advert.updatedAt,
}
}
}

View file

@ -1,83 +0,0 @@
<div class="myContainer1">
<div class="myContainer2">
<!-- titre popup -->
<h1 mat-dialog-title>{{title}}</h1>
<mat-divider></mat-divider><br>
<!-- tous les champs -->
<div class="row">
<!-- title + interests + comments + isVisible -->
<div class="col-6">
<!-- Title -->
<mat-form-field class="titleContainer" appearance="fill">
<mat-label> Titre annonce </mat-label>
<input matInput type="text" [(ngModel)]="advert.title" required>
</mat-form-field>
<!-- Interests -->
<app-input-interests-ad [myInterests]="advert.interests" (eventEmitter)="onEventInputTags($event)"></app-input-interests-ad>
<!-- Comments -->
<mat-form-field class="commentContainer" appearance="fill">
<mat-label> Commentaire </mat-label>
<textarea matInput [(ngModel)]="advert.comment" rows="5" style="resize: none;"></textarea>
</mat-form-field><br>
<!-- url -->
<mat-form-field class="commentContainer" appearance="fill">
<mat-label> URL </mat-label>
<input matInput [(ngModel)]="advert.url">
</mat-form-field><br>
<!-- IsVisible -->
<mat-checkbox [(ngModel)]="advert.isVisible"> Visible </mat-checkbox><br><br>
<!-- Images déjà présentes -->
<div *ngIf="advert.images.length !== 0">
<div style="font-weight: bold; margin-bottom: 5px;">
Images déjà associées:
</div>
<div style="margin-left: 20px; padding-left: 2px; border-left: solid 1px #a4a4a4">
<div *ngFor="let image of advert.images" style="padding: 2px 0px 2px 0px;">
<mat-chip [selectable]="true" [removable]="true" style="font-size: small;">
{{image.description}}
<button matChipRemove (click)="onRemoveImgAlreadyPresent(image)">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
</div>
</div>
</div>
</div>
<!-- nouvelles images -->
<div class="col-6" style="overflow-x: hidden; overflow-y: scroll; max-height: 70vh;">
<app-drag-and-drop (eventEmitter)="onReceiveNewImages($event)"></app-drag-and-drop>
</div>
</div>
<br><mat-divider></mat-divider>
<!-- message d'erreur -->
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
<span class="mat-error">{{errorMessage}}</span>
</div>
<!-- Actions -->
<mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close()">Annuler</button>
<button mat-button (click)="onValidate()">Valider</button>
</mat-dialog-actions>
</div>
</div>

View file

@ -1,90 +0,0 @@
.myContainer1 {
padding: 10px 10px 0px 25px;
margin: 0px 0px 0px 0px;
font-size: small;
}
.myContainer2 {
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 0px;
overflow-y: hidden;
overflow-x: hidden;
-ms-overflow-style: none;
scrollbar-width: none;
}
.myContainer2::-webkit-scrollbar {
display: none;
}
h1 {
text-align: center;
font-size: large;
}
.col-6, .col-8 {
border-left: solid 1px #a4a4a4;
}
// -------------------------------------------------------------------------
.titleContainer {
width: 100%;
}
.commentContainer {
width: 100%;
}
.imageContainer {
border: solid 1px grey;
}
mat-dialog-actions {
margin-bottom: 0px;
}
button {
font-size: small;
}
// -------------------------------------------------------------------------
// --- LightTheme ---
// aura
.lightTheme ::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
.lightTheme ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
.lightTheme ::ng-deep .mat-checkbox .mat-checkbox-frame {
border-color: black !important;
background-color: white !important;
}
// --- DarkTheme ---
// aura
.darTheme ::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
.darkTheme ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
.darkTheme ::ng-deep .mat-checkbox .mat-checkbox-frame {
border-color: white !important;
//background-color: white !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupAddOrUpdateAdComponent } from './popup-add-or-update-ad.component';
describe('PopupAddOrUpdateAdComponent', () => {
let component: PopupAddOrUpdateAdComponent;
let fixture: ComponentFixture<PopupAddOrUpdateAdComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupAddOrUpdateAdComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupAddOrUpdateAdComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,221 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {Advert} from "../../../utils/interfaces/advert";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
import {ThemeService} from "../../../utils/services/theme/theme.service";
const ADVERT_VIDE: Advert = {
_id: "",
userId: "",
title: "",
url: "",
images: [],
interests: [],
comment: "",
views: [],
isVisible: true,
isActive: true,
createdAt: new Date(),
updatedAt: new Date(),
}
@Component({
selector: 'app-popup-add-or-update-ad',
templateUrl: './popup-add-or-update-ad.component.html',
styleUrls: ['./popup-add-or-update-ad.component.scss']
})
export class PopupAddOrUpdateAdComponent implements OnInit
{
advert: any;
title: string = "" ;
allVideoCategorie = [];
allTitle = [];
tabOfNewImagesBase64 = [];
tabOfNewImagesName = [];
hasError: boolean = false;
errorMessage: string = "" ;
constructor( public dialogRef: MatDialogRef<PopupAddOrUpdateAdComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService,
public themeService: ThemeService ) { }
ngOnInit(): void
{
this.allVideoCategorie = this.data.allVideoCategorie;
this.allTitle = this.data.allTitle.slice();
if(this.data.action === "add")
{
this.advert = Object.assign({}, ADVERT_VIDE);
this.advert.images = [];
this.advert.interests = [];
this.title = "Ajouter annonce" ;
}
else
{
this.advert = Object.assign({}, this.data.advert);
this.advert.interests = this.data.advert.interests.slice();
this.title = "Modifier annonce" ;
const indexOldTitle = this.allTitle.findIndex(title => title == this.advert.title);
this.allTitle.splice(indexOldTitle, 1);
}
}
onValidate(): void
{
this.checkField();
if(!this.hasError)
{
// preparation des donnees
this.prepareAdvertInterests();
this.prepareAdvertImages();
// si creation
if (this.data.action === "add")
{
this.messageService
.post("ad/create", this.advert)
.subscribe(ret => this.onCreateCallback(ret), err => this.onCreateCallback(err));
}
// si update
else
{
const id = this.advert.id;
Reflect.deleteProperty(this.advert, "id");
Reflect.deleteProperty(this.advert, "_id");
this.messageService
.put("ad/update/" + id, this.advert)
.subscribe(ret => this.onUpdateCallback(ret, id), err => this.onUpdateCallback(err, id));
}
}
}
checkField()
{
if(this.advert.title.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'titre'." ;
this.hasError = true;
}
else if(this.allTitle.includes(this.advert.title)) {
this.errorMessage = "Ce titre est déjà pris." ;
this.hasError = true;
}
else if((this.advert.images.length === 0) && (this.tabOfNewImagesName.length === 0)) {
this.errorMessage = "Veuillez uploader au moins une image." ;
this.hasError = true;
}
else {
this.errorMessage = "";
this.hasError = false;
}
}
onCreateCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
this.dialogRef.close();
}
else {
this.dialogRef.close(retour.data);
}
}
onUpdateCallback(retour: any, id: string): void
{
if(retour.status !== "success") {
console.log(retour);
this.dialogRef.close();
}
else {
this.advert.id = id;
this.dialogRef.close(this.advert);
}
}
onEventInputTags(myTags: string[]): void
{
this.advert.interests = myTags;
}
onRemoveImgAlreadyPresent(image)
{
const index = this.advert.images.indexOf(image);
this.advert.images.splice(index, 1);
}
onReceiveNewImages(files: any): void
{
this.tabOfNewImagesBase64 = [];
this.tabOfNewImagesName = [];
if(files)
{
for(let file of files)
{
if(file)
{
const reader = new FileReader();
reader.onload = this.handleReaderLoaded.bind(this);
this.tabOfNewImagesName.push(file.name)
reader.readAsBinaryString(file);
}
}
}
}
handleReaderLoaded(e)
{
this.tabOfNewImagesBase64.push('data:image/png;base64,' + btoa(e.target.result))
}
// Met bien en forme les "images" avant d'être envoyer
prepareAdvertImages(): void
{
for(let i=0; i<this.tabOfNewImagesName.length ; i++)
{
let newImagePrepared = {
base64: this.tabOfNewImagesBase64[i],
url: "",
description: this.tabOfNewImagesName[i],
type: 0,
};
this.advert.images.push(newImagePrepared);
}
}
// Met bien en forme les "interests" avant d'être envoyer
prepareAdvertInterests(): void
{
let interests = [];
for (let interest of this.advert.interests) {
for (let videoCategorie of this.allVideoCategorie) {
if (videoCategorie.interest === interest) {
interests.push(videoCategorie);
break;
}
}
}
this.advert.interests = interests;
}
}

View file

@ -1,8 +0,0 @@
<mat-dialog-content class="mat-typography">
Êtes-vous sûr de vouloir supprimer l'annonce <i>{{advert.title}}</i> ?
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close();">Annuler</button>
<button mat-button (click)="onValidate()" cdkFocusInitial>Valider</button>
</mat-dialog-actions>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupDeleteAdAdvertiserComponent } from './popup-delete-ad-advertiser.component';
describe('PopupDeleteAdComponent', () => {
let component: PopupDeleteAdAdvertiserComponent;
let fixture: ComponentFixture<PopupDeleteAdAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupDeleteAdAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupDeleteAdAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,47 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-popup-delete-ad-advertiser',
templateUrl: './popup-delete-ad-advertiser.component.html',
styleUrls: ['./popup-delete-ad-advertiser.component.scss']
})
export class PopupDeleteAdAdvertiserComponent implements OnInit
{
advert: any;
constructor( public dialogRef: MatDialogRef<PopupDeleteAdAdvertiserComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService) { }
ngOnInit(): void
{
this.advert = this.data.advert;
}
onValidate(): void
{
this.messageService
.delete("ad/delete/"+this.advert.id)
.subscribe(ret => this.onValidateCallback(ret), err => this.onValidateCallback(err));
}
onValidateCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
this.dialogRef.close();
}
else {
this.dialogRef.close(true);
}
}
}

View file

@ -1,71 +0,0 @@
<div [class]="themeService.getClassTheme()">
<h1 mat-dialog-title>{{advert.title}}</h1>
<!-- ----------------------------------------------------------------------------------------------------------------- -->
<mat-divider></mat-divider>
<mat-dialog-content>
<!-- Images -->
<div class="row myRow">
<div class="col-6 myLabel"> Images: </div>
<div class="col-6 myValue" style="border-left: solid 1px #e6e6e6">
<div *ngFor="let image of advert.images"> {{image.url}} </div>
</div>
</div>
<!-- Tags -->
<div class="row myRow">
<div class="col-6 myLabel"> Centre d'intérêt :</div>
<div class="col-6 myValue" style="border-left: solid 1px #e6e6e6">
<div *ngFor="let tag of advert.interests"> • {{tag}} </div>
</div>
</div>
<!-- Comment -->
<div class="row myRow">
<div class="col-6 myLabel"> Commentaire: </div>
<div class="col-6 myValue"> {{advert.comment}} </div>
</div>
<!-- Views -->
<div class="row myRow">
<label class="col-6 myLabel"> Vues: </label>
<div class="col-6 myValue"> {{advert.views}} </div>
</div>
<!-- Created at -->
<div class="row myRow">
<label class="col-6 myLabel"> Date de création: </label>
<div class="col-6 myValue">
{{ advert.createdAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</div>
</div>
<!-- Last updtade -->
<div class="row myRow">
<label class="col-6 myLabel"> Date de dernière modification: </label>
<div class="col-6 myValue">
{{ advert.updatedAt | date:'dd/LL/YYYY à HH:mm:ss' }}
</div>
</div>
<!-- IsVisible -->
<div class="row myRow">
<label class="col-6 myLabel"> Visibilité: </label>
<div class="col-6 myValue">
<mat-icon *ngIf="advert.isVisible">checked</mat-icon>
<mat-icon *ngIf="!advert.isVisible">close</mat-icon>
</div>
</div>
</mat-dialog-content>
<!-- ----------------------------------------------------------------------------------------------------------------- -->
<mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close()">Fermer</button>
</mat-dialog-actions>
</div>

View file

@ -1,28 +0,0 @@
.lightTheme, .darkTheme {
background-image: none;
}
h1 {
text-align: center;
font-size: xx-large;
}
.myRow {
margin: 15px 0px 15px 0px;
}
.myLabel {
text-align: right;
padding: 0px 5px 0px 0px;
margin: 0px;
font-weight: bold;
}
.myValue {
text-align: left;
padding: 0px 0px 0px 5px;
margin: 0px;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupVisualizeAdAdvertiserComponent } from './popup-visualize-ad-advertiser.component';
describe('PopupVisualizeAdComponent', () => {
let component: PopupVisualizeAdAdvertiserComponent;
let fixture: ComponentFixture<PopupVisualizeAdAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupVisualizeAdAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupVisualizeAdAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,27 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
import {Advert} from "../../../utils/interfaces/advert";
@Component({
selector: 'app-popup-visualize-ad-advertiser',
templateUrl: './popup-visualize-ad-advertiser.component.html',
styleUrls: ['./popup-visualize-ad-advertiser.component.scss']
})
export class PopupVisualizeAdAdvertiserComponent implements OnInit
{
advert: Advert;
constructor( public dialogRef: MatDialogRef<PopupVisualizeAdAdvertiserComponent>,
@Inject(MAT_DIALOG_DATA) public data,
public themeService: ThemeService,
public dialog: MatDialog ) { }
ngOnInit(): void
{
this.advert = this.data.advert;
}
}

View file

@ -1,20 +0,0 @@
<div mat-dialog-title class="dialog-title">
<h2></h2>
<button mat-icon-button aria-label="close dialog" mat-dialog-close>
<mat-icon>close</mat-icon>
</button>
</div>
<mat-grid-list cols="12" rowHeight="500">
<mat-grid-tile colspan="1" rowspan="1" (click)="onPrecedent()">
<button> < </button>
</mat-grid-tile>
<mat-grid-tile colspan="10" rowspan="1">
<img [src]="tabImages[index].base64" [alt]="tabImages[index].description">
</mat-grid-tile>
<mat-grid-tile colspan="1" rowspan="1" (click)="onSuivant()">
<button> > </button>
</mat-grid-tile>
</mat-grid-list>

View file

@ -1,14 +0,0 @@
carousel {
width: 100%;
margin: 0 auto;
text-align: center;
justify-content: center
}
.dialog-title {
display: flex;
justify-content: space-between;
align-items: center;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupVisualizeImagesAdvertiserComponent } from './popup-visualize-images-advertiser.component';
describe('PopupVisualizeImagesComponent', () => {
let component: PopupVisualizeImagesAdvertiserComponent;
let fixture: ComponentFixture<PopupVisualizeImagesAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupVisualizeImagesAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupVisualizeImagesAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,38 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
@Component({
selector: 'app-popup-visualize-images-advertiser',
templateUrl: './popup-visualize-images-advertiser.component.html',
styleUrls: ['./popup-visualize-images-advertiser.component.scss']
})
export class PopupVisualizeImagesAdvertiserComponent implements OnInit
{
tabImages = [];
index: number = 0;
nbImage: number = 0;
constructor( public dialogRef: MatDialogRef<PopupVisualizeImagesAdvertiserComponent>,
@Inject(MAT_DIALOG_DATA) public data ) { }
ngOnInit(): void
{
this.tabImages = this.data.images;
this.nbImage = this.tabImages.length;
}
onPrecedent(): void
{
if(this.index !== 0) this.index -= 1;
}
onSuivant(): void
{
if(this.index !== (this.nbImage-1)) this.index += 1;
}
}

View file

@ -1,49 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- NavBar -->
<app-navbar-advertiser></app-navbar-advertiser>
<!-- Boite -->
<div class="boite">
<!-- Photo de profil -->
<div style="text-align: center">
<img [src]="advertiser.profileImageUrl"
onerror="this.onerror=null; this.src='assets/profil.png'">
</div>
<!-- entreprise -->
<div class="row myRow">
<div class="col-6 myLabel">Entreprise:</div>
<div class="col-6 myValue"> {{advertiser.company}} </div>
</div>
<!-- login -->
<div class="row myRow">
<div class="col-6 myLabel">Pseudo:</div>
<div class="col-6 myValue"> {{advertiser.login}} </div>
</div>
<!-- email -->
<div class="row myRow">
<div class="col-6 myLabel">Mail:</div>
<div class="col-6 myValue"> {{advertiser.email}} </div>
</div>
<!-- createdAt -->
<div class="row myRow">
<div class="col-6 myLabel">Date de création:</div>
<div class="col-6 myValue">{{advertiser.createdAt | date:'dd/LL/YYYY'}}</div>
</div>
<!-- Modifier profil -->
<div class="btnContainer">
<button mat-button class="myBtn" (click)="onModifier()">Modifier profil</button>
</div>
</div>
</div>
</div>

View file

@ -1,61 +0,0 @@
.myContainer {
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
}
.boite {
margin-left: auto;
margin-right: auto;
width: 25%;
margin-top: 10vh;
border: solid 3px;
border-radius: 10px;
padding: 20px 40px 20px 40px;
background-color: #ffffff;
text-align: center;
box-shadow: 10px 5px 5px black;
}
.lightTheme .boite {
border-color: black;
}
.darkTheme .boite {
border-color: white;
}
img {
margin: 0px 0px 10px 0px;
width: 5vw;
height: 5vw;
border: solid 2px black;
border-radius: 50%;
font-size: xxx-large;
}
.myRow {
margin: 15px 0px 15px 0px;
}
.myLabel {
text-align: right;
padding: 0px 5px 0px 0px;
margin: 0px;
font-weight: bold;
}
.myValue {
text-align: left;
padding: 0px 0px 0px 5px;
margin: 0px;
}
.btnContainer {
text-align: center;
margin-top: 40px;
}
.myBtn {
border: solid 1px black;
background-color: white;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageProfilAdvertiserComponent } from './page-profil-advertiser.component';
describe('PageProfilAdvertiserComponent', () => {
let component: PageProfilAdvertiserComponent;
let fixture: ComponentFixture<PageProfilAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageProfilAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageProfilAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,90 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {User} from "../../../utils/interfaces/user";
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MatDialog} from "@angular/material/dialog";
import {MatSnackBar} from "@angular/material/snack-bar";
import {PopupUpdateAdvertiserComponent} from "../popup-update-advertiser/popup-update-advertiser.component";
import {MessageService} from "../../../utils/services/message/message.service";
import {ProfilService} from "../../../utils/services/profil/profil.service";
@Component({
selector: 'app-page-profil-advertiser',
templateUrl: './page-profil-advertiser.component.html',
styleUrls: ['./page-profil-advertiser.component.scss']
})
export class PageProfilAdvertiserComponent implements OnInit
{
advertiser: User = {
_id: "",
login: "",
hashPass: "",
email: "",
role: {
name: "advertiser",
permission: 5,
isAccepted: true,
},
profileImageUrl: "",
dateOfBirth: null,
gender: "man",
interests: [],
company: "",
isActive: true,
createdAt: new Date(),
updatedAt: new Date(),
lastConnexion: null
};
constructor( public themeService: ThemeService,
public dialog: MatDialog,
private snackBar: MatSnackBar,
private messageService: MessageService,
private profilService: ProfilService ) { }
ngOnInit(): void
{
this.messageService
.get( "user/findOne/"+this.profilService.getId())
.subscribe( retour => this.ngOnInitCallback(retour), err => this.ngOnInitCallback(err) )
}
ngOnInitCallback(retour: any)
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.advertiser = retour.data;
}
}
onModifier()
{
const config = {
width: '25%',
data: { advertiser: this.advertiser }
};
this.dialog
.open(PopupUpdateAdvertiserComponent, config)
.afterClosed()
.subscribe(retour => {
if((retour === null) || (retour === undefined))
{
const config = { duration: 1000, panelClass: "custom-class" };
this.snackBar.open( "Opération annulé", "", config);
}
else
{
this.advertiser = retour;
}
});
}
}

View file

@ -1,65 +0,0 @@
<div class="myContainer">
<div class="boite">
<!-- photo de profil -->
<div style="text-align: center">
<img [src]="advertiserCopy.profileImageUrl" onerror="this.onerror=null; this.src='assets/profil.png'"><br>
<input title="lien vers image" type="text" [(ngModel)]="advertiserCopy.profileImageUrl" style="width: 90%">
</div>
<!-- divider -->
<br><mat-divider></mat-divider><br>
<!-- entreprise -->
<mat-form-field appearance="fill">
<mat-label>Entreprise</mat-label>
<input matInput type="text" [(ngModel)]="advertiserCopy.company">
</mat-form-field><br>
<!-- login -->
<mat-form-field appearance="fill">
<mat-label>Pseudo</mat-label>
<input matInput type="text" [(ngModel)]="advertiserCopy.login">
</mat-form-field><br>
<!-- divider -->
<mat-divider></mat-divider><br>
<!-- Modifier mot de passe -->
<div>
Modifier mot de passe:
<mat-checkbox [(ngModel)]="changePassword"></mat-checkbox>
</div>
<!-- nouveau mot de passe -->
<div *ngIf="changePassword" style="margin-top: 10px">
<!-- Nouveau mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Nouveau mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="newPassword">
</mat-form-field>
<br>
<!-- Confirmation nouveau mot de passe -->
<mat-form-field appearance="fill">
<mat-label>Confirmation nouveau mot de passe</mat-label>
<input matInput type="password" [(ngModel)]="confirmNewPassword">
</mat-form-field>
</div>
<div *ngIf="!changePassword"><br></div>
<!-- divider -->
<mat-divider></mat-divider><br>
<!-- message d'erreur -->
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
<span class="mat-error">{{errorMessage}}</span>
</div>
<!-- boutons -->
<div style="width: 100%; text-align: right">
<button mat-button (click)="this.dialogRef.close(null)"> Annuler </button>
<button mat-button (click)="onValider()"> Enregistrer </button>
</div>
</div>
</div>

View file

@ -1,33 +0,0 @@
.boite {
font-size: small;
}
button {
font-size: small;
}
img {
margin: 0px 0px 10px 0px;
width: 5vw;
height: 5vw;
border: solid 2px black;
border-radius: 50%;
font-size: xxx-large;
}
// -------------------------------------------------------------------------
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
background-color: white !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupUpdateAdvertiserComponent } from './popup-update-advertiser.component';
describe('PopupUpdateAdvertiserComponent', () => {
let component: PopupUpdateAdvertiserComponent;
let fixture: ComponentFixture<PopupUpdateAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupUpdateAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupUpdateAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,125 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {User} from "../../../utils/interfaces/user";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../../utils/services/message/message.service";
import {ProfilService} from "../../../utils/services/profil/profil.service";
@Component({
selector: 'app-popup-update-advertiser',
templateUrl: './popup-update-advertiser.component.html',
styleUrls: ['./popup-update-advertiser.component.scss']
})
export class PopupUpdateAdvertiserComponent implements OnInit
{
advertiserCopy: User;
newPassword: string = "";
confirmNewPassword: string = "" ;
changePassword: boolean = false ;
hasError: boolean = false;
errorMessage: string = "" ;
constructor( public dialogRef: MatDialogRef<PopupUpdateAdvertiserComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService,
private profilService: ProfilService ) { }
ngOnInit(): void
{
const advertiser0 = this.data.advertiser;
this.advertiserCopy = {
_id: advertiser0._id,
login: advertiser0.login,
hashPass: advertiser0.hashPass,
email: advertiser0.email,
role: {
name: advertiser0.role.name,
permission: advertiser0.role.permission,
isAccepted: advertiser0.role.isAccepted,
},
profileImageUrl: advertiser0.profileImageUrl,
dateOfBirth: advertiser0.dateOfBirth,
gender: advertiser0.gender,
interests: [],
company: advertiser0.company,
isActive: advertiser0.isActive,
createdAt: advertiser0.createdAt,
updatedAt: advertiser0.updatedAt,
lastConnexion: new Date()
};
for(let interest of advertiser0.interests) this.advertiserCopy.interests.push(interest);
}
onValider()
{
this.checkField();
if(!this.hasError)
{
if(this.changePassword) this.advertiserCopy.hashPass = this.newPassword;
const data = {
login: this.advertiserCopy.login,
hashPass: this.advertiserCopy.hashPass,
email: this.advertiserCopy.email,
profileImageUrl: this.advertiserCopy.profileImageUrl,
company: this.advertiserCopy.company
};
this.messageService
.put("user/update/"+this.profilService.getId(), data)
.subscribe( ret => this.onValiderCallback(ret), err => this.onValiderCallback(err) );
}
}
onValiderCallback(retour: any)
{
if(retour.status !== "success") {
console.log(retour);
this.dialogRef.close(null);
}
else {
this.profilService.setProfileImageUrl(this.advertiserCopy.profileImageUrl);
this.dialogRef.close(this.advertiserCopy);
}
}
checkField()
{
if(this.advertiserCopy.login.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'pseudo'" ;
this.hasError = true;
}
else if(this.advertiserCopy.email.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'email'" ;
this.hasError = true;
}
else if(!this.isValidEmail(this.advertiserCopy.email)) {
this.errorMessage = "Email invalide" ;
this.hasError = true;
}
else if((this.changePassword) && (this.newPassword.length === 0)) {
this.errorMessage = "Veuillez remplir le champ 'mot de passe'" ;
this.hasError = true;
}
else if((this.changePassword) && (this.newPassword !== this.confirmNewPassword)) {
this.errorMessage = "Le mot de passe est différent de sa confirmation" ;
this.hasError = true;
}
else {
this.errorMessage = "" ;
this.hasError = false;
}
}
isValidEmail(email)
{
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
}

View file

@ -1,94 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<app-navbar-advertiser></app-navbar-advertiser>
<!-- Filter -->
<div class="filtersContainer mat-elevation-z8">
<div style="font-weight: bold;">Filtre</div>
<mat-divider></mat-divider><br>
<div *ngIf="true; then colPeriode"></div>
<br><mat-divider style="width: 60%"></mat-divider><br>
<div style="text-align: right; font-size: small;">
<button mat-button (click)="onApplyFilter()" style="font-size: small">Appliquer</button>
</div>
</div>
<!-- chart -->
<div *ngIf="isDisplayable" class="chartContainer">
<canvas baseChart
[datasets]="lineChartData"
[labels]="lineChartLabels"
[options]="chartOptions"
[colors]="[]"
[legend]="true"
[chartType]="'line'">
</canvas>
</div>
</div>
</div>
<!-- ------------------------------------------------------------------------------------------------------------------- -->
<ng-template #colPeriode>
<!-- startDate -->
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>début</mat-label>
<input matInput type="date" [ngModel] ="startDate | date:'yyyy-MM-dd'" (ngModelChange)="onNewStartDate($event);">
</mat-form-field>
&nbsp; - &nbsp;
<!-- endDate -->
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>fin</mat-label>
<input matInput type="date" [ngModel] ="endDate | date:'yyyy-MM-dd'" (ngModelChange)="onNewEndDate($event);">
</mat-form-field>
&nbsp; - &nbsp;
<!-- step -->
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>pas d'affichage</mat-label>
<input matInput type="number" [(ngModel)] =step>
</mat-form-field>
&nbsp; - &nbsp;
<!-- step unity -->
<mat-form-field appearance="fill">
<mat-label>unité du pas d'affichage</mat-label>
<mat-select [(ngModel)]="stepUnity">
<mat-option value="jour">jour</mat-option>
<mat-option value="semaine">semaine</mat-option>
<mat-option value="mois">mois</mat-option>
</mat-select>
</mat-form-field><br>
<!-- ads -->
<mat-select [formControl]="formControl" multiple style="padding-top: 10px; width: 60%;">
<mat-select-trigger>
<span *ngIf="formControl.value?.length > 0">
<span *ngFor="let coupleNameViews of formControl.value"> {{coupleNameViews.name}}, </span>
</span>
</mat-select-trigger>
<mat-option *ngFor="let coupleNameViews of allCoupleNameViews" [value]="coupleNameViews">{{coupleNameViews.name}}</mat-option>
</mat-select>
<button mat-button class="btnToutSelectionner" (click)="onSelectAll()">Tout sélectionner</button>
<button mat-button class="btnToutDeselectionner" (click)="onDeSelectAll()">Tout désélectionner</button>
</ng-template>

View file

@ -1,53 +0,0 @@
.myContainer {
font-size: small;
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
overflow-y: scroll;
}
input {
font-size: small;
width: 140px;
}
.filtersContainer {
background-color: white;
width: 60%;
margin: 50px 50px 50px 50px;
padding: 20px 20px 20px 20px;
}
.chartContainer {
background-color: white;
border: solid 1px black;
padding: 10px 10px 10px 10px;
margin: 50px 50px 50px 50px;
}
// ---------------------------------------------
// periode
.periode {
padding: 10px 10px 0px 10px;
}
.periode .titleContainer {
text-align: right;
border-right: solid 1px #dcdcdc;
font-weight: bold;
}
.btnToutSelectionner {
font-size: small;
}
.btnToutDeselectionner {
font-size: small;
}
// -------------------------------------------------------------------------
::ng-deep .mat-pseudo-checkbox-checked {
background-color: black !important;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PagesPopularityComponent } from './pages-popularity.component';
describe('SubjectsPopularityComponent', () => {
let component: PagesPopularityComponent;
let fixture: ComponentFixture<PagesPopularityComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PagesPopularityComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PagesPopularityComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,308 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {FormControl} from "@angular/forms";
import {ChartDataSets} from "chart.js";
import {Label} from "ng2-charts";
import { Router} from "@angular/router";
import {FictitiousAdvertsService} from "../../utils/services/fictitiousDatas/fictitiousAdverts/fictitious-adverts.service";
import {FictitiousVideosService} from "../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
import {ThemeService} from "../../utils/services/theme/theme.service";
import {MessageService} from "../../utils/services/message/message.service";
import {HttpParams} from "@angular/common/http";
interface CoupleNameViews {
name: string,
views: Date[],
}
@Component({
selector: 'app-subjects-popularity',
templateUrl: './pages-popularity.component.html',
styleUrls: ['./pages-popularity.component.scss']
})
export class PagesPopularityComponent implements OnInit
{
formControl: FormControl = new FormControl();
allCoupleNameViews: CoupleNameViews[] = [];
allInterests: string[] = [];
startDate: Date = null;
endDate: Date = null;
step: number = 1;
stepUnity: string = "jour" ;
oneDay: number = 24*60*60*1000;
oneWeek: number = 7*24*60*60*1000;
lineChartData: ChartDataSets[] = [];
lineChartLabels: Label[] = [];
chartOptions: any = {
responsive: true,
scales: {
yAxes: [{ display: true, scaleLabel: { display: true, labelString: "vues" } }],
xAxes: [{ scaleLabel: { display: true, labelString: "temps" } }],
}
};
isDisplayable: boolean = false;
constructor( private router: Router,
public themeService: ThemeService,
private fictitiousAdvertsService: FictitiousAdvertsService,
private fictitiousVideosService: FictitiousVideosService,
private messageService: MessageService ) {}
// -----------------------------------------------------------------------------------------------------
ngOnInit(): void
{
// Sera excuté si on est sur la page 'adsPopularity'
// Remplie l'attribut 'allCoupleNameViews'
if(this.router.url.includes("ads"))
{
let params = new HttpParams();
params = params.append("isActive", true);
this.messageService
.get("ad/findAll", params )
.subscribe(ret => this.afterReceivingAds(ret), err => this.afterReceivingAds(err));
}
// Sera excuté si on est sur la page 'subjectsPopularity'
// Remplie l'attribut 'allCoupleNameViews'
else if(this.router.url.includes("subjects"))
{
this.messageService
.get("misc/getInterests")
.subscribe( retour => {
if(retour.status !== "success") {
console.log(retour);
}
else {
this.allInterests = retour.data.map(x => x.interest);
this.allInterests.sort();
this.messageService
.get("video/findAll")
.subscribe(ret => this.afterReceivingVideos(ret), err => this.afterReceivingVideos(err));
}
});
}
}
// Callback: Sera excuté si on est sur la page 'adsPopularity'
afterReceivingAds(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
const allAdverts = retour.data;
for(let advert of allAdverts)
{
let couple = {name: advert.title, views: advert.views }
this.allCoupleNameViews.push(couple);
}
this.formControl = new FormControl(this.allCoupleNameViews);
this.onApplyFilter();
}
}
// Callback: Sera excuté si on est sur la page 'subjectsPopularity'
afterReceivingVideos(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
const allVideos = retour.data;
let myMap: Map<string,Date[]> = new Map();
// parcours des interest de chaque video
for(let video of allVideos)
{
const key = video.interest;
if(!myMap.has(key)) myMap.set(key, video.watchedDates);
else {
let tabDate = myMap.get(key);
for(let date0 of video.watchedDates) tabDate = this.insertInOrder(tabDate, date0);
myMap.set(key, tabDate);
}
}
// parcours les interest qui n'ont pas p été vu dans les videos
for(let interest of this.allInterests)
{
if(!myMap.has(interest)) myMap.set(interest, []);
}
// parcours de la map pour remplir 'allCoupleNameViews'
for(const [key, value] of myMap.entries())
{
let couple = {name: key, views: value }
this.allCoupleNameViews.push(couple);
}
this.formControl = new FormControl(this.allCoupleNameViews);
this.onApplyFilter();
}
}
// -----------------------------------------------------------------------------------------------------
// Applique le filtre
onApplyFilter(): void
{
// --- initialisation ---
this.lineChartData = [];
this.lineChartLabels = [];
if(this.step <= 0) this.step = 0;
if((this.endDate === null) || (this.endDate === undefined)) this.endDate = new Date();
if((this.startDate === null) || (this.startDate === undefined)) this.startDate = new Date(this.endDate.getTime() - this.oneWeek); // date d'il y a une semaine
const startTime = this.startDate.getTime();
const endTime = this.endDate.getTime();
// --- remplissage de 'lineChartLabels' ---
let dataWithZeros = [];
let time = startTime;
const intervals = [];
while(time <= endTime)
{
dataWithZeros.push(0);
this.lineChartLabels.push(this.getLabel(new Date(time)));
intervals.push(time);
time = this.addStep(time);
}
intervals.push(time);
// --- remplissage de 'lineChartLabels' ---
for(let coupleNameViews of this.formControl.value)
{
let data = dataWithZeros.slice();
let label = coupleNameViews.name;
let index = 0;
for(let date0 of coupleNameViews.views)
{
const time0 = (new Date(date0)).getTime();
if(time0 > endTime) break;
if((startTime <= time0) && (time0 <= endTime))
{
while((index < intervals.length) && (time0 >= intervals[index])) index += 1;
index = index - 1;
data[index] += 1;
}
}
this.lineChartData.push({"data": data.slice(), "label": label});
}
this.isDisplayable = true;
}
onNewStartDate(event): void {
this.startDate = new Date(event);
}
onNewEndDate(event): void {
this.endDate = new Date(event);
}
// Renvoie le bon label pour le graph
getLabel(date0: Date): string
{
if((this.stepUnity === 'jour') && (this.step === 1))
{
return date0.toLocaleDateString();
}
else {
const time2 = this.addStep((new Date(date0)).getTime()) - this.oneDay;
let date2 = new Date(time2);
return date0.toLocaleDateString() + " à " + date2.toLocaleDateString();
}
}
// Ajoute le bon pas à la date 'new Date(time)'
addStep(time: number): number
{
let newDate;
if(this.stepUnity === 'jour') {
newDate = new Date(time + this.step*this.oneDay);
}
else if(this.stepUnity === 'semaine') {
newDate = new Date(time + this.step*this.oneWeek);
}
else
{
const oldDate = new Date(time);
let newMonth = oldDate.getMonth() + this.step;
const newYear = oldDate.getFullYear() + (newMonth / 12);
newMonth = newMonth % 12;
const day = this.startDate.getDate();
if((newMonth === 1) && ([29, 30, 31].includes(day))) { // si fevrier et si jour n'existe pas
newDate = new Date(newYear, newMonth, 28);
}
else if((day === 31) && ([3, 5, 9, 10].includes(newMonth))) { // si 31 et mois à 30 jours
newDate = new Date(newYear, newMonth, 30);
}
else {
newDate = new Date(newYear, newMonth, day);
}
}
const _1h = 60*60*1000;
if(newDate.getHours() === 23) return newDate.getTime() + _1h;
else if(newDate.getHours() === 1) return newDate.getTime() - _1h;
else return newDate.getTime();
}
// Insere la date0 dans le tableau tabDate par ordre croissant
insertInOrder(tabDate: Date[], date0: Date): Date[]
{
let i = 0;
let n = tabDate.length;
let time0 = (new Date(date0)).getTime();
while((i <n) && (time0 > (new Date(tabDate[i])).getTime())) i++;
if(i === n) tabDate.push(date0);
else tabDate.splice(i, 0, date0);
return tabDate;
}
onSelectAll(): void
{
this.formControl = new FormControl(this.allCoupleNameViews);
}
onDeSelectAll(): void
{
this.formControl = new FormControl([]);
}
}

View file

@ -1,8 +0,0 @@
import { DragAndDropDirective } from './drag-and-drop.directive';
describe('DragAndDropDirective', () => {
it('should create an instance', () => {
const directive = new DragAndDropDirective();
expect(directive).toBeTruthy();
});
});

View file

@ -1,36 +0,0 @@
import {Directive, EventEmitter, HostBinding, HostListener, Output} from '@angular/core';
@Directive({
selector: '[appDragAndDrop]'
})
export class DragAndDropDirective
{
@HostBinding('class.fileover') fileOver: boolean;
@Output() fileDropped = new EventEmitter<any>();
// Dragover listener
@HostListener('dragover', ['$event']) onDragOver(evt) {
evt.preventDefault();
evt.stopPropagation();
this.fileOver = true;
}
// Dragleave listener
@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
evt.preventDefault();
evt.stopPropagation();
this.fileOver = false;
}
// Drop listener
@HostListener('drop', ['$event']) public ondrop(evt) {
evt.preventDefault();
evt.stopPropagation();
this.fileOver = false;
let files = evt.dataTransfer.files;
if (files.length > 0) {
this.fileDropped.emit(files);
}
}
}

View file

@ -1,41 +0,0 @@
<nav class="navbar navbar-expand-lg">
<!-- PolyNotFound -->
<a class="navbar-brand" routerLink="/url/adList"> StreamNotFound </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- [adList] [adsPopularity] [subjectsPopularity] -->
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item active monLi">
<a *ngIf="(url !== routes[0]) && (url !== routes[1])" [routerLink]="routes[1]" class="nav-link">Gestion des annonces</a>
<a *ngIf="(url === routes[0]) || (url === routes[1])" [routerLink]="routes[1]" class="nav-link myActiveLink">Gestion des annonces</a>
</li>
<li class="nav-item active monLi">
<a *ngIf="url !== routes[2]" [routerLink]="routes[2]" class="nav-link">Popularité des annonces</a>
<a *ngIf="url === routes[2]" [routerLink]="routes[2]" class="nav-link myActiveLink">Popularité des annonces</a>
</li>
<li class="nav-item active monLi">
<a *ngIf="url !== routes[3]" [routerLink]="routes[3]" class="nav-link">Popularité des domaines</a>
<a *ngIf="url === routes[3]" [routerLink]="routes[3]" class="nav-link myActiveLink">Popularité des domaines</a>
</li>
</ul>
</div>
<!-- Mon profil -->
<img [src]=profilService.getProfileImageUrl()
onerror="this.onerror=null; this.src='assets/profil.png'"
[routerLink]="routes[4]"
alt="">
<!-- Deconnexion -->
<button mat-button class="btnDeconnexion" (click)="onDeconnexion()" routerLink="/">
Déconnexion
</button>
</nav>

View file

@ -1,80 +0,0 @@
.navbar {
background-color: black;
height: 60px;
font-size: medium;
color: white;
}
.navbar-expand-lg {
border-bottom: solid;
border-color: white;
border-bottom-width: 2px;
}
// PolyNotFound
.navbar-brand {
font-family: cursive;
font-weight: bold;
font-size: x-large;
margin-left: 15px;
color: white;
}
.monLi {
margin: 0px 10px 0px 10px;
}
.nav-link {
color: white;
}
.nav-link:hover {
color: grey;
}
.myActiveLink {
text-decoration: underline;
}
.btnDeconnexion {
font-size: medium;
margin: 0px 10px 0px 10px
}
.btnDeconnexion:hover {
color: grey;
}
img {
border: solid 2px white;
border-radius: 50px;
margin: 0px 10px 0px 15px;
width: 40px;
height: 40px;
}
img:hover {
cursor: pointer;
}
// --------------------------------------------------------------------
::ng-deep .mat-slide-toggle-thumb {
background-color: #c8c8c8;
}
::ng-deep .mat-slide-toggle-bar {
background-color: #ffffff;
}
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
background-color: #ffffff;
}
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
background-color: #646464;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarAdvertiserComponent } from './navbar-advertiser.component';
describe('NavbarAdvertiserComponent', () => {
let component: NavbarAdvertiserComponent;
let fixture: ComponentFixture<NavbarAdvertiserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavbarAdvertiserComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(NavbarAdvertiserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,41 +0,0 @@
import { Component } from '@angular/core';
import {Router} from "@angular/router";
import {ProfilService} from "../../../utils/services/profil/profil.service";
import {MessageService} from "../../../utils/services/message/message.service";
@Component({
selector: 'app-navbar-advertiser',
templateUrl: './navbar-advertiser.component.html',
styleUrls: ['./navbar-advertiser.component.scss']
})
export class NavbarAdvertiserComponent
{
routes: string[] = [
"/advertiser", // 0
"/advertiser/adList", // 1
"/advertiser/adsPopularity", // 2
"/advertiser/subjectsPopularity", // 3
"/advertiser/myProfil" // 4
];
url = this.router.url;
constructor( private router: Router,
public profilService: ProfilService,
private messageService: MessageService ) { }
onDeconnexion(): void
{
this.messageService
.delete('user/logout')
.subscribe(retour => this.onDeconnexionCallback(retour), err => this.onDeconnexionCallback(err));
}
onDeconnexionCallback(retour: any): void
{
if(retour.status !== "success") console.log(retour);
}
}

View file

@ -1,53 +0,0 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {PageLoginComponent} from './beforeConnexion/login/page-login/page-login.component';
import {PageRegisterComponent} from "./beforeConnexion/register/page-register/page-register.component";
import {PageSearchComponent} from "./user/search/page-search/page-search.component";
import {PageMyPlaylistsComponent} from "./user/myPlaylists/page-my-playlists/page-my-playlists.component";
import {PageHistoryUserComponent} from "./user/history/page-history-user/page-history-user.component";
import {PageAdListAdvertiserComponent} from "./advertiser/adList/page-ad-list-advertiser/page-ad-list-advertiser.component";
import {PageProfilUserComponent} from "./user/myProfil/page-profil-user/page-profil-user.component";
import {PageProfilAdvertiserComponent} from "./advertiser/myProfil/page-profil-advertiser/page-profil-advertiser.component";
import {PageProfilAdminComponent} from "./admin/myProfil/page-profil-admin/page-profil-admin.component";
import {PageAdListAdminComponent} from "./admin/adList/page-ad-list-admin/page-ad-list-admin.component";
import {PageUserListComponent} from "./admin/userList/page-user-list/page-user-list.component";
import {PageWatchingVideoComponent} from "./user/watching/page-watching-video/page-watching-video.component";
import {PagesPopularityComponent} from "./advertiser/pages-popularity/pages-popularity.component";
const routes: Routes = [
// Before connexion
{ path: '', component: PageLoginComponent },
{ path: 'login', component: PageLoginComponent },
{ path: 'register', component: PageRegisterComponent },
// User
{ path: 'user', component: PageSearchComponent },
{ path: 'user/search', component: PageSearchComponent },
{ path: 'user/myPlaylists', component: PageMyPlaylistsComponent },
{ path: 'user/history', component: PageHistoryUserComponent },
{ path: 'user/myProfil', component: PageProfilUserComponent },
{ path: 'user/watching', component: PageWatchingVideoComponent },
// Advertiser
{ path: 'advertiser', component: PageAdListAdvertiserComponent },
{ path: 'advertiser/adList', component: PageAdListAdvertiserComponent },
{ path: 'advertiser/myProfil', component: PageProfilAdvertiserComponent },
{ path: 'advertiser/adsPopularity', component: PagesPopularityComponent },
{ path: 'advertiser/subjectsPopularity', component: PagesPopularityComponent },
// Admin
{ path: 'admin', component: PageUserListComponent },
{ path: 'admin/userList', component: PageUserListComponent },
{ path: 'admin/adList', component: PageAdListAdminComponent },
{ path: 'admin/myProfil', component: PageProfilAdminComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

View file

@ -1 +0,0 @@
<router-outlet></router-outlet>

View file

@ -1,24 +0,0 @@
::ng-deep snack-bar-container.custom-class {
//background: yellow;
}
::ng-deep .custom-class .mat-simple-snackbar {
//color: green;
justify-content: center;
}
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
border: solid 1px black !important;
background-color: white !important;
}

View file

@ -1,35 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'frontend'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('frontend');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('frontend app is running!');
});
});

View file

@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'frontend';
themeIsLight = true;
}

View file

@ -1,157 +0,0 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PageLoginComponent } from './beforeConnexion/login/page-login/page-login.component';
import { PageRegisterComponent } from './beforeConnexion/register/page-register/page-register.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import { PageSearchComponent } from './user/search/page-search/page-search.component';
import {HttpClientModule} from "@angular/common/http";
import { PopupConfirmationComponent } from './beforeConnexion/register/popup-confirmation/popup-confirmation.component';
import {MatDialogModule} from '@angular/material/dialog';
import {MatButtonModule} from "@angular/material/button";
import { AdvertComponent } from './user/utils/components/advert/advert.component';
import { VideoGridComponent } from './user/search/video-grid/video-grid.component';
import {MatIconModule} from "@angular/material/icon";
import { PopupAddVideoToPlaylistsComponent } from './user/utils/components/popup-add-video-to-playlists/popup-add-video-to-playlists.component';
import {MatInputModule} from "@angular/material/input";
import {MatDividerModule} from "@angular/material/divider";
import {MatCheckboxModule} from "@angular/material/checkbox";
import {MatFormFieldModule} from "@angular/material/form-field";
import {MatSnackBarModule} from "@angular/material/snack-bar";
import {MatGridListModule} from "@angular/material/grid-list";
import { PageMyPlaylistsComponent } from './user/myPlaylists/page-my-playlists/page-my-playlists.component';
import { PlaylistListComponent } from './user/myPlaylists/playlist-list/playlist-list.component';
import {VideoListComponent} from "./user/myPlaylists/video-list/video-list.component";
import { PopupCreateOrUpdatePlaylistComponent } from './user/myPlaylists/popup-create-or-update-playlist/popup-create-or-update-playlist.component';
import { PageHistoryUserComponent } from './user/history/page-history-user/page-history-user.component';
import {MatTableModule} from '@angular/material/table';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import {MatSortModule} from "@angular/material/sort";
import { PageAdListAdvertiserComponent } from './advertiser/adList/page-ad-list-advertiser/page-ad-list-advertiser.component';
import { PopupDeleteAdAdvertiserComponent } from './advertiser/adList/popup-delete-ad-advertiser/popup-delete-ad-advertiser.component';
import { PopupAddOrUpdateAdComponent } from './advertiser/adList/popup-add-or-update-ad/popup-add-or-update-ad.component';
import { PopupVisualizeAdAdvertiserComponent } from './advertiser/adList/popup-visualize-ad-advertiser/popup-visualize-ad-advertiser.component';
import { InputInterestsAdComponent } from './advertiser/adList/input-interests-ad/input-interests-ad.component';
import {MatChipsModule} from "@angular/material/chips";
import {MatAutocompleteModule} from "@angular/material/autocomplete";
import {MatSelectModule} from "@angular/material/select";
import { PopupVisualizeImagesAdvertiserComponent } from './advertiser/adList/popup-visualize-images-advertiser/popup-visualize-images-advertiser.component';
import {IvyCarouselModule} from "angular-responsive-carousel";
import { DragAndDropComponent } from './advertiser/adList/drag-and-drop/drag-and-drop.component';
import { DragAndDropDirective } from './advertiser/utils/dragAndDrop/drag-and-drop.directive';
import { PageProfilUserComponent } from './user/myProfil/page-profil-user/page-profil-user.component';
import { NavbarUserComponent } from './user/utils/components/navbar-user/navbar-user.component';
import { NavbarAdvertiserComponent } from './advertiser/utils/navbar-advertiser/navbar-advertiser.component';
import { NavbarAdminComponent } from './admin/utils/navbar-admin/navbar-admin.component';
import { PageProfilAdvertiserComponent } from './advertiser/myProfil/page-profil-advertiser/page-profil-advertiser.component';
import { PopupUpdateAdvertiserComponent } from './advertiser/myProfil/popup-update-advertiser/popup-update-advertiser.component';
import { PopupUpdateUserComponent } from './user/myProfil/popup-update-user/popup-update-user.component';
import { NavbarBeforeConnexionComponent } from './beforeConnexion/utils/navbar-before-connexion/navbar-before-connexion.component';
import {MatRadioModule} from "@angular/material/radio";
import { InputInterestsProfilComponent } from './user/myProfil/input-interests-profil/input-interests-profil.component';
import { PageProfilAdminComponent } from './admin/myProfil/page-profil-admin/page-profil-admin.component';
import { PopupUpdateAdminComponent } from './admin/myProfil/popup-update-admin/popup-update-admin.component';
import {MatStepperModule} from "@angular/material/stepper";
import { InputInterestsRegisterComponent } from './beforeConnexion/register/input-interests-register/input-interests-register.component';
import {MatPaginatorModule} from "@angular/material/paginator";
import { PageAdListAdminComponent } from './admin/adList/page-ad-list-admin/page-ad-list-admin.component';
import { PopupDeleteAdAdminComponent } from './admin/adList/popup-delete-ad-admin/popup-delete-ad-admin.component';
import { PopupVisualizeImagesAdminComponent } from './admin/adList/popup-visualize-images-admin/popup-visualize-images-admin.component';
import { PageUserListComponent } from './admin/userList/page-user-list/page-user-list.component';
import { PopupDeleteUserComponent } from './admin/userList/popup-delete-user/popup-delete-user.component';
import { PopupCreateUserComponent } from './admin/userList/popup-create-user/popup-create-user.component';
import { InputInterestsAdminComponent } from './admin/userList/input-interests-admin/input-interests-admin.component';
import { PageWatchingVideoComponent } from './user/watching/page-watching-video/page-watching-video.component';
import {MatDatepickerModule} from "@angular/material/datepicker";
import { PagesPopularityComponent } from './advertiser/pages-popularity/pages-popularity.component';
import { ChartsModule } from 'ng2-charts';
import { PopupDeletePlaylistComponent } from './user/myPlaylists/popup-delete-playlist/popup-delete-playlist.component';
import { PopupForgottenPasswordComponent } from './beforeConnexion/login/popup-forgotten-password/popup-forgotten-password.component';
@NgModule({
declarations: [
AppComponent,
PageLoginComponent,
PageRegisterComponent,
PageSearchComponent,
PopupConfirmationComponent,
AdvertComponent,
VideoGridComponent,
PopupAddVideoToPlaylistsComponent,
PageMyPlaylistsComponent,
VideoListComponent,
PlaylistListComponent,
VideoListComponent,
PopupCreateOrUpdatePlaylistComponent,
PageHistoryUserComponent,
PageAdListAdvertiserComponent,
PopupDeleteAdAdvertiserComponent,
PopupAddOrUpdateAdComponent,
PopupVisualizeAdAdvertiserComponent,
InputInterestsAdComponent,
PopupVisualizeImagesAdvertiserComponent,
DragAndDropComponent,
DragAndDropDirective,
PageProfilUserComponent,
NavbarUserComponent,
NavbarAdvertiserComponent,
NavbarAdminComponent,
PageProfilAdvertiserComponent,
PopupUpdateAdvertiserComponent,
PopupUpdateUserComponent,
NavbarBeforeConnexionComponent,
InputInterestsProfilComponent,
PageProfilAdminComponent,
PopupUpdateAdminComponent,
InputInterestsRegisterComponent,
PageAdListAdminComponent,
PopupDeleteAdAdminComponent,
PopupVisualizeImagesAdminComponent,
PageUserListComponent,
PopupDeleteUserComponent,
PopupCreateUserComponent,
InputInterestsAdminComponent,
PageWatchingVideoComponent,
PagesPopularityComponent,
PopupDeletePlaylistComponent,
PopupForgottenPasswordComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatSlideToggleModule,
FormsModule,
HttpClientModule,
MatDialogModule,
MatButtonModule,
MatIconModule,
MatInputModule,
MatDividerModule,
MatCheckboxModule,
MatFormFieldModule,
MatSnackBarModule,
MatGridListModule,
MatTableModule,
NgbModule,
MatSortModule,
MatChipsModule,
ReactiveFormsModule,
MatAutocompleteModule,
MatSelectModule,
IvyCarouselModule,
MatRadioModule,
MatStepperModule,
MatPaginatorModule,
MatDatepickerModule,
ChartsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View file

@ -1,36 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="bg">
<app-navbar-before-connexion pour="login"></app-navbar-before-connexion>
<div class="wrapper fadeInDown">
<div id="formContent">
<!-- Icon -->
<div class="fadeIn first">
<h1 style="font-family: cursive; font-size: 45px; margin-top: 20px; margin-bottom: 10px">StreamNotFound</h1>
<img src="../../../../assets/logo.png" id="icon" alt="User Icon" style="margin-top: 10px"/>
</div>
<!-- Login Form -->
<form>
<input [(ngModel)]="email" type="text" id="email" class="fadeIn second" name="email" placeholder="Email">
<input [(ngModel)]="password" type="password" id="password" class="fadeIn third" name="password" placeholder="Mot de passe">
<!-- Message d'erreur -->
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
<span class="mat-error"> {{errorMessage}} </span>
</div>
<input type="submit" class="fadeIn fourth" value="Se connecter" (click)="onSeConnecter()">
</form>
<!-- Oubli mot de passe -->
<div id="formFooter">
<a class="underlineHover" (click)="onForgottenPassword()">J'ai oublié mon mot de passe</a>
</div>
</div>
</div>
</div>
</div>

View file

@ -1,271 +0,0 @@
html {
background-color: #56baed;
}
body {
font-family: "Poppins", sans-serif;
height: 100vh;
}
a {
color: #5E89FF;
display:inline-block;
text-decoration: none;
font-weight: 400;
}
h2 {
text-align: center;
font-size: 16px;
font-weight: 600;
text-transform: uppercase;
display:inline-block;
margin: 40px 8px 10px 8px;
color: #cccccc;
}
/* STRUCTURE */
.wrapper {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
width: 100%;
min-height: 80%;
padding: 20px;
}
#formContent {
-webkit-border-radius: 10px 10px 10px 10px;
border-radius: 10px 10px 10px 10px;
background: #fff;
padding: 30px;
width: 90%;
max-width: 450px;
position: relative;
padding: 0px;
-webkit-box-shadow: 0 30px 60px 0 rgba(0,0,0,0.3);
box-shadow: 0 30px 60px 0 rgba(0,0,0,0.3);
text-align: center;
}
#formFooter {
background-color: #f6f6f6;
border-top: 1px solid #dce8f1;
padding: 25px;
text-align: center;
-webkit-border-radius: 0 0 10px 10px;
border-radius: 0 0 10px 10px;
}
/* TABS */
h2.inactive {
color: #cccccc;
}
h2.active {
color: #0d0d0d;
border-bottom: 2px solid #5fbae9;
}
/* FORM TYPOGRAPHY*/
input[type=button], input[type=submit], input[type=reset] {
background-color: #5E89FF;
border: none;
color: white;
padding: 15px 80px;
text-align: center;
text-decoration: none;
display: inline-block;
text-transform: uppercase;
font-size: 13px;
-webkit-box-shadow: 0 10px 30px 0 rgba(95,186,233,0.4);
box-shadow: 0 10px 30px 0 rgba(95,186,233,0.4);
-webkit-border-radius: 5px 5px 5px 5px;
border-radius: 5px 5px 5px 5px;
margin: 5px 20px 40px 20px;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
-o-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
input[type=button]:hover, input[type=submit]:hover, input[type=reset]:hover {
background-color: #39ace7;
}
input[type=button]:active, input[type=submit]:active, input[type=reset]:active {
-moz-transform: scale(0.95);
-webkit-transform: scale(0.95);
-o-transform: scale(0.95);
-ms-transform: scale(0.95);
transform: scale(0.95);
}
input[type=text], input[type=password] {
background-color: #f6f6f6;
border: none;
color: #0d0d0d;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 5px;
width: 85%;
border: 2px solid #f6f6f6;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
-webkit-border-radius: 5px 5px 5px 5px;
border-radius: 5px 5px 5px 5px;
}
input[type=text]:focus, input[type=password]:focus {
background-color: #fff;
border-bottom: 2px solid #5fbae9;
}
input[type=text]::placeholder, input[type=password]::placeholder {
color: #cccccc;
}
.bg{
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
overflow-y: hidden;
overflow-x: hidden;
}
/* ANIMATIONS */
/* Simple CSS3 Fade-in-down Animation */
.fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
@-webkit-keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
@keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
/* Simple CSS3 Fade-in Animation */
@-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.fadeIn {
opacity:0;
-webkit-animation:fadeIn ease-in 1;
-moz-animation:fadeIn ease-in 1;
animation:fadeIn ease-in 1;
-webkit-animation-fill-mode:forwards;
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.fadeIn.first {
-webkit-animation-delay: 0.4s;
-moz-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.fadeIn.second {
-webkit-animation-delay: 0.6s;
-moz-animation-delay: 0.6s;
animation-delay: 0.6s;
}
.fadeIn.third {
-webkit-animation-delay: 0.8s;
-moz-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.fadeIn.fourth {
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
/* Simple CSS3 Fade-in Animation */
.underlineHover:after {
display: block;
left: 0;
bottom: -10px;
width: 0;
height: 2px;
//background-color: #5E89FF;
background-color: #5E89FF;
content: "";
transition: width 0.2s;
}
.underlineHover:hover {
color: #0d0d0d;
}
.underlineHover:hover:after{
width: 100%;
}
h1{
color: black;
}
/* OTHERS */
*:focus {
outline: none;
}
#icon {
width:30%;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageLoginComponent } from './page-login.component';
describe('PageConnexionComponent', () => {
let component: PageLoginComponent;
let fixture: ComponentFixture<PageLoginComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageLoginComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageLoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,101 +0,0 @@
import {Component, OnInit} from '@angular/core';
import {MessageService} from "../../../utils/services/message/message.service";
import {Router} from "@angular/router";
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {MatDialog} from "@angular/material/dialog";
import {PopupForgottenPasswordComponent} from "../popup-forgotten-password/popup-forgotten-password.component";
import {MatSnackBar} from "@angular/material/snack-bar";
import {ProfilService} from "../../../utils/services/profil/profil.service";
@Component({
selector: 'app-page-login',
templateUrl: './page-login.component.html',
styleUrls: ['./page-login.component.scss']
})
export class PageLoginComponent implements OnInit
{
email: string = "" ;
password: string = "" ;
hasError: boolean = false;
errorMessage: string = "";
constructor( private messageService: MessageService,
private router: Router,
public themeService: ThemeService,
public dialog: MatDialog,
private snackBar: MatSnackBar,
private profilService: ProfilService) { }
ngOnInit(): void {}
onSeConnecter(): void
{
this.checkError();
if(!this.hasError)
{
let data = {
email: this.email,
hashPass: this.password
};
this.messageService
.post('user/auth', data)
.subscribe( retour => this.onSeConnecterCallback(retour), err => this.onSeConnecterCallback(err));
}
}
onSeConnecterCallback(retour): void
{
if(retour.status !== "success") {
console.log(retour);
this.errorMessage = retour.error.reason;
this.hasError = true;
}
else {
this.profilService.setId(retour.data.id);
this.profilService.setProfileImageUrl(retour.data.profileImageUrl);
if(retour.data.role.name === "user") this.router.navigateByUrl( '/user/search');
else if(retour.data.role.name === "advertiser") this.router.navigateByUrl( '/advertiser/adList');
else if(retour.data.role.name === "admin" || retour.data.role.name === "superAdmin") this.router.navigateByUrl( '/admin/userList');
}
}
onForgottenPassword(): void
{
this.dialog
.open(PopupForgottenPasswordComponent, {width: '30%'})
.afterClosed()
.subscribe(result => {
if((result !== null) && (result !== undefined))
{
const config = { duration: 5000, panelClass: "custom-class" };
this.snackBar.open( "Un mail de réinitialisation de mot de passe vous a été envoyé.", "", config);
}
});
}
checkError(): void
{
if(this.email === "") {
this.errorMessage = "Veuillez remplir le champ email" ;
this.hasError = true;
}
else if(this.password === "") {
this.errorMessage = "Veuillez remplir le champ mot de passe" ;
this.hasError = true;
}
else {
this.errorMessage = "" ;
this.hasError = false;
}
}
}

View file

@ -1,24 +0,0 @@
<h4>Récupération du mot de passe</h4>
<mat-divider></mat-divider><br>
<!-- email -->
<div class="myDiv">
<mat-form-field appearance="fill">
<mat-label>Email</mat-label>
<input matInput type="email" [(ngModel)]="email" required>
</mat-form-field>
</div>
<!-- message d'erreur -->
<div class="myError" *ngIf="hasError">
<span class="mat-error">{{errorMessage}}</span>
</div>
<mat-divider></mat-divider>
<!-- boutons -->
<mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close()">Annuler</button>
<button mat-button (click)="onValidate()" cdkFocusInitial>Valider</button>
</mat-dialog-actions>

View file

@ -1,12 +0,0 @@
h4 {
text-align: center;
}
.myDiv {
text-align: center;
font-size: small;
}
.myError {
text-align: center;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupForgottenPasswordComponent } from './popup-forgotten-password.component';
describe('PopupForgottenPasswordComponent', () => {
let component: PopupForgottenPasswordComponent;
let fixture: ComponentFixture<PopupForgottenPasswordComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupForgottenPasswordComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupForgottenPasswordComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,47 +0,0 @@
import { Component } from '@angular/core';
import {MatDialogRef} from "@angular/material/dialog";
@Component({
selector: 'app-popup-forgotten-password',
templateUrl: './popup-forgotten-password.component.html',
styleUrls: ['./popup-forgotten-password.component.scss']
})
export class PopupForgottenPasswordComponent
{
email: string;
hasError: boolean = false;
errorMessage: string = "";
constructor(public dialogRef: MatDialogRef<PopupForgottenPasswordComponent>) {}
// Click sur valider
onValidate()
{
if(this.email.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'email'." ;
this.hasError = true;
}
else if(!this.isValidEmail(this.email)) {
this.errorMessage = "Email invalide." ;
this.hasError = true;
}
else {
this.errorMessage = "" ;
this.hasError = false;
this.dialogRef.close(true);
}
}
// Indique si email a bien le format d'un email
isValidEmail(email): boolean
{
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
}

Some files were not shown because too many files have changed in this diff Show more