diff --git a/src/app/components/add-pin-popup/add-pin-popup.component.html b/src/app/components/add-pin-popup/add-pin-popup.component.html index 90baa14..bf80d4b 100644 --- a/src/app/components/add-pin-popup/add-pin-popup.component.html +++ b/src/app/components/add-pin-popup/add-pin-popup.component.html @@ -68,7 +68,11 @@
- + -
- Le titre est requis - Le titre doit contenir au moins 3 caractères +
+ Le titre est requis + Le titre doit contenir au moins 3 caractères
@@ -97,8 +108,15 @@ (focus)="onFocus()" (blur)="onBlur()" /> -
- La localisation est requise +
+ La localisation est requise
    - + -
    - La description est requise - La description doit contenir au moins 3 caractères +
    + La description est requise + La description doit contenir au moins 3 caractères
    diff --git a/src/app/components/leaflet-map/leaflet-map.component.ts b/src/app/components/leaflet-map/leaflet-map.component.ts index f6610bf..01bbd95 100644 --- a/src/app/components/leaflet-map/leaflet-map.component.ts +++ b/src/app/components/leaflet-map/leaflet-map.component.ts @@ -10,11 +10,11 @@ import { FormsModule } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import * as L from 'leaflet'; import { Pin } from '../../model/Pin'; +import { AutocompleteService } from '../../services/auto-complete/auto-complete.service'; import { MapReloadService } from '../../services/map-reload/map-reload.service'; import { ModalService } from '../../services/modal/modal.service'; import { PinService } from '../../services/pin/pin.service'; import { PinMarkerComponent } from '../pin-marker/pin-marker.component'; -import { AutocompleteService } from '../../services/auto-complete/auto-complete.service'; @Component({ selector: 'app-leaflet-map', @@ -112,11 +112,13 @@ export class LeafletMapComponent implements OnInit { // Créer le contenu du menu contextuel const menuContent = document.createElement('div'); - menuContent.className = 'bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden'; - + menuContent.className = + 'bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden'; + const addPinButton = document.createElement('button'); - addPinButton.className = 'w-full px-4 py-2.5 text-sm font-medium text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-600 flex items-center gap-2'; - + addPinButton.className = + 'w-full px-4 py-2.5 text-sm font-medium text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-600 flex items-center gap-2'; + // Ajouter l'icône de pin const pinIcon = document.createElement('span'); pinIcon.innerHTML = ` @@ -125,13 +127,13 @@ export class LeafletMapComponent implements OnInit { `; - + const buttonText = document.createElement('span'); buttonText.textContent = 'Ajouter un pin ici'; - + addPinButton.appendChild(pinIcon); addPinButton.appendChild(buttonText); - + addPinButton.onclick = () => { this.addPinAtLocation(latlng); if (this.contextMenu) { @@ -147,7 +149,7 @@ export class LeafletMapComponent implements OnInit { closeButton: false, className: 'context-menu-popup', maxWidth: 200, - offset: [0, -10] + offset: [0, -10], }) .setLatLng(latlng) .setContent(menuContent) @@ -165,15 +167,15 @@ export class LeafletMapComponent implements OnInit { this.modalService.openModal('add-pin-modal', [], { location: address?.display_name || '', complete_address: address?.display_name || '', - coordinates: [latlng.lat, latlng.lng] + coordinates: [latlng.lat, latlng.lng], }); } catch (error) { - console.error('Erreur lors de la récupération de l\'adresse:', error); + console.error("Erreur lors de la récupération de l'adresse:", error); // En cas d'erreur, ouvrir la modal avec juste les coordonnées this.modalService.openModal('add-pin-modal', [], { location: `${latlng.lat}, ${latlng.lng}`, complete_address: `${latlng.lat}, ${latlng.lng}`, - coordinates: [latlng.lat, latlng.lng] + coordinates: [latlng.lat, latlng.lng], }); } } @@ -201,15 +203,18 @@ export class LeafletMapComponent implements OnInit { private extractPersons(pins: Pin[]): void { const personsSet = new Set(); - const regex = /@(\w+)/g; + + // Pour chaque pin, récupérer ses partages pins.forEach((pin) => { - const desc = pin.description || ''; - let match; - while ((match = regex.exec(desc)) !== null) { - personsSet.add(match[1]); - } + this.pinsService.getPinShares(pin.id).subscribe((response: any) => { + if (response && response.shares) { + response.shares.forEach((share: any) => { + personsSet.add(share.username); + }); + this.availablePersons = Array.from(personsSet).sort(); + } + }); }); - this.availablePersons = Array.from(personsSet).sort(); } onCountryChange(country: string) { @@ -288,8 +293,8 @@ export class LeafletMapComponent implements OnInit { const zoom = this.map.getZoom(); const offsetLat = 0.05 / Math.pow(2, zoom - 10); this.map.setView( - L.latLng(latlng.lat + offsetLat, latlng.lng), - zoom + L.latLng(latlng.lat + offsetLat, latlng.lng), + zoom ); } } @@ -311,7 +316,9 @@ export class LeafletMapComponent implements OnInit { public loadPins(): void { this.pinsService.getPins().subscribe((pins: Pin[]) => { // Supprimer du body toutes les divs confirm-modal-* / share-modal-* / edit-pin-popup-* - const modals = document.querySelectorAll('div[id^="confirm-modal-"], div[id^="share-modal-"], div[id^="edit-pin-popup-"]'); + const modals = document.querySelectorAll( + 'div[id^="confirm-modal-"], div[id^="share-modal-"], div[id^="edit-pin-popup-"]' + ); modals.forEach((modal) => { modal.remove(); }); diff --git a/src/app/components/share-modal/share-modal.component.html b/src/app/components/share-modal/share-modal.component.html index 76792a6..e208b65 100644 --- a/src/app/components/share-modal/share-modal.component.html +++ b/src/app/components/share-modal/share-modal.component.html @@ -1,4 +1,4 @@ -
    +
    diff --git a/src/app/components/share-modal/share-modal.component.ts b/src/app/components/share-modal/share-modal.component.ts index 8c997ab..348bde5 100644 --- a/src/app/components/share-modal/share-modal.component.ts +++ b/src/app/components/share-modal/share-modal.component.ts @@ -1,7 +1,12 @@ import { CommonModule } from '@angular/common'; -import { Component, Input, EventEmitter, OnDestroy, OnInit } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnDestroy, + OnInit, +} from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { Router } from '@angular/router'; import { Subject, Subscription } from 'rxjs'; import { FriendsService } from '../../services/friends/friends.service'; import { ModalService } from '../../services/modal/modal.service'; @@ -25,14 +30,15 @@ export class ShareModalComponent implements OnInit, OnDestroy { searchTermChanged = new Subject(); listUser: any[] = []; listFriend: any[] = []; - + pinShares: any[] = []; + @Input() pinId!: string; @Input() pinOpened!: EventEmitter; constructor( private modalService: ModalService, private friendService: FriendsService, - private pinService: PinService, + private pinService: PinService ) {} ngOnInit() { @@ -84,22 +90,33 @@ export class ShareModalComponent implements OnInit, OnDestroy { } protected getFriend() { - this.friendService.getFriend().subscribe((friends: any[]) => { - this.listFriend = []; - this.listUser = []; - - // Récupérer les détails de chaque ami - friends.forEach((friend) => { - this.friendService - .getFriendById(friend.friend_user_id) - .subscribe((userDetails: any) => { - const friendWithDetails = { - ...friend, - username: userDetails.username, - }; - this.listFriend.push(friendWithDetails); - this.listUser.push(friendWithDetails); - }); + // Récupérer d'abord les partages du pin + this.pinService.getPinShares(this.pinId).subscribe((response: any) => { + this.pinShares = response.shares || []; + + // Ensuite récupérer les amis + this.friendService.getFriend().subscribe((friends: any[]) => { + this.listFriend = []; + this.listUser = []; + + // Récupérer les détails de chaque ami + friends.forEach((friend) => { + if (friend.status === 'accepted') { + this.friendService + .getFriendById(friend.friend_user_id) + .subscribe((userDetails: any) => { + const friendWithDetails = { + ...friend, + username: userDetails.username, + isShared: this.pinShares.some( + (share) => share.user_id === friend.friend_user_id + ), + }; + this.listFriend.push(friendWithDetails); + this.listUser.push(friendWithDetails); + }); + } + }); }); }); } diff --git a/src/app/services/pin/pin.service.ts b/src/app/services/pin/pin.service.ts index d764e70..097b4ee 100644 --- a/src/app/services/pin/pin.service.ts +++ b/src/app/services/pin/pin.service.ts @@ -1,11 +1,8 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { switchMap } from 'rxjs'; import { environment } from '../../../environment'; import { Pin } from '../../model/Pin'; -import { AutocompleteService } from '../auto-complete/auto-complete.service'; import { AuthService } from '../auth/auth.service'; -// import { ImageService } from '../image/image.service'; @Injectable({ providedIn: 'root', @@ -16,17 +13,13 @@ export class PinService { private apiURL = environment.apiURL; - constructor( - private http: HttpClient, - private autoCompleteService: AutocompleteService, - private authService: AuthService - ) {} + constructor(private http: HttpClient, private authService: AuthService) {} getPins(): any { const url = `${this.apiURL}/pins`; const headers = this.authService.getAuthHeaders(); headers.set('Content-Type', 'application/json'); - + return this.http.get(url, { headers }); } @@ -34,32 +27,24 @@ export class PinService { const url = `${this.apiURL}/pin/add`; const headers = this.authService.getAuthHeaders(); headers.set('Content-Type', 'application/json'); - - return this.http.post( - url, pin, { headers } - ); + + return this.http.post(url, pin, { headers }); } - updatePin( - id: string, - pin: Pin - ) { + updatePin(id: string, pin: Pin) { const url = `${this.apiURL}/pin/${id}`; const headers = this.authService.getAuthHeaders(); headers.set('Content-Type', 'application/json'); - // Obtenir les coordonnées GPS à partir de l'adresse - return this.http.patch( - url, pin, { headers } - ); + return this.http.patch(url, pin, { headers }); } deletePin(id: string) { const url = `${this.apiURL}/pin/${id}`; const headers = this.authService.getAuthHeaders(); headers.set('Content-Type', 'application/json'); - + return this.http.delete(url, { headers }); } @@ -67,7 +52,16 @@ export class PinService { const url = `${this.apiURL}/pin/${pinId}/share`; const headers = this.authService.getAuthHeaders(); headers.set('Content-Type', 'application/json'); - + return this.http.post(url, { friend_id: friendId }, { headers }); } + + getPinShares(pinId: string) { + const url = `${this.apiURL}/pin/${pinId}/shares`; + const headers = new HttpHeaders({ + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + localStorage.getItem('auth_token'), + }); + return this.http.get(url, { headers }); + } }