136 lines
3.2 KiB
JavaScript
136 lines
3.2 KiB
JavaScript
/**
|
|
* SocioWire frontend API client
|
|
*/
|
|
|
|
const API_BASE = "/api";
|
|
|
|
/**
|
|
* Récupère la liste des posts, avec filtres optionnels.
|
|
*/
|
|
export async function fetchPosts(filters = {}) {
|
|
const params = new URLSearchParams();
|
|
|
|
if (filters.category) params.set("category", filters.category);
|
|
if (filters.subCategory) params.set("sub_category", filters.subCategory);
|
|
if (filters.time) params.set("time", filters.time);
|
|
if (typeof filters.lat === "number") params.set("lat", String(filters.lat));
|
|
if (typeof filters.lon === "number") params.set("lon", String(filters.lon));
|
|
if (typeof filters.radiusKm === "number") {
|
|
params.set("radius_km", String(filters.radiusKm));
|
|
}
|
|
|
|
const qs = params.toString();
|
|
const url = qs ? `${API_BASE}/posts?${qs}` : `${API_BASE}/posts`;
|
|
|
|
const res = await fetch(url, {
|
|
credentials: "include",
|
|
});
|
|
|
|
if (!res.ok) {
|
|
console.warn("fetchPosts failed (treated as empty)", res.status);
|
|
return [];
|
|
}
|
|
|
|
const data = await res.json();
|
|
return Array.isArray(data) ? data : data.items || [];
|
|
}
|
|
|
|
/**
|
|
* Récupère la position approx de l'utilisateur depuis le backend.
|
|
*/
|
|
export async function fetchIpLocation() {
|
|
try {
|
|
const res = await fetch(`${API_BASE}/ip-location`, {
|
|
credentials: "include",
|
|
});
|
|
|
|
if (!res.ok) {
|
|
console.warn("fetchIpLocation: HTTP", res.status);
|
|
return null;
|
|
}
|
|
|
|
const text = await res.text();
|
|
if (!text || text === "null") {
|
|
return null;
|
|
}
|
|
|
|
let data;
|
|
try {
|
|
data = JSON.parse(text);
|
|
} catch (e) {
|
|
console.warn("fetchIpLocation: JSON parse error", e, text);
|
|
return null;
|
|
}
|
|
|
|
const lat = data.lat;
|
|
const lon = data.lon;
|
|
|
|
if (
|
|
typeof lat === "number" &&
|
|
typeof lon === "number" &&
|
|
!Number.isNaN(lat) &&
|
|
!Number.isNaN(lon)
|
|
) {
|
|
return [lon, lat]; // [lng, lat]
|
|
}
|
|
|
|
console.warn("fetchIpLocation: invalid payload", data);
|
|
return null;
|
|
} catch (err) {
|
|
console.warn("fetchIpLocation: network error", err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Crée un nouveau post
|
|
* token: access token Keycloak (string) ou null
|
|
*/
|
|
export async function createPost(payload, token) {
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
};
|
|
if (token) {
|
|
headers["Authorization"] = `Bearer ${token}`;
|
|
}
|
|
|
|
const res = await fetch(`${API_BASE}/post`, {
|
|
method: "POST",
|
|
headers,
|
|
credentials: "include",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => "");
|
|
console.error("createPost failed", res.status, text);
|
|
throw new Error("Failed to create post");
|
|
}
|
|
|
|
return res.json().catch(() => ({}));
|
|
}
|
|
|
|
/**
|
|
* Crée un nouvel utilisateur via le backend
|
|
* (backend: POST /api/signup)
|
|
* payload: { username, email, password, firstName, lastName }
|
|
*/
|
|
export async function registerUser(payload) {
|
|
const res = await fetch(`${API_BASE}/signup`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
credentials: "include",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => "");
|
|
console.error("registerUser failed", res.status, text);
|
|
throw new Error(text || "Failed to register user");
|
|
}
|
|
|
|
return res.json().catch(() => ({}));
|
|
}
|