Auto deploy: 2025-12-09 03:26:48
This commit is contained in:
parent
174f3784e3
commit
71368d4a5e
|
|
@ -7,7 +7,7 @@ const API_BASE = "/api";
|
||||||
/**
|
/**
|
||||||
* Récupère la liste des posts avec filtres.
|
* Récupère la liste des posts avec filtres.
|
||||||
* filters: {
|
* filters: {
|
||||||
* category?: "NEWS" | "FRIENDS" | "EVENTS" | "MARKET"
|
* category?: "NEWS" | "FRIENDS" | "EVENT" | "MARKET"
|
||||||
* subCategory?: string
|
* subCategory?: string
|
||||||
* time?: "NOW" | "TODAY" | "RECENT" | "PAST"
|
* time?: "NOW" | "TODAY" | "RECENT" | "PAST"
|
||||||
* lat?: number
|
* lat?: number
|
||||||
|
|
@ -94,6 +94,7 @@ export async function fetchIpLocation() {
|
||||||
/**
|
/**
|
||||||
* Crée un nouveau post
|
* Crée un nouveau post
|
||||||
* Backend: POST /api/post (postCreateHandler)
|
* Backend: POST /api/post (postCreateHandler)
|
||||||
|
* Attend: { title, snippet, category, sub_category, lat, lon, author }
|
||||||
*/
|
*/
|
||||||
export async function createPost(payload) {
|
export async function createPost(payload) {
|
||||||
const res = await fetch(`${API_BASE}/post`, {
|
const res = await fetch(`${API_BASE}/post`, {
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ import maplibregl from "maplibre-gl";
|
||||||
import "maplibre-gl/dist/maplibre-gl.css";
|
import "maplibre-gl/dist/maplibre-gl.css";
|
||||||
import { fetchPosts, fetchIpLocation, createPost } from "../../api/client";
|
import { fetchPosts, fetchIpLocation, createPost } from "../../api/client";
|
||||||
|
|
||||||
/* ------------ UTILS -------------- */
|
/* ------------ CONSTANTES LOCALSTORAGE -------------- */
|
||||||
const LAST_POS_KEY = "sociowire:lastPosition"; // position utilisateur (GPS/IP)
|
const LAST_POS_KEY = "sociowire:lastPosition"; // position utilisateur (GPS/IP)
|
||||||
const LAST_VIEW_KEY = "sociowire:lastView"; // dernière vue carte (centre+zoom)
|
const LAST_VIEW_KEY = "sociowire:lastView"; // dernière vue carte (centre+zoom)
|
||||||
|
|
||||||
|
/* ------------ UTILS -------------- */
|
||||||
|
|
||||||
// petite haversine pour estimer le rayon en km en fonction du zoom
|
// petite haversine pour estimer le rayon en km en fonction du zoom
|
||||||
function haversineKm(lat1, lon1, lat2, lon2) {
|
function haversineKm(lat1, lon1, lat2, lon2) {
|
||||||
const R = 6371;
|
const R = 6371;
|
||||||
|
|
@ -84,15 +86,17 @@ function categoryCode(mainFilter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------ CATEGORIES -------------- */
|
/* ------------ CATEGORIES POUR LES CHIPS -------------- */
|
||||||
const CATEGORY_MAP = {
|
const CATEGORY_MAP = {
|
||||||
News: ["World", "Politics", "Tech", "Finance", "Local"],
|
News: ["World", "Politics", "Tech", "Finance", "Local"],
|
||||||
Friends: ["Nearby", "Chats", "Groups", "Stories", "Favs"],
|
Friends: ["Nearby", "Chats", "Groups", "Stories", "Favs"],
|
||||||
Events: ["Today", "Weekend", "Music", "Sports", "Local"],
|
Events: ["Today", "Weekend", "Music", "Sports", "Local"],
|
||||||
Market: ["Actu", "Tech", "Finan", "Sport", "Deals"],
|
Market: ["Actu", "Tech", "Finan", "Sport", "Deals"],
|
||||||
Default: ["World", "Actu", "Tech", "Finan", "Sport"],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* =====================================================
|
||||||
|
COMPONENT
|
||||||
|
===================================================== */
|
||||||
export default function MapView() {
|
export default function MapView() {
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
const mapRef = useRef(null);
|
const mapRef = useRef(null);
|
||||||
|
|
@ -101,7 +105,7 @@ export default function MapView() {
|
||||||
|
|
||||||
const [status, setStatus] = useState("Loading posts...");
|
const [status, setStatus] = useState("Loading posts...");
|
||||||
|
|
||||||
const [mainFilter, setMainFilter] = useState("Default"); // News/Friends/Events/Market
|
const [mainFilter, setMainFilter] = useState("News"); // News/Friends/Events/Market
|
||||||
const [timeFilter, setTimeFilter] = useState("RECENT"); // NOW/TODAY/RECENT/PAST
|
const [timeFilter, setTimeFilter] = useState("RECENT"); // NOW/TODAY/RECENT/PAST
|
||||||
const [subFilter, setSubFilter] = useState(null); // sous-catégorie du bas
|
const [subFilter, setSubFilter] = useState(null); // sous-catégorie du bas
|
||||||
|
|
||||||
|
|
@ -127,13 +131,33 @@ export default function MapView() {
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
const [saveError, setSaveError] = useState("");
|
const [saveError, setSaveError] = useState("");
|
||||||
|
|
||||||
/* ------------ INIT MAP -------------- */
|
/* ------------ INIT MAP (THEME BLEU NUIT + LAST VIEW) -------------- */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!containerRef.current) return;
|
if (!containerRef.current) return;
|
||||||
|
|
||||||
const map = new maplibregl.Map({
|
const map = new maplibregl.Map({
|
||||||
container: containerRef.current,
|
container: containerRef.current,
|
||||||
style: "https://demotiles.maplibre.org/style.json",
|
// Thème nuit bleu CARTO + villes
|
||||||
|
style: {
|
||||||
|
version: 8,
|
||||||
|
sources: {
|
||||||
|
"carto-dark": {
|
||||||
|
type: "raster",
|
||||||
|
tiles: [
|
||||||
|
"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
||||||
|
],
|
||||||
|
tileSize: 256,
|
||||||
|
attribution: "© OpenStreetMap contributors © CARTO",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layers: [
|
||||||
|
{
|
||||||
|
id: "carto-dark-layer",
|
||||||
|
type: "raster",
|
||||||
|
source: "carto-dark",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
center: [-95, 40],
|
center: [-95, 40],
|
||||||
zoom: 3.5,
|
zoom: 3.5,
|
||||||
pitch: 45,
|
pitch: 45,
|
||||||
|
|
@ -274,8 +298,7 @@ export default function MapView() {
|
||||||
}, [hasLastView]);
|
}, [hasLastView]);
|
||||||
|
|
||||||
/* ------------ SOUS-CATEGORIES (bas) -------------- */
|
/* ------------ SOUS-CATEGORIES (bas) -------------- */
|
||||||
const bottomCategories =
|
const bottomCategories = CATEGORY_MAP[mainFilter] || [];
|
||||||
CATEGORY_MAP[mainFilter] || CATEGORY_MAP.Default;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!bottomCategories.length) return;
|
if (!bottomCategories.length) return;
|
||||||
|
|
@ -475,9 +498,9 @@ export default function MapView() {
|
||||||
setDraftTitle("");
|
setDraftTitle("");
|
||||||
setDraftBody("");
|
setDraftBody("");
|
||||||
|
|
||||||
const main = mainFilter === "Default" ? "News" : mainFilter;
|
const main = mainFilter || "News";
|
||||||
setDraftCategory(main);
|
setDraftCategory(main);
|
||||||
const list = CATEGORY_MAP[main] || CATEGORY_MAP.Default;
|
const list = CATEGORY_MAP[main] || CATEGORY_MAP.News;
|
||||||
setDraftSubCategory(list[0]);
|
setDraftSubCategory(list[0]);
|
||||||
setDraftCoords(null);
|
setDraftCoords(null);
|
||||||
};
|
};
|
||||||
|
|
@ -651,7 +674,7 @@ export default function MapView() {
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const cat = e.target.value;
|
const cat = e.target.value;
|
||||||
setDraftCategory(cat);
|
setDraftCategory(cat);
|
||||||
const list = CATEGORY_MAP[cat] || CATEGORY_MAP.Default;
|
const list = CATEGORY_MAP[cat] || CATEGORY_MAP.News;
|
||||||
setDraftSubCategory(list[0]);
|
setDraftSubCategory(list[0]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -666,7 +689,7 @@ export default function MapView() {
|
||||||
value={draftSubCategory}
|
value={draftSubCategory}
|
||||||
onChange={(e) => setDraftSubCategory(e.target.value)}
|
onChange={(e) => setDraftSubCategory(e.target.value)}
|
||||||
>
|
>
|
||||||
{(CATEGORY_MAP[draftCategory] || CATEGORY_MAP.Default).map(
|
{(CATEGORY_MAP[draftCategory] || CATEGORY_MAP.News).map(
|
||||||
(sub) => (
|
(sub) => (
|
||||||
<option key={sub} value={sub}>
|
<option key={sub} value={sub}>
|
||||||
{sub}
|
{sub}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue