update frontend

This commit is contained in:
Your Name 2025-12-09 19:33:29 -05:00
parent 253346cedc
commit e0a8e68f33
3 changed files with 260 additions and 2 deletions

View File

@ -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>
);
}

View File

@ -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>

184
src/styles/posts.css Normal file
View File

@ -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 01000 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 DUN 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;
}