update frontend
This commit is contained in:
parent
721e17d3a6
commit
2bbb74de35
|
|
@ -1,7 +1,8 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import "maplibre-gl/dist/maplibre-gl.css";
|
import "maplibre-gl/dist/maplibre-gl.css";
|
||||||
import "../../styles/mapMarkers.css";
|
import "../../styles/mapMarkers.css";
|
||||||
import "../../styles/mapLayout.css";
|
import "../../styles/overlays.css";
|
||||||
|
import "../../styles/posts.css";
|
||||||
|
|
||||||
import { createPost } from "../../api/client";
|
import { createPost } from "../../api/client";
|
||||||
import {
|
import {
|
||||||
|
|
@ -15,7 +16,6 @@ import { usePostsEngine } from "./usePostsEngine";
|
||||||
import PostList from "../Posts/PostList";
|
import PostList from "../Posts/PostList";
|
||||||
|
|
||||||
export default function MapView() {
|
export default function MapView() {
|
||||||
// MAP + refs
|
|
||||||
const {
|
const {
|
||||||
containerRef,
|
containerRef,
|
||||||
mapRef,
|
mapRef,
|
||||||
|
|
@ -25,15 +25,12 @@ export default function MapView() {
|
||||||
hasLastView,
|
hasLastView,
|
||||||
} = useMapCore();
|
} = useMapCore();
|
||||||
|
|
||||||
// FILTRES
|
|
||||||
const [mainFilter, setMainFilter] = useState("All");
|
const [mainFilter, setMainFilter] = useState("All");
|
||||||
const [timeFilter, setTimeFilter] = useState("RECENT");
|
const [timeFilter, setTimeFilter] = useState("RECENT");
|
||||||
const [subFilter, setSubFilter] = useState("All");
|
const [subFilter, setSubFilter] = useState("All");
|
||||||
|
|
||||||
// USER POSITION
|
|
||||||
const userPosition = useUserPosition(mapRef, hasLastView);
|
const userPosition = useUserPosition(mapRef, hasLastView);
|
||||||
|
|
||||||
// POSTS ENGINE (markers + Sociowall)
|
|
||||||
const {
|
const {
|
||||||
status,
|
status,
|
||||||
visiblePosts,
|
visiblePosts,
|
||||||
|
|
@ -50,10 +47,8 @@ export default function MapView() {
|
||||||
expandedElRef,
|
expandedElRef,
|
||||||
});
|
});
|
||||||
|
|
||||||
// SOCIOWALL selection
|
|
||||||
const [selectedPost, setSelectedPost] = useState(null);
|
const [selectedPost, setSelectedPost] = useState(null);
|
||||||
|
|
||||||
// NEW POST (overlay)
|
|
||||||
const [isCreating, setIsCreating] = useState(false);
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
const [draftTitle, setDraftTitle] = useState("");
|
const [draftTitle, setDraftTitle] = useState("");
|
||||||
const [draftBody, setDraftBody] = useState("");
|
const [draftBody, setDraftBody] = useState("");
|
||||||
|
|
@ -65,8 +60,6 @@ export default function MapView() {
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
const [saveError, setSaveError] = useState("");
|
const [saveError, setSaveError] = useState("");
|
||||||
|
|
||||||
/* ================= FILTRES (bas) ================= */
|
|
||||||
|
|
||||||
const bottomCategories = FILTER_CATEGORY_MAP[mainFilter] || ["All"];
|
const bottomCategories = FILTER_CATEGORY_MAP[mainFilter] || ["All"];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -76,59 +69,34 @@ export default function MapView() {
|
||||||
}
|
}
|
||||||
}, [mainFilter, bottomCategories, subFilter]);
|
}, [mainFilter, bottomCategories, subFilter]);
|
||||||
|
|
||||||
/* ================= WEBSOCKET ================= */
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const proto = window.location.protocol === "https:" ? "wss" : "ws";
|
const proto = window.location.protocol === "https:" ? "wss" : "ws";
|
||||||
const host =
|
const host =
|
||||||
window.location.port === "5173"
|
window.location.port === "5173"
|
||||||
? `${window.location.hostname}:8081`
|
? `${window.location.hostname}:8081`
|
||||||
: window.location.host;
|
: window.location.host;
|
||||||
|
|
||||||
const wsUrl = `${proto}://${host}/ws`;
|
const wsUrl = `${proto}://${host}/ws`;
|
||||||
let ws;
|
let ws;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ws = new WebSocket(wsUrl);
|
ws = new WebSocket(wsUrl);
|
||||||
} catch (e) {
|
} catch {
|
||||||
console.warn("WebSocket init error:", e);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.onmessage = (ev) => {
|
ws.onmessage = (ev) => {
|
||||||
try {
|
try {
|
||||||
const msg = JSON.parse(ev.data);
|
const msg = JSON.parse(ev.data);
|
||||||
if (msg.type === "new_post" && msg.post) {
|
if (msg.type === "new_post" && msg.post) {
|
||||||
handleIncomingPost(msg.post);
|
handleIncomingPost(msg.post);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {}
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onerror = (e) => {
|
|
||||||
console.warn("WebSocket error:", e);
|
|
||||||
};
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
||||||
ws.close();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
return () => ws && ws.close();
|
||||||
}, [handleIncomingPost]);
|
}, [handleIncomingPost]);
|
||||||
|
|
||||||
/* ================= ACTIONS UI ================= */
|
|
||||||
|
|
||||||
const handleFlyToMe = () => {
|
const handleFlyToMe = () => {
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map || !userPosition) return;
|
if (!map || !userPosition) return;
|
||||||
map.flyTo({
|
map.flyTo({ center: userPosition, zoom: 9, speed: 1.2 });
|
||||||
center: userPosition,
|
|
||||||
zoom: 9,
|
|
||||||
speed: 1.2,
|
|
||||||
curve: 1.5,
|
|
||||||
essential: true,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePickCenter = () => {
|
const handlePickCenter = () => {
|
||||||
|
|
@ -140,10 +108,8 @@ export default function MapView() {
|
||||||
|
|
||||||
const handleOpenCreate = () => {
|
const handleOpenCreate = () => {
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
setSaveError("");
|
|
||||||
setDraftTitle("");
|
setDraftTitle("");
|
||||||
setDraftBody("");
|
setDraftBody("");
|
||||||
|
|
||||||
const main = mainFilter === "All" ? "News" : mainFilter;
|
const main = mainFilter === "All" ? "News" : mainFilter;
|
||||||
setDraftCategory(main);
|
setDraftCategory(main);
|
||||||
const list = CREATE_CATEGORY_MAP[main] || CREATE_CATEGORY_MAP.News;
|
const list = CREATE_CATEGORY_MAP[main] || CREATE_CATEGORY_MAP.News;
|
||||||
|
|
@ -151,55 +117,37 @@ export default function MapView() {
|
||||||
setDraftCoords(null);
|
setDraftCoords(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSearchClick = () => {
|
||||||
|
alert("🔍 Search feature coming soon!");
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmitPost = async () => {
|
const handleSubmitPost = async () => {
|
||||||
if (isSaving) return;
|
if (isSaving) return;
|
||||||
setSaveError("");
|
setSaveError("");
|
||||||
|
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map) return;
|
if (!map) return;
|
||||||
|
let coords = draftCoords || [map.getCenter().lng, map.getCenter().lat];
|
||||||
let coords = draftCoords;
|
|
||||||
if (!coords) {
|
|
||||||
const center = map.getCenter();
|
|
||||||
coords = [center.lng, center.lat];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!coords) {
|
|
||||||
setSaveError("Position inconnue. Déplace la carte et tap sur la cible.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [lng, lat] = coords;
|
const [lng, lat] = coords;
|
||||||
|
|
||||||
if (!draftTitle.trim()) {
|
if (!draftTitle.trim()) {
|
||||||
setSaveError("Le titre est requis.");
|
setSaveError("Title required.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const categoryUpper =
|
|
||||||
draftCategory && draftCategory.toUpperCase() !== "DEFAULT"
|
|
||||||
? draftCategory.toUpperCase()
|
|
||||||
: "NEWS";
|
|
||||||
|
|
||||||
const payload = {
|
|
||||||
title: draftTitle.trim(),
|
|
||||||
snippet: draftBody.trim() || draftTitle.trim(),
|
|
||||||
category: categoryUpper,
|
|
||||||
sub_category: draftSubCategory || "ALL",
|
|
||||||
lat,
|
|
||||||
lon: lng,
|
|
||||||
author: "tommy",
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
await createPost(payload);
|
await createPost({
|
||||||
|
title: draftTitle.trim(),
|
||||||
|
snippet: draftBody.trim() || draftTitle.trim(),
|
||||||
|
category: draftCategory.toUpperCase(),
|
||||||
|
sub_category: draftSubCategory || "ALL",
|
||||||
|
lat,
|
||||||
|
lon: lng,
|
||||||
|
author: "tommy",
|
||||||
|
});
|
||||||
setIsSaving(false);
|
setIsSaving(false);
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
} catch (e) {
|
} catch {
|
||||||
console.error("createPost error:", e);
|
|
||||||
setIsSaving(false);
|
setIsSaving(false);
|
||||||
setSaveError("Erreur lors de la création du post.");
|
setSaveError("Error creating post.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -207,59 +155,27 @@ export default function MapView() {
|
||||||
setSelectedPost(post);
|
setSelectedPost(post);
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map) return;
|
if (!map) return;
|
||||||
|
const lng = post.lon ?? post.lng;
|
||||||
const lng =
|
const lat = post.lat ?? post.latitude;
|
||||||
post.lon ??
|
if (lng && lat) map.flyTo({ center: [lng, lat], zoom: 8, speed: 1.4 });
|
||||||
post.lng ??
|
|
||||||
(Array.isArray(post.coords) ? post.coords[0] : null);
|
|
||||||
const lat =
|
|
||||||
post.lat ??
|
|
||||||
post.latitude ??
|
|
||||||
(Array.isArray(post.coords) ? post.coords[1] : null);
|
|
||||||
|
|
||||||
if (typeof lng === "number" && typeof lat === "number") {
|
|
||||||
map.flyTo({
|
|
||||||
center: [lng, lat],
|
|
||||||
zoom: Math.max(map.getZoom(), 8),
|
|
||||||
speed: 1.4,
|
|
||||||
curve: 1.6,
|
|
||||||
essential: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ouvre le gros post si on a le marker
|
|
||||||
const markerEntry = markersRef.current.find((m) => m.id === post.id);
|
|
||||||
if (markerEntry && markerEntry.el) {
|
|
||||||
const root = markerEntry.el;
|
|
||||||
const isExpanded = root.classList.contains("post-pin--expanded");
|
|
||||||
if (!isExpanded) {
|
|
||||||
root.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ================= RENDER ================= */
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="map-view">
|
<div className="map-view">
|
||||||
<div ref={containerRef} className="map-container" />
|
<div ref={containerRef} className="map-container" />
|
||||||
{status && <div className="map-status">{status}</div>}
|
{status && <div className="map-status">{status}</div>}
|
||||||
|
|
||||||
{/* TOP */}
|
{/* TOP BAR SIMPLIFIÉE */}
|
||||||
<div className="map-overlay map-overlay-top">
|
<div className="map-overlay map-overlay-top">
|
||||||
<div className="lookat-box">Look at…</div>
|
<button className="chip-pill" onClick={handleSearchClick}>
|
||||||
<div className="wire-title">Place your wire</div>
|
Look at…
|
||||||
<div className="zoom-buttons">
|
</button>
|
||||||
<button className="chip-hex">Zoom In</button>
|
<button className="chip-pill" onClick={handleOpenCreate}>
|
||||||
<button className="chip-hex">Zoom Out</button>
|
Place your wire
|
||||||
<button className="chip-hex">Swall</button>
|
|
||||||
</div>
|
|
||||||
<button className="chip-pill top-newpost" onClick={handleOpenCreate}>
|
|
||||||
New post
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* LEFT — time filters */}
|
{/* LEFT */}
|
||||||
<div className="map-overlay map-overlay-left">
|
<div className="map-overlay map-overlay-left">
|
||||||
{[
|
{[
|
||||||
["NOW", "Now"],
|
["NOW", "Now"],
|
||||||
|
|
@ -279,7 +195,7 @@ export default function MapView() {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* RIGHT — main categories */}
|
{/* RIGHT */}
|
||||||
<div className="map-overlay map-overlay-right">
|
<div className="map-overlay map-overlay-right">
|
||||||
{FILTER_MAIN_CATEGORIES.map((cat) => (
|
{FILTER_MAIN_CATEGORIES.map((cat) => (
|
||||||
<button
|
<button
|
||||||
|
|
@ -294,7 +210,7 @@ export default function MapView() {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* BOTTOM — subcategories */}
|
{/* BOTTOM SUBCATEGORIES */}
|
||||||
<div className="map-overlay map-overlay-bottom">
|
<div className="map-overlay map-overlay-bottom">
|
||||||
{bottomCategories.map((c) => (
|
{bottomCategories.map((c) => (
|
||||||
<button
|
<button
|
||||||
|
|
@ -320,96 +236,66 @@ export default function MapView() {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* CROSSHAIR */}
|
{/* CREATE POST */}
|
||||||
{isCreating && (
|
|
||||||
<div className="map-overlay map-crosshair" onClick={handlePickCenter}>
|
|
||||||
<div className="crosshair-aim" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* CREATE POST PANEL */}
|
|
||||||
{isCreating && (
|
{isCreating && (
|
||||||
<div className="map-overlay create-post-panel">
|
<div className="map-overlay create-post-panel">
|
||||||
<div className="create-post-header">
|
<div className="create-post-header">
|
||||||
<span>Create wire</span>
|
<span>Create wire</span>
|
||||||
<button
|
<button className="create-close" onClick={() => setIsCreating(false)}>
|
||||||
className="create-close"
|
|
||||||
onClick={() => setIsCreating(false)}
|
|
||||||
>
|
|
||||||
✕
|
✕
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<span className="crosshair-label">
|
||||||
<div className="create-row">
|
Move the map, then tap to fix the position.
|
||||||
<span className="crosshair-label">
|
</span>
|
||||||
Déplace la carte sous la cible, puis tap sur la cible pour fixer
|
|
||||||
la position.
|
|
||||||
{draftCoords ? " ✓ Position choisie" : ""}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="create-row">
|
<div className="create-row">
|
||||||
<select
|
<select
|
||||||
value={draftCategory}
|
value={draftCategory}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const cat = e.target.value;
|
const cat = e.target.value;
|
||||||
setDraftCategory(cat);
|
setDraftCategory(cat);
|
||||||
const list =
|
setDraftSubCategory(
|
||||||
CREATE_CATEGORY_MAP[cat] || CREATE_CATEGORY_MAP.News;
|
(CREATE_CATEGORY_MAP[cat] || CREATE_CATEGORY_MAP.News)[0]
|
||||||
setDraftSubCategory(list[0]);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{["News", "Friends", "Events", "Market"].map((cat) => (
|
{["News", "Friends", "Events", "Market"].map((cat) => (
|
||||||
<option key={cat} value={cat}>
|
<option key={cat}>{cat}</option>
|
||||||
{cat}
|
|
||||||
</option>
|
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
value={draftSubCategory}
|
value={draftSubCategory}
|
||||||
onChange={(e) => setDraftSubCategory(e.target.value)}
|
onChange={(e) => setDraftSubCategory(e.target.value)}
|
||||||
>
|
>
|
||||||
{(CREATE_CATEGORY_MAP[draftCategory] ||
|
{(CREATE_CATEGORY_MAP[draftCategory] ||
|
||||||
CREATE_CATEGORY_MAP.News
|
CREATE_CATEGORY_MAP.News).map((sub) => (
|
||||||
).map((sub) => (
|
<option key={sub}>{sub}</option>
|
||||||
<option key={sub} value={sub}>
|
|
||||||
{sub}
|
|
||||||
</option>
|
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
className="create-input"
|
className="create-input"
|
||||||
placeholder="Short title..."
|
placeholder="Short title..."
|
||||||
value={draftTitle}
|
value={draftTitle}
|
||||||
onChange={(e) => setDraftTitle(e.target.value)}
|
onChange={(e) => setDraftTitle(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<textarea
|
<textarea
|
||||||
className="create-textarea"
|
className="create-textarea"
|
||||||
rows={2}
|
rows={2}
|
||||||
placeholder="Add a bit more context (optional)..."
|
placeholder="Context (optional)..."
|
||||||
value={draftBody}
|
value={draftBody}
|
||||||
onChange={(e) => setDraftBody(e.target.value)}
|
onChange={(e) => setDraftBody(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{saveError && <div className="create-error">{saveError}</div>}
|
{saveError && <div className="create-error">{saveError}</div>}
|
||||||
|
|
||||||
<div className="create-actions">
|
<div className="create-actions">
|
||||||
<button
|
<button className="chip-pill" onClick={handleSubmitPost} disabled={isSaving}>
|
||||||
className="chip-pill"
|
|
||||||
onClick={handleSubmitPost}
|
|
||||||
disabled={isSaving}
|
|
||||||
>
|
|
||||||
{isSaving ? "Posting..." : "Post as tommy"}
|
{isSaving ? "Posting..." : "Post as tommy"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* SOCIOWALL + CHAT EN BAS */}
|
{/* SOCIOWALL FIXE + CHAT */}
|
||||||
<div className="map-overlay map-overlay-wall">
|
<div className="map-overlay map-overlay-wall">
|
||||||
<div className="sociowall-panel">
|
<div className="sociowall-panel">
|
||||||
<div className="sociowall-header">Sociowall</div>
|
<div className="sociowall-header">Sociowall</div>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import "./styles/map.css";
|
||||||
import "./styles/markers.css";
|
import "./styles/markers.css";
|
||||||
import "./styles/popup.css";
|
import "./styles/popup.css";
|
||||||
import "./styles/overlays.css";
|
import "./styles/overlays.css";
|
||||||
import "./styles/posts.css";
|
import "./styles/posts.css"; // Sociowall + chat
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/* ==========================================
|
/* ==========================================
|
||||||
SOCIOWIRE — OVERLAY + ARC + CREATE PANEL
|
SOCIOWIRE — OVERLAYS (TOP / LEFT / RIGHT /
|
||||||
|
BOTTOM / MY SPOT / CREATE PANEL)
|
||||||
========================================== */
|
========================================== */
|
||||||
|
|
||||||
.map-overlay {
|
.map-overlay {
|
||||||
|
|
@ -24,12 +25,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.lookat-box {
|
.lookat-box {
|
||||||
padding: 0.35rem 0.9rem;
|
/* maintenant on utilise un bouton chip, cette classe sert juste au texte au centre si besoin */
|
||||||
background: rgba(0, 10, 30, 0.85);
|
|
||||||
border-radius: 999px;
|
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
border: 1px solid rgba(56, 189, 248, 0.5);
|
color: #93c5fd;
|
||||||
color: #dbeafe;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.wire-title {
|
.wire-title {
|
||||||
|
|
@ -38,16 +36,6 @@
|
||||||
color: #93c5fd;
|
color: #93c5fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoom-buttons {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.35rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bouton New post dans la top bar */
|
|
||||||
.top-newpost {
|
|
||||||
margin-left: 0.4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------- LEFT --------- */
|
/* --------- LEFT --------- */
|
||||||
|
|
||||||
.map-overlay-left {
|
.map-overlay-left {
|
||||||
|
|
@ -80,8 +68,7 @@
|
||||||
/* --------- BOTTOM — ARC (INVERSE AUTOUR DU GLOBE) --------- */
|
/* --------- BOTTOM — ARC (INVERSE AUTOUR DU GLOBE) --------- */
|
||||||
|
|
||||||
.map-overlay-bottom {
|
.map-overlay-bottom {
|
||||||
/* on remonte les œufs pour les placer au-dessus du Sociowall */
|
bottom: 3.2rem;
|
||||||
bottom: 5.8rem; /* avant ~3.2rem */
|
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
gap: 0.6rem;
|
gap: 0.6rem;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 10; /* plus bas que les autres overlays */
|
z-index: 10; /* un peu plus bas que les autres overlays */
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-overlay-wall * {
|
.map-overlay-wall * {
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
.sociowall-panel {
|
.sociowall-panel {
|
||||||
flex: 1.5;
|
flex: 1.5;
|
||||||
min-height: 90px;
|
min-height: 90px;
|
||||||
max-height: 150px; /* hauteur bloquée → n’envahit pas la map */
|
max-height: 150px; /* HAUTEUR FIXE → n’envahit pas la map */
|
||||||
background: rgba(15, 23, 42, 0.96);
|
background: rgba(15, 23, 42, 0.96);
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
border: 1px solid rgba(148, 163, 184, 0.9);
|
border: 1px solid rgba(148, 163, 184, 0.9);
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
.post-list {
|
.post-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto; /* c’est ici que ça scrolle */
|
overflow-y: auto; /* c’est ICI que ça scrolle */
|
||||||
padding-right: 0.15rem;
|
padding-right: 0.15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue