update frontend
This commit is contained in:
parent
f6957f347f
commit
666ca2bc1d
|
|
@ -1,39 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
function getKmFromPost(post) {
|
|
||||||
return (
|
|
||||||
post.km ??
|
|
||||||
post.distance_km ??
|
|
||||||
post.distanceKm ??
|
|
||||||
post.dist_km ??
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function PostCard({ post, selected, onSelect }) {
|
|
||||||
const title = post.title || post.name || "Post";
|
|
||||||
|
|
||||||
const fullBody =
|
|
||||||
post.body || post.content || post.text || "";
|
|
||||||
|
|
||||||
// texte court dans le Sociowall
|
|
||||||
const body =
|
|
||||||
fullBody.length > 80 ? fullBody.slice(0, 77) + "..." : fullBody;
|
|
||||||
|
|
||||||
const km = getKmFromPost(post);
|
|
||||||
|
|
||||||
function handleClick() {
|
|
||||||
if (onSelect) onSelect(post);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<article
|
|
||||||
className={"post-card" + (selected ? " selected" : "")}
|
|
||||||
onClick={handleClick}
|
|
||||||
>
|
|
||||||
<h3>{title}</h3>
|
|
||||||
<p>{body}</p>
|
|
||||||
{km != null && <span className="post-km">{km} km</span>}
|
|
||||||
</article>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
import React, { useState, useMemo } from "react";
|
|
||||||
import PostCard from "./PostCard";
|
|
||||||
|
|
||||||
function getKmFromPost(post) {
|
|
||||||
return (
|
|
||||||
post.km ??
|
|
||||||
post.distance_km ??
|
|
||||||
post.distanceKm ??
|
|
||||||
post.dist_km ??
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function PostList({
|
|
||||||
posts,
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
selectedPost,
|
|
||||||
onSelectPost,
|
|
||||||
}) {
|
|
||||||
const [kmFilter, setKmFilter] = useState(1000);
|
|
||||||
|
|
||||||
const filtered = useMemo(
|
|
||||||
() =>
|
|
||||||
posts.filter((p) => {
|
|
||||||
const km = getKmFromPost(p);
|
|
||||||
if (km == null) return true;
|
|
||||||
return km <= kmFilter;
|
|
||||||
}),
|
|
||||||
[posts, kmFilter]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="post-list">
|
|
||||||
<div className="post-list-header">
|
|
||||||
<div className="km-filter">
|
|
||||||
<label>
|
|
||||||
Rayon : <span>{kmFilter} km</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="range"
|
|
||||||
min={0}
|
|
||||||
max={1000}
|
|
||||||
value={kmFilter}
|
|
||||||
onChange={(e) => setKmFilter(Number(e.target.value))}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{loading && <p className="status-text">Chargement...</p>}
|
|
||||||
{error && <p className="status-text status-error">{error}</p>}
|
|
||||||
|
|
||||||
{filtered.map((p) => (
|
|
||||||
<PostCard
|
|
||||||
key={p.id ?? p._id}
|
|
||||||
post={p}
|
|
||||||
selected={selectedPost && (selectedPost.id ?? selectedPost._id) === (p.id ?? p._id)}
|
|
||||||
onSelect={onSelectPost}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{!loading && filtered.length === 0 && (
|
|
||||||
<p className="status-text">Aucun post dans ce rayon.</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
import React, { useEffect, useMemo, useState } from "react";
|
|
||||||
import { fetchPosts } from "../../api/client";
|
|
||||||
|
|
||||||
function useHashParams() {
|
|
||||||
const [hash, setHash] = useState(window.location.hash || "");
|
|
||||||
useEffect(() => {
|
|
||||||
const onHash = () => setHash(window.location.hash || "");
|
|
||||||
window.addEventListener("hashchange", onHash);
|
|
||||||
return () => window.removeEventListener("hashchange", onHash);
|
|
||||||
}, []);
|
|
||||||
const q = new URLSearchParams(hash.replace(/^#wall\??/, ""));
|
|
||||||
return { hash, params: q };
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function WallPage() {
|
|
||||||
const { params } = useHashParams();
|
|
||||||
const [posts, setPosts] = useState([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
|
|
||||||
const filters = useMemo(() => {
|
|
||||||
const f = {};
|
|
||||||
if (params.get("category")) f.category = params.get("category");
|
|
||||||
if (params.get("sub")) f.subCategory = params.get("sub");
|
|
||||||
if (params.get("time")) f.time = params.get("time");
|
|
||||||
if (params.get("lat")) f.lat = Number(params.get("lat"));
|
|
||||||
if (params.get("lon")) f.lon = Number(params.get("lon"));
|
|
||||||
if (params.get("r")) f.radiusKm = Number(params.get("r"));
|
|
||||||
return f;
|
|
||||||
}, [params]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let off = false;
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
const data = await fetchPosts(filters);
|
|
||||||
if (!off) setPosts(Array.isArray(data) ? data : []);
|
|
||||||
} finally {
|
|
||||||
if (!off) setLoading(false);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
return () => {
|
|
||||||
off = true;
|
|
||||||
};
|
|
||||||
}, [filters]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="wall-page">
|
|
||||||
<div className="wall-header">
|
|
||||||
<button className="wall-back" onClick={() => (window.location.hash = "")}>
|
|
||||||
← Back to map
|
|
||||||
</button>
|
|
||||||
<div className="wall-title">SOCIOWALL — full view</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="wall-content">
|
|
||||||
{loading && <div>Loading…</div>}
|
|
||||||
{!loading && posts.length === 0 && <div>No posts with these filters.</div>}
|
|
||||||
{posts.map((p) => (
|
|
||||||
<article key={p.id ?? p._id} className="wall-post">
|
|
||||||
<h3>{p.title || "Post"}</h3>
|
|
||||||
<p>{p.snippet || p.body || p.text || ""}</p>
|
|
||||||
</article>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue