diff --git a/src/app/advertiser/drag-and-drop/drag-and-drop.component.html b/src/app/advertiser/drag-and-drop/drag-and-drop.component.html new file mode 100644 index 0000000..f173baa --- /dev/null +++ b/src/app/advertiser/drag-and-drop/drag-and-drop.component.html @@ -0,0 +1,29 @@ +
+ +

Images

+ +
Glisser déposer
+
ou
+
Cliquer pour selectionner
+
+info +
+
+ file +
+

+ {{ file?.name }} +

+

+ {{ formatBytes(file?.size) }} +

+
+
+
+
+
+ +
+
diff --git a/src/app/advertiser/drag-and-drop/drag-and-drop.component.scss b/src/app/advertiser/drag-and-drop/drag-and-drop.component.scss new file mode 100644 index 0000000..4683f9f --- /dev/null +++ b/src/app/advertiser/drag-and-drop/drag-and-drop.component.scss @@ -0,0 +1,143 @@ +.container { + width: 450px; + height: 220px; + 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; +} + + +h3 { + font-size: 20px; + font-weight: 600; + color: #38424c; +} + + + +.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; + } +} diff --git a/src/app/advertiser/drag-and-drop/drag-and-drop.component.spec.ts b/src/app/advertiser/drag-and-drop/drag-and-drop.component.spec.ts new file mode 100644 index 0000000..e4666b0 --- /dev/null +++ b/src/app/advertiser/drag-and-drop/drag-and-drop.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DragAndDropComponent } from './drag-and-drop.component'; + +describe('DragAndDropComponent', () => { + let component: DragAndDropComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DragAndDropComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DragAndDropComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/advertiser/drag-and-drop/drag-and-drop.component.ts b/src/app/advertiser/drag-and-drop/drag-and-drop.component.ts new file mode 100644 index 0000000..6fe4a6d --- /dev/null +++ b/src/app/advertiser/drag-and-drop/drag-and-drop.component.ts @@ -0,0 +1,90 @@ +import {Component, ElementRef, OnInit, 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; + files: any[] = []; + info_image = "Vos annonces seront affichées dans un rectangle de rapport 1/5 avec: \n • 1 la largeur durectangle \n • 5 la hauteur du rectangle" ; + + + /** + * on file drop handler + */ + onFileDropped($event) { + this.prepareFilesList($event); + } + + /** + * handle file from browsing + */ + fileBrowseHandler(files) { + this.prepareFilesList(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); + } + + /** + * 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) { + 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]; + } + +} diff --git a/src/app/advertiser/page-advertiser/page-advertiser.component.ts b/src/app/advertiser/page-advertiser/page-advertiser.component.ts index dc83d59..939ff63 100644 --- a/src/app/advertiser/page-advertiser/page-advertiser.component.ts +++ b/src/app/advertiser/page-advertiser/page-advertiser.component.ts @@ -62,7 +62,8 @@ export class PageAdvertiserComponent implements OnInit onAdd(): void { const config = { - width: '50%', + width: '40%', + height: '80%', data: { action: "add", advert: null } }; this.dialog @@ -89,7 +90,8 @@ export class PageAdvertiserComponent implements OnInit onUpdate(advertToUpdate: Advert): void { const config = { - width: '50%', + width: '40%', + height: '80%', data: { action: "update", advert: advertToUpdate } }; this.dialog diff --git a/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.html b/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.html index 3d4fc66..86f8a65 100644 --- a/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.html +++ b/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.html @@ -5,7 +5,7 @@ - +
@@ -15,9 +15,7 @@
- - - + @@ -31,7 +29,7 @@ Visible - +
diff --git a/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.scss b/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.scss index f7796bd..5bfabd8 100644 --- a/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.scss +++ b/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.scss @@ -1,5 +1,7 @@ .lightTheme, .darkTheme { background-image: none; + overflow-y: hidden; + overflow-x: hidden; } h1 { @@ -12,15 +14,15 @@ h1 { // ------------------------------------------------------------------------- -mat-dialog-content { - overflow-y: hidden; - //padding: 20px 20px 20px 20px; -} .commentContainer { width: 100%; } +.imageContainer { + border: solid 1px grey; +} + // ------------------------------------------------------------------------- // --- LightTheme --- diff --git a/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.ts b/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.ts index 5c81ce0..d109b04 100644 --- a/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.ts +++ b/src/app/advertiser/popup-add-or-update-ad/popup-add-or-update-ad.component.ts @@ -29,6 +29,9 @@ export class PopupAddOrUpdateAdComponent implements OnInit advert: Advert; urlBackend: string = "" ; title: string = "" ; + tabWaitingFile: File[] = []; // fichiers selectionnés mais pas encore "validés" + tabSelectedFile: File[] = []; // fichier "validés" + _event; constructor( public dialogRef: MatDialogRef, @@ -79,9 +82,34 @@ export class PopupAddOrUpdateAdComponent implements OnInit } - onEventBarTags(myTags: string[]) + onEventBarTags(myTags: string[]): void { this.advert.tags = myTags; } + + // Lorsque l'annonceur selectionne des fichiers + onSelectFile(event) + { + const nbFileSelected = event.target.files.length ; + for(let i=0 ; i file); + this.tabSelectedFile.splice(index, 1); + } + } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 76d3331..b8dc48d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -46,6 +46,8 @@ import {MatAutocompleteModule} from "@angular/material/autocomplete"; import {MatSelectModule} from "@angular/material/select"; import { PopupVisualizeImagesComponent } from './advertiser/popup-visualize-images/popup-visualize-images.component'; import {IvyCarouselModule} from "angular-responsive-carousel"; +import { DragAndDropComponent } from './advertiser/drag-and-drop/drag-and-drop.component'; +import { DragAndDropDirective } from './utils/directives/dragAndDrop/drag-and-drop.directive'; @NgModule({ @@ -75,6 +77,8 @@ import {IvyCarouselModule} from "angular-responsive-carousel"; PopupVisualizeAdComponent, BarTagsComponent, PopupVisualizeImagesComponent, + DragAndDropComponent, + DragAndDropDirective, ], imports: [ BrowserModule, diff --git a/src/app/utils/directives/dragAndDrop/drag-and-drop.directive.spec.ts b/src/app/utils/directives/dragAndDrop/drag-and-drop.directive.spec.ts new file mode 100644 index 0000000..60cf3d6 --- /dev/null +++ b/src/app/utils/directives/dragAndDrop/drag-and-drop.directive.spec.ts @@ -0,0 +1,8 @@ +import { DragAndDropDirective } from './drag-and-drop.directive'; + +describe('DragAndDropDirective', () => { + it('should create an instance', () => { + const directive = new DragAndDropDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/src/app/utils/directives/dragAndDrop/drag-and-drop.directive.ts b/src/app/utils/directives/dragAndDrop/drag-and-drop.directive.ts new file mode 100644 index 0000000..b3d1162 --- /dev/null +++ b/src/app/utils/directives/dragAndDrop/drag-and-drop.directive.ts @@ -0,0 +1,36 @@ +import {Directive, EventEmitter, HostBinding, HostListener, Output} from '@angular/core'; + +@Directive({ + selector: '[appDragAndDrop]' +}) +export class DragAndDropDirective +{ + @HostBinding('class.fileover') fileOver: boolean; + @Output() fileDropped = new EventEmitter(); + + // 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); + } + } + +} diff --git a/src/assets/uploadFile.png b/src/assets/uploadFile.png new file mode 100644 index 0000000..cff9f38 Binary files /dev/null and b/src/assets/uploadFile.png differ