update frontend
This commit is contained in:
parent
0989edbd09
commit
0dad16e338
|
|
@ -17,11 +17,7 @@ import TimeFilterButtons from "../Filters/TimeFilterButtons";
|
||||||
|
|
||||||
export default function MapView({
|
export default function MapView({
|
||||||
theme = "dark",
|
theme = "dark",
|
||||||
|
|
||||||
// lift posts to App (so Sociowall is NOT inside the map)
|
|
||||||
onPostsState,
|
onPostsState,
|
||||||
|
|
||||||
// selection controlled by App
|
|
||||||
selectedPost,
|
selectedPost,
|
||||||
onSelectPost,
|
onSelectPost,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -79,7 +75,6 @@ export default function MapView({
|
||||||
|
|
||||||
const bottomCategories = FILTER_CATEGORY_MAP[mainFilter] || ["All"];
|
const bottomCategories = FILTER_CATEGORY_MAP[mainFilter] || ["All"];
|
||||||
|
|
||||||
/* SW_SUBCAT_ICONS:BEGIN */
|
|
||||||
const getSubcatIcon = (main, sub) => {
|
const getSubcatIcon = (main, sub) => {
|
||||||
const M = {
|
const M = {
|
||||||
All: {
|
All: {
|
||||||
|
|
@ -125,15 +120,12 @@ export default function MapView({
|
||||||
|
|
||||||
return (M[main] && M[main][sub]) || "";
|
return (M[main] && M[main][sub]) || "";
|
||||||
};
|
};
|
||||||
/* SW_SUBCAT_ICONS:END */
|
|
||||||
|
|
||||||
// keep subFilter valid
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!bottomCategories.length) return;
|
if (!bottomCategories.length) return;
|
||||||
if (!subFilter || !bottomCategories.includes(subFilter)) setSubFilter("All");
|
if (!subFilter || !bottomCategories.includes(subFilter)) setSubFilter("All");
|
||||||
}, [mainFilter, bottomCategories, subFilter]);
|
}, [mainFilter, bottomCategories, subFilter]);
|
||||||
|
|
||||||
// push posts state up to App (for Sociowall)
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!onPostsState) return;
|
if (!onPostsState) return;
|
||||||
onPostsState({
|
onPostsState({
|
||||||
|
|
@ -144,7 +136,6 @@ export default function MapView({
|
||||||
});
|
});
|
||||||
}, [status, visiblePosts, loadingPosts, loadError, onPostsState]);
|
}, [status, visiblePosts, loadingPosts, loadError, onPostsState]);
|
||||||
|
|
||||||
// if App selects a post (from Sociowall), fly to it on map
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedPost) return;
|
if (!selectedPost) return;
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
|
|
@ -158,7 +149,6 @@ export default function MapView({
|
||||||
}
|
}
|
||||||
}, [selectedPost, mapRef]);
|
}, [selectedPost, mapRef]);
|
||||||
|
|
||||||
// Hide subcats when map isn't visible enough (keeps UI clean)
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const el = stageRef.current;
|
const el = stageRef.current;
|
||||||
if (!el || typeof IntersectionObserver === "undefined") return;
|
if (!el || typeof IntersectionObserver === "undefined") return;
|
||||||
|
|
@ -176,7 +166,6 @@ export default function MapView({
|
||||||
return () => obs.disconnect();
|
return () => obs.disconnect();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Websocket for new posts
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const proto = window.location.protocol === "https:" ? "wss" : "ws";
|
const proto = window.location.protocol === "https:" ? "wss" : "ws";
|
||||||
const host =
|
const host =
|
||||||
|
|
@ -231,7 +220,6 @@ export default function MapView({
|
||||||
setDraftCoords(null);
|
setDraftCoords(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keep submit to allow Enter key, but no popup:
|
|
||||||
const handleSearchSubmit = (e) => {
|
const handleSearchSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
@ -271,7 +259,6 @@ export default function MapView({
|
||||||
baseLat = center.lat;
|
baseLat = center.lat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep marker visually above pointer
|
|
||||||
const pixelOffsetY = -20;
|
const pixelOffsetY = -20;
|
||||||
const screenPoint = map.project([baseLng, baseLat]);
|
const screenPoint = map.project([baseLng, baseLat]);
|
||||||
const correctedPoint = { x: screenPoint.x, y: screenPoint.y + pixelOffsetY };
|
const correctedPoint = { x: screenPoint.x, y: screenPoint.y + pixelOffsetY };
|
||||||
|
|
@ -327,7 +314,6 @@ export default function MapView({
|
||||||
setMainFilter(code);
|
setMainFilter(code);
|
||||||
};
|
};
|
||||||
|
|
||||||
// allow selecting from map later (optional hook)
|
|
||||||
const handleSelectPost = (post) => {
|
const handleSelectPost = (post) => {
|
||||||
if (onSelectPost) onSelectPost(post);
|
if (onSelectPost) onSelectPost(post);
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
|
|
@ -345,10 +331,10 @@ export default function MapView({
|
||||||
<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 OVERLAY: Search + 2 boutons === */}
|
{/* TOP: Search à gauche, 2 icônes à droite */}
|
||||||
<div className="map-overlay map-overlay-top">
|
<div className="map-overlay map-overlay-top sw-top-row">
|
||||||
<form
|
<form
|
||||||
className="sw-searchbar"
|
className="sw-searchbar sw-top-search"
|
||||||
onSubmit={handleSearchSubmit}
|
onSubmit={handleSearchSubmit}
|
||||||
role="search"
|
role="search"
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
|
|
@ -377,22 +363,28 @@ export default function MapView({
|
||||||
) : null}
|
) : null}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div className="map-top-buttons">
|
<div className="map-top-actions">
|
||||||
<button
|
<button
|
||||||
className="chip-pill"
|
|
||||||
type="button"
|
type="button"
|
||||||
|
className="map-action-btn"
|
||||||
onClick={handleFlyToMe}
|
onClick={handleFlyToMe}
|
||||||
disabled={!userPosition}
|
disabled={!userPosition}
|
||||||
>
|
>
|
||||||
My spot
|
<div className="map-action-icon">
|
||||||
|
<i className="fa-solid fa-location-crosshairs" />
|
||||||
|
</div>
|
||||||
|
<div className="map-action-label">My spot</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="chip-pill"
|
|
||||||
type="button"
|
type="button"
|
||||||
|
className="map-action-btn"
|
||||||
onClick={handleOpenCreate}
|
onClick={handleOpenCreate}
|
||||||
>
|
>
|
||||||
Place your wire
|
<div className="map-action-icon">
|
||||||
|
<i className="fa-solid fa-bolt" />
|
||||||
|
</div>
|
||||||
|
<div className="map-action-label">New wire</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -426,8 +418,6 @@ export default function MapView({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* On n'a plus besoin du bouton My spot séparé en bas, il est en haut maintenant */}
|
|
||||||
|
|
||||||
{isCreating && (
|
{isCreating && (
|
||||||
<div className="map-overlay map-crosshair">
|
<div className="map-overlay map-crosshair">
|
||||||
<div className="crosshair-aim" />
|
<div className="crosshair-aim" />
|
||||||
|
|
|
||||||
|
|
@ -173,3 +173,59 @@ body[data-theme="light"] .sw-search-clear{
|
||||||
align-items:center;
|
align-items:center;
|
||||||
justify-content:center;
|
justify-content:center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ==== TOP ROW: search + 2 icônes actions ===== */
|
||||||
|
|
||||||
|
.sw-top-row{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:space-between;
|
||||||
|
gap:0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* la search prend tout l'espace dispo à gauche */
|
||||||
|
.sw-top-search{
|
||||||
|
flex:1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bloc des 2 boutons icônes à droite */
|
||||||
|
.map-top-actions{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
align-items:center;
|
||||||
|
gap:0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bouton icône: rond + label en dessous */
|
||||||
|
.map-action-btn{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
padding:0.25rem 0.45rem;
|
||||||
|
border-radius:0.9rem;
|
||||||
|
border:1px solid rgba(255,255,255,0.08);
|
||||||
|
background:rgba(8,8,16,0.9);
|
||||||
|
backdrop-filter:blur(14px);
|
||||||
|
box-shadow:0 8px 22px rgba(0,0,0,0.55);
|
||||||
|
font-size:0.7rem;
|
||||||
|
line-height:1.1;
|
||||||
|
cursor:pointer;
|
||||||
|
white-space:nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-action-btn:disabled{
|
||||||
|
opacity:0.45;
|
||||||
|
cursor:default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-action-icon{
|
||||||
|
font-size:1.05rem;
|
||||||
|
margin-bottom:0.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-action-label{
|
||||||
|
font-size:0.6rem;
|
||||||
|
text-transform:uppercase;
|
||||||
|
letter-spacing:0.04em;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue