update frontend
This commit is contained in:
parent
253346cedc
commit
e0a8e68f33
|
|
@ -20,6 +20,7 @@ import {
|
|||
matchesTimeFilter,
|
||||
} from "./mapFilter";
|
||||
import { createMarkerForPost, clearAllMarkers } from "./markerManager";
|
||||
import PostList from "../Posts/PostList";
|
||||
|
||||
export default function MapView() {
|
||||
const containerRef = useRef(null);
|
||||
|
|
@ -64,6 +65,12 @@ export default function MapView() {
|
|||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [saveError, setSaveError] = useState("");
|
||||
|
||||
// SOCIOWALL
|
||||
const [visiblePosts, setVisiblePosts] = useState([]);
|
||||
const [selectedPost, setSelectedPost] = useState(null);
|
||||
const [loadingPosts, setLoadingPosts] = useState(false);
|
||||
const [loadError, setLoadError] = useState("");
|
||||
|
||||
/* ================= INIT MAP ================= */
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -258,6 +265,7 @@ export default function MapView() {
|
|||
createMarkerForPost(post, mapRef, markersRef, expandedElRef);
|
||||
});
|
||||
|
||||
setVisiblePosts(visible);
|
||||
setStatus(visible.length ? "" : "No posts found.");
|
||||
};
|
||||
|
||||
|
|
@ -289,6 +297,8 @@ export default function MapView() {
|
|||
|
||||
try {
|
||||
setStatus("Loading posts...");
|
||||
setLoadingPosts(true);
|
||||
setLoadError("");
|
||||
|
||||
const catCode = categoryCode(mainFilter);
|
||||
const subCatParam =
|
||||
|
|
@ -333,9 +343,14 @@ export default function MapView() {
|
|||
};
|
||||
|
||||
rebuildMarkersForTimeFilter(timeFilter);
|
||||
setLoadingPosts(false);
|
||||
} catch (err) {
|
||||
console.error("Erreur chargement posts:", err);
|
||||
if (!cancelled) setStatus("Error loading posts.");
|
||||
if (!cancelled) {
|
||||
setStatus("Error loading posts.");
|
||||
setLoadError("Error loading posts.");
|
||||
setLoadingPosts(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,6 +417,7 @@ export default function MapView() {
|
|||
allPostsRef.current = [...allPostsRef.current, p];
|
||||
|
||||
createMarkerForPost(p, mapRef, markersRef, expandedElRef);
|
||||
setVisiblePosts((current) => [...current, p]);
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
|
|
@ -505,6 +521,41 @@ export default function MapView() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleSelectPost = (post) => {
|
||||
setSelectedPost(post);
|
||||
const map = mapRef.current;
|
||||
if (!map) return;
|
||||
|
||||
const lng =
|
||||
post.lon ??
|
||||
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 (
|
||||
|
|
@ -529,7 +580,7 @@ export default function MapView() {
|
|||
{/* LEFT — time filters */}
|
||||
<div className="map-overlay map-overlay-left">
|
||||
{[
|
||||
["NOW", "Live"],
|
||||
["NOW", "Now"],
|
||||
["TODAY", "Today"],
|
||||
["RECENT", "Recently"],
|
||||
["PAST", "Past"],
|
||||
|
|
@ -675,6 +726,28 @@ export default function MapView() {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* SOCIOWALL + CHAT EN BAS */}
|
||||
<div className="map-overlay map-overlay-wall">
|
||||
<div className="sociowall-panel">
|
||||
<div className="sociowall-header">Sociowall</div>
|
||||
<PostList
|
||||
posts={visiblePosts}
|
||||
loading={loadingPosts}
|
||||
error={loadError}
|
||||
selectedPost={selectedPost}
|
||||
onSelectPost={handleSelectPost}
|
||||
/>
|
||||
</div>
|
||||
<div className="chat-panel">
|
||||
<div className="chat-header">Chat</div>
|
||||
<ul className="chat-users">
|
||||
<li>Yan</li>
|
||||
<li>Marc</li>
|
||||
<li>Fiso</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import "./styles/map.css";
|
|||
import "./styles/markers.css";
|
||||
import "./styles/popup.css";
|
||||
import "./styles/overlays.css";
|
||||
import "./styles/posts.css";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
/* ==========================================
|
||||
SOCIOWALL + CHAT (bas de l'écran)
|
||||
========================================== */
|
||||
|
||||
.map-overlay-wall {
|
||||
position: absolute;
|
||||
left: 0.7rem;
|
||||
right: 0.7rem;
|
||||
bottom: 0.7rem;
|
||||
display: flex;
|
||||
gap: 0.6rem;
|
||||
align-items: stretch;
|
||||
pointer-events: none;
|
||||
z-index: 25;
|
||||
}
|
||||
|
||||
.map-overlay-wall * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* --------- SOCIOWALL (liste de posts) --------- */
|
||||
|
||||
.sociowall-panel {
|
||||
flex: 1.5;
|
||||
min-height: 120px;
|
||||
max-height: 220px;
|
||||
background: rgba(15, 23, 42, 0.96);
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.9);
|
||||
box-shadow:
|
||||
0 14px 40px rgba(0, 0, 0, 0.9),
|
||||
0 0 22px rgba(56, 189, 248, 0.45);
|
||||
padding: 0.5rem 0.6rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sociowall-header {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
color: #bfdbfe;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
/* --------- LISTE DES POSTS --------- */
|
||||
|
||||
.post-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding-right: 0.2rem;
|
||||
}
|
||||
|
||||
.post-list-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.25rem;
|
||||
font-size: 0.7rem;
|
||||
color: #cbd5f5;
|
||||
}
|
||||
|
||||
.km-filter label {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.km-filter span {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* slider 0–1000 km */
|
||||
.km-filter input[type="range"] {
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
/* texte de statut (chargement / erreur / vide) */
|
||||
.status-text {
|
||||
font-size: 0.72rem;
|
||||
opacity: 0.85;
|
||||
margin: 0.15rem 0;
|
||||
}
|
||||
|
||||
.status-error {
|
||||
color: #fecaca;
|
||||
}
|
||||
|
||||
/* --------- CARTE D’UN POST --------- */
|
||||
|
||||
.post-card {
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(55, 65, 81, 0.9);
|
||||
background: rgba(15, 23, 42, 0.92);
|
||||
padding: 0.3rem 0.45rem;
|
||||
margin-bottom: 0.25rem;
|
||||
font-size: 0.76rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s ease, border-color 0.15s ease,
|
||||
box-shadow 0.15s ease, transform 0.1s ease;
|
||||
}
|
||||
|
||||
.post-card:hover {
|
||||
background: rgba(17, 24, 39, 0.95);
|
||||
border-color: rgba(96, 165, 250, 0.9);
|
||||
box-shadow: 0 0 12px rgba(56, 189, 248, 0.4);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.post-card.selected {
|
||||
background: linear-gradient(135deg, #1d4ed8, #0ea5e9);
|
||||
border-color: #bfdbfe;
|
||||
box-shadow:
|
||||
0 0 16px rgba(56, 189, 248, 0.6),
|
||||
0 12px 26px rgba(15, 23, 42, 0.98);
|
||||
}
|
||||
|
||||
.post-card h3 {
|
||||
margin: 0 0 0.15rem 0;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.post-card p {
|
||||
margin: 0;
|
||||
font-size: 0.72rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.post-km {
|
||||
display: inline-block;
|
||||
margin-top: 0.12rem;
|
||||
font-size: 0.68rem;
|
||||
padding: 0.05rem 0.35rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(15, 118, 110, 0.2);
|
||||
border: 1px solid rgba(45, 212, 191, 0.7);
|
||||
color: #a5f3fc;
|
||||
}
|
||||
|
||||
/* --------- PANEL CHAT (à droite) --------- */
|
||||
|
||||
.chat-panel {
|
||||
width: 150px;
|
||||
min-width: 130px;
|
||||
max-height: 220px;
|
||||
background: rgba(15, 23, 42, 0.96);
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.9);
|
||||
box-shadow:
|
||||
0 14px 40px rgba(0, 0, 0, 0.9),
|
||||
0 0 22px rgba(56, 189, 248, 0.45);
|
||||
padding: 0.45rem 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
color: #bfdbfe;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.chat-users {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.chat-users li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
padding: 0.18rem 0.1rem;
|
||||
}
|
||||
|
||||
.chat-users li::before {
|
||||
content: "👤";
|
||||
font-size: 0.72rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
Loading…
Reference in New Issue