sw-fe/src/api/client.js

136 lines
3.3 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.error("fetchPosts failed", res.status);
throw new Error("Failed to load posts");
}
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(() => ({}));
}