add register and see panel
Deploy Nexus Portal to HestiaCP (FTP) / build-and-deploy (push) Successful in 30s
Deploy Nexus Portal to HestiaCP (FTP) / build-and-deploy (push) Successful in 30s
This commit is contained in:
+136
-20
@@ -1,28 +1,67 @@
|
||||
const BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
|
||||
const CUSTOM_API_BASE_URL = import.meta.env.VITE_CUSTOM_API_BASE_URL || '';
|
||||
|
||||
const apiCall = async (url, body = null) => {
|
||||
// Configuration de base pour l'appel réseau
|
||||
// Le moteur de requête unifié et intelligent
|
||||
const apiCall = async (endpoint, param2 = 'GET', param3 = null) => {
|
||||
let method = 'GET';
|
||||
let body = null;
|
||||
|
||||
// DÉTECTION DE SIGNATURE (Le bouclier anti-crash)
|
||||
if (typeof param2 === 'string') {
|
||||
// Cas 1 : On a bien envoyé (URL, "POST", {données})
|
||||
method = param2.toUpperCase();
|
||||
body = param3;
|
||||
} else if (typeof param2 === 'object' && param2 !== null) {
|
||||
// Cas 2 : L'ancienne méthode a envoyé (URL, {données})
|
||||
// On redirige l'objet vers le body, et on force en POST
|
||||
body = param2;
|
||||
method = (typeof param3 === 'string') ? param3.toUpperCase() : 'POST';
|
||||
}
|
||||
|
||||
// 1. Récupération du sésame
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
// 2. Préparation de l'enveloppe
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
};
|
||||
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
// 3. Configuration finale garantie sans objets égarés
|
||||
const options = {
|
||||
method: body ? 'POST' : 'GET', // Devient GET s'il n'y a pas de body (ex: getClientProfile)
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
credentials: 'include', // CRUCIAL : Maintient la session active avec FOSSBilling
|
||||
method: method,
|
||||
headers: headers,
|
||||
credentials: 'include'
|
||||
};
|
||||
|
||||
if (body) {
|
||||
options.body = JSON.stringify(body);
|
||||
}
|
||||
|
||||
const response = await fetch(url, options);
|
||||
const data = await response.json();
|
||||
|
||||
// Interception des erreurs de l'API FOSSBilling
|
||||
if (data.error) throw new Error(data.error.message);
|
||||
|
||||
return data.result;
|
||||
try {
|
||||
const response = await fetch(endpoint, options);
|
||||
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new Error("Accès refusé. Session expirée ou non valide.");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Gestion des erreurs internes de l'API
|
||||
if (data.error) {
|
||||
throw new Error(data.error.message || "Erreur renvoyée par le serveur de facturation.");
|
||||
}
|
||||
|
||||
return data.result || data;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`[API FAIL] ${method} ${endpoint} :`, error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================
|
||||
@@ -32,9 +71,6 @@ const apiCall = async (url, body = null) => {
|
||||
export const loginClient = (email, password) =>
|
||||
apiCall(`${BASE_URL}/api/guest/client/login`, { email, password });
|
||||
|
||||
export const getClientProfile = () =>
|
||||
apiCall(`${BASE_URL}/api/client/profile/get`);
|
||||
|
||||
// Récupère la liste des services/commandes du client
|
||||
export const getClientOrders = () =>
|
||||
apiCall(`${BASE_URL}/api/client/order/get_list`);
|
||||
@@ -47,6 +83,39 @@ export const getOrderService = (order_id) =>
|
||||
export const getProductList = () =>
|
||||
apiCall(`${BASE_URL}/api/guest/product/get_list`);
|
||||
|
||||
// Vide le panier (Action PUBLIQUE : on passe par l'API Guest)
|
||||
export const resetCart = async () => {
|
||||
try {
|
||||
// Changement : api/guest/ au lieu de api/client/
|
||||
const cart = await apiCall(`${BASE_URL}/api/guest/cart/get`, 'GET');
|
||||
|
||||
if (cart && cart.items && cart.items.length > 0) {
|
||||
for (const item of cart.items) {
|
||||
// Changement : api/guest/
|
||||
await apiCall(`${BASE_URL}/api/guest/cart/remove_item`, 'POST', { id: item.id });
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Nettoyage du panier ignoré :", err);
|
||||
}
|
||||
};
|
||||
|
||||
// Ajoute un produit au panier avec ses options étalées à la racine
|
||||
export const addToCart = (productId, period, additionalData = {}) =>
|
||||
apiCall(`${BASE_URL}/api/guest/cart/add_item`, 'POST', {
|
||||
id: productId,
|
||||
period: period,
|
||||
...additionalData // Les 3 petits points "étalent" le contenu de l'objet
|
||||
});
|
||||
|
||||
// Valide le panier (Action PRIVÉE : on reste sur l'API Client pour générer la facture)
|
||||
export const checkoutCart = () =>
|
||||
apiCall(`${BASE_URL}/api/client/cart/checkout`, 'POST');
|
||||
|
||||
// Récupère les informations du client connecté
|
||||
export const getClientProfile = () =>
|
||||
apiCall(`${BASE_URL}/api/client/profile/get`, 'GET');
|
||||
|
||||
// ==========================================
|
||||
// ROUTES PERSONNALISÉES (CUSTOM API)
|
||||
// ==========================================
|
||||
@@ -65,7 +134,7 @@ export const registerUnifiedClient = async (email, username, password, firstName
|
||||
last_name: lastName
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
const data = await response.json();
|
||||
if (data.error) throw new Error(data.error.message);
|
||||
return data.result;
|
||||
@@ -73,4 +142,51 @@ export const registerUnifiedClient = async (email, username, password, firstName
|
||||
console.error("Erreur lors de l'inscription unifiée :", err);
|
||||
throw new Error("Échec de l'inscription. Veuillez réessayer plus tard.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Récupère la liste de toutes les commandes actives du client
|
||||
export const getMyServices = () =>
|
||||
apiCall(`${BASE_URL}/api/client/order/get_list`, 'GET');
|
||||
|
||||
// Récupère les détails secrets d'un service (dont le mot de passe HestiaCP/VPS)
|
||||
export const getServiceDetails = (orderId) =>
|
||||
apiCall(`${BASE_URL}/api/client/order/get`, 'POST', { id: orderId });
|
||||
|
||||
// Récupère les secrets spécifiques du service physique attaché à une commande
|
||||
export const getHostingServiceDetails = (orderId) =>
|
||||
apiCall(`${BASE_URL}/api/client/order/service`, 'POST', { id: orderId });
|
||||
|
||||
// Force la réinitialisation du mot de passe sur le serveur distant (HestiaCP)
|
||||
export const resetHostingPassword = (orderId, newPassword) =>
|
||||
apiCall(`${BASE_URL}/api/client/servicehosting/change_password`, 'POST', {
|
||||
order_id: orderId,
|
||||
password: newPassword,
|
||||
password_confirm: newPassword
|
||||
});
|
||||
|
||||
// Déclenche le sas de connexion SSO via le navigateur (Ne pas utiliser apiCall ici)
|
||||
export const launchSSOGateway = (username, password) => {
|
||||
const form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
|
||||
// Tu peux utiliser ta BASE_URL si elle pointe vers web.gise.be
|
||||
// Sinon, on garde l'URL absolue vers ton API personnalisée
|
||||
form.action = `${CUSTOM_API_BASE_URL}/custom_api/sso.php`;
|
||||
form.target = '_blank';
|
||||
|
||||
const userField = document.createElement('input');
|
||||
userField.type = 'hidden';
|
||||
userField.name = 'user';
|
||||
userField.value = username;
|
||||
form.appendChild(userField);
|
||||
|
||||
const passField = document.createElement('input');
|
||||
passField.type = 'hidden';
|
||||
passField.name = 'password';
|
||||
passField.value = password;
|
||||
form.appendChild(passField);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
document.body.removeChild(form);
|
||||
};
|
||||
Reference in New Issue
Block a user