-
+
-
-
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
0 && inputFocused"
@@ -130,7 +148,11 @@
-
+
-
-
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 });
+ }
}