diff --git a/src/components/Map/markerManager.js b/src/components/Map/markerManager.js
index 8cb2ef8..6480a74 100644
--- a/src/components/Map/markerManager.js
+++ b/src/components/Map/markerManager.js
@@ -1,50 +1,30 @@
import maplibregl from "maplibre-gl";
-/**
- * Supprime tous les marqueurs
- */
export function clearAllMarkers(markersRef, expandedElRef) {
if (markersRef.current) {
for (const m of markersRef.current) {
- try {
- m.marker.remove();
- } catch {
- // ignore
- }
+ try { m.marker.remove(); } catch {}
}
}
markersRef.current = [];
- if (expandedElRef) {
- expandedElRef.current = null;
- }
+ if (expandedElRef) expandedElRef.current = null;
}
-/**
- * Marker stable: root 0x0 + UI en absolute au-dessus d'un tip fixe.
- * => Le pin ne "jump" plus quand tu expand/collapse.
- */
export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
const map = mapRef.current;
if (!map) return;
- // --- coordonnées ---
const lat =
- typeof post.lat === "number"
- ? post.lat
- : typeof post.Lat === "number"
- ? post.Lat
- : typeof post.latitude === "number"
- ? post.latitude
- : null;
+ typeof post.lat === "number" ? post.lat :
+ typeof post.Lat === "number" ? post.Lat :
+ typeof post.latitude === "number" ? post.latitude :
+ null;
const lon =
- typeof post.lon === "number"
- ? post.lon
- : typeof post.Lon === "number"
- ? post.Lon
- : typeof post.longitude === "number"
- ? post.longitude
- : null;
+ typeof post.lon === "number" ? post.lon :
+ typeof post.Lon === "number" ? post.Lon :
+ typeof post.longitude === "number" ? post.longitude :
+ null;
if (lat == null || lon == null) {
console.warn("post sans coordonnée:", post);
@@ -58,20 +38,16 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
title;
const author = (post.author || post.Author || "").trim() || "unknown";
- const created =
- (post.created_at || post.CreatedAt || "").toString().slice(0, 19);
+ const created = (post.created_at || post.CreatedAt || "").toString().slice(0, 19);
const category = (post.category || post.Category || "").toUpperCase() || "";
const subCat = (post.sub_category || post.SubCategory || "").toString();
- // Root ancré stable
const root = document.createElement("div");
root.className = "post-pin";
- // Layer UI (au-dessus du tip)
const layer = document.createElement("div");
layer.className = "post-pin-layer";
- // Compact UI
const compact = document.createElement("div");
compact.className = "post-pin-compact";
compact.innerHTML = `
@@ -79,7 +55,6 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
${escapeHtml(title)}
`;
- // Expanded UI
const expanded = document.createElement("div");
expanded.className = "post-pin-expanded post-hidden";
expanded.innerHTML = `
@@ -115,7 +90,9 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
`;
- // Tip fixe (le point de la map)
+ // IMPORTANT: cliquer sur les boutons ne doit pas re-toggle le marker
+ expanded.addEventListener("click", (e) => e.stopPropagation());
+
const tip = document.createElement("div");
tip.className = "post-pin-tip";
@@ -124,10 +101,7 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
root.appendChild(layer);
root.appendChild(tip);
- const marker = new maplibregl.Marker({
- element: root,
- anchor: "bottom",
- })
+ const marker = new maplibregl.Marker({ element: root, anchor: "bottom" })
.setLngLat([lon, lat])
.addTo(map);
@@ -145,10 +119,12 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
}
}
+ // expose pour fermer depuis un autre marker
+ root.__setExpanded = setExpanded;
+
root.addEventListener("click", (ev) => {
ev.stopPropagation();
- // Fermer l'ancien expanded
if (expandedElRef.current && expandedElRef.current !== root) {
const prev = expandedElRef.current;
if (prev && prev.__setExpanded) prev.__setExpanded(false);
@@ -157,12 +133,8 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
const isExpanded = !expanded.classList.contains("post-hidden");
setExpanded(!isExpanded);
});
-
- // expose pour pouvoir fermer depuis un autre marker
- root.__setExpanded = setExpanded;
}
-/* petite fonction pour éviter d’injecter du HTML sale */
function escapeHtml(str) {
return String(str)
.replace(/&/g, "&")
diff --git a/src/styles/mapMarkers.css b/src/styles/mapMarkers.css
index e53a68c..0400b50 100644
--- a/src/styles/mapMarkers.css
+++ b/src/styles/mapMarkers.css
@@ -1,166 +1,140 @@
-/* MapLibre gère la position/transform, on ne touche pas */
-.post-pin {
+/* SocioWire — Marker stable (no jump)
+ Root 0x0 anchored, UI absolutely positioned above a fixed tip */
+
+.post-pin{
+ position: relative;
+ width: 0;
+ height: 0;
+ pointer-events: auto;
+ transform: translate3d(0,0,0);
+}
+
+.post-pin-layer{
+ position: absolute;
+ left: 0;
+ top: 0;
+ transform: translate(-50%, calc(-100% - 14px)); /* 14px ~ tip height */
display: flex;
flex-direction: column;
align-items: center;
- pointer-events: auto;
}
-/* ===== ÉTAT COMPACT : petite bulle + petite pointe ===== */
+.post-pin-tip{
+ position: absolute;
+ left: 0;
+ top: 0;
+ transform: translate(-50%, -100%);
+ width: 0;
+ height: 0;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+ border-top: 11px solid rgba(8, 20, 40, 0.97);
+ filter: drop-shadow(0 2px 4px rgba(0,0,0,0.8));
+}
-.post-pin--compact .post-pin-bubble {
+.post-hidden{ display:none !important; }
+
+/* ===== COMPACT ===== */
+.post-pin-compact{
display: inline-flex;
align-items: center;
padding: 4px 8px;
border-radius: 999px;
background: rgba(6, 40, 80, 0.95);
border: 1px solid rgba(80, 180, 255, 0.9);
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 2px 4px rgba(0,0,0,0.5);
+ max-width: 200px;
}
-.post-pin-dot {
+.post-pin-dot{
width: 10px;
height: 10px;
border-radius: 999px;
background: #ff8a00;
margin-right: 6px;
+ flex-shrink: 0;
}
-.post-pin-text {
+.post-pin-text{
color: #e8f5ff;
font-size: 11px;
font-weight: 500;
- max-width: 120px;
+ max-width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
-/* petite pointe */
-.post-pin-pointer-small {
- width: 0;
- height: 0;
- margin-top: 2px;
- border-left: 7px solid transparent;
- border-right: 7px solid transparent;
- border-top: 9px solid rgba(6, 40, 80, 0.95);
- filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
-}
-
-/* ===== ÉTAT ÉTENDU : gros post (carte) ===== */
-
-.post-pin--expanded .post-card {
+/* ===== EXPANDED ===== */
+.post-pin-expanded{
min-width: 260px;
max-width: 320px;
background: rgba(8, 20, 40, 0.97);
border-radius: 14px;
padding: 10px 12px;
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.8);
+ box-shadow: 0 6px 18px rgba(0,0,0,0.8);
border: 1px solid rgba(90, 190, 255, 0.9);
color: #e8f5ff;
box-sizing: border-box;
}
-/* header : catégorie + heure/date */
-.post-card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 11px;
- margin-bottom: 6px;
+/* header */
+.post-card-header{
+ display:flex;
+ justify-content:space-between;
+ align-items:center;
+ font-size:11px;
+ margin-bottom:6px;
}
+.post-card-cat{ font-weight:600; color:#8fc5ff; }
+.post-card-time{ color:#9eb7ff; }
-.post-card-cat {
- font-weight: 600;
- color: #8fc5ff;
+/* main */
+.post-card-main{
+ display:flex;
+ gap:8px;
+ margin-bottom:6px;
}
-
-.post-card-time {
- color: #9eb7ff;
-}
-
-/* corps : media + texte */
-.post-card-main {
- display: flex;
- flex-direction: row;
- gap: 8px;
- margin-bottom: 6px;
-}
-
-/* fake bloc image/vidéo */
-.post-card-media {
- width: 72px;
- height: 72px;
- border-radius: 10px;
+.post-card-media{
+ width:72px;
+ height:72px;
+ border-radius:10px;
background: radial-gradient(circle at 30% 30%, #4a9dff, #07152b);
- display: flex;
- align-items: center;
- justify-content: center;
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ flex-shrink:0;
}
-
-.post-card-media-label {
- font-size: 9px;
- text-align: center;
- color: #e8f5ff;
+.post-card-media-label{
+ font-size:9px;
+ text-align:center;
+ color:#e8f5ff;
}
+.post-card-info{ flex:1; min-width:0; }
+.post-card-title{ font-size:13px; font-weight:600; margin-bottom:2px; }
+.post-card-meta{ font-size:10px; color:#9eb7ff; margin-bottom:4px; }
+.post-card-body{ font-size:11px; color:#c7e3ff; max-height:70px; overflow:hidden; }
-/* texte principal */
-.post-card-info {
- flex: 1;
+/* footer */
+.post-card-footer{
+ display:flex;
+ gap:6px;
+ margin-bottom:6px;
+ flex-wrap:wrap;
}
-
-.post-card-title {
- font-size: 13px;
- font-weight: 600;
- margin-bottom: 2px;
-}
-
-.post-card-meta {
- font-size: 10px;
- color: #9eb7ff;
- margin-bottom: 4px;
-}
-
-.post-card-body {
- font-size: 11px;
- color: #c7e3ff;
- max-height: 70px;
- overflow: hidden;
-}
-
-/* footer boutons */
-.post-card-footer {
- display: flex;
- gap: 6px;
- margin-bottom: 6px;
-}
-
-.post-card-btn {
- border: none;
- border-radius: 999px;
- padding: 3px 8px;
- font-size: 10px;
+.post-card-btn{
+ border:none;
+ border-radius:999px;
+ padding:3px 8px;
+ font-size:10px;
background: rgba(5, 35, 70, 0.95);
- color: #e8f5ff;
- cursor: pointer;
+ color:#e8f5ff;
+ cursor:pointer;
}
-
-/* zone commentaires */
-.post-card-comments {
- font-size: 10px;
- color: #9eb7ff;
- padding: 4px 6px;
- border-radius: 8px;
+.post-card-comments{
+ font-size:10px;
+ color:#9eb7ff;
+ padding:4px 6px;
+ border-radius:8px;
background: rgba(3, 14, 32, 0.95);
}
-
-/* Pointe sous le gros post */
-.post-card-pointer {
- width: 0;
- height: 0;
- margin-top: 3px;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-top: 11px solid rgba(8, 20, 40, 0.97);
- filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8));
-}