+
+ {/* Condition d'affichage : Rétractation J+14 vs Résiliation standard */}
+ {isEligibleForRefund ? (
+
+
+ Droit de rétractation (≤ 14 jours)
+
+
+ Votre abonnement a été activé il y a moins de 14 jours.
+ Vous allez être intégralement remboursé.
+ Vos services HestiaCP et bases de données seront supprimés immédiatement.
+
+
+ ) : (
+
+
📅 Résiliation standard (> 14 jours)
+
+ La période de rétractation est dépassée. Votre abonnement restera actif jusqu'à sa date d'échéance officielle.
+ Aucun renouvellement ni prélèvement n'aura lieu.
+
+
+ )}
+
+
+ Êtes-vous absolument sûr de vouloir procéder ? Cette action est irréversible une fois validée par nos serveurs.
+
+
+
+
+
+
+
+
+ )}
);
}
\ No newline at end of file
diff --git a/src/pages/app/Dashboard.jsx b/src/pages/app/Dashboard.jsx
index 4358746..85f9dd3 100644
--- a/src/pages/app/Dashboard.jsx
+++ b/src/pages/app/Dashboard.jsx
@@ -20,8 +20,10 @@ export default function Dashboard() {
const triggerAlert = (title, message, type = "info") => setCustomAlert({ title, message, type });
- const fetchInventory = async () => {
- setIsLoading(true);
+ const fetchInventory = async (retryCount = 0) => {
+ // On n'affiche le loader global que lors du tout premier essai
+ if (retryCount === 0) setIsLoading(true);
+
try {
const data = await getOrdersList();
@@ -37,17 +39,28 @@ export default function Dashboard() {
title.startsWith('domaine ') ||
title.startsWith('enregistrement ');
- return !isGhostProduct;
+ return (order.status === 'active' || order.status === 'pending_setup') && !isGhostProduct;
});
setOrders(filteredOrders);
} else {
setOrders([]);
}
+
+ setError(null); // On efface l'erreur s'il y en avait une
+ setIsLoading(false); // Le chargement est terminé
+
} catch (err) {
- setError(err.message || "Impossible de récupérer la télémétrie des services.");
- } finally {
- setIsLoading(false);
+ // 🛡️ SYSTÈME D'AUTO-GUÉRISON : Si on détecte le redémarrage d'HestiaCP (Erreur HTML/JSON)
+ if (err.message && err.message.includes('Unexpected token') && retryCount < 3) {
+ console.warn(`Redémarrage d'infrastructure détecté. Nouvelle tentative... (Essai ${retryCount + 1}/3)`);
+ // On attend 2,5 secondes, puis la fonction s'appelle elle-même (récursivité)
+ setTimeout(() => fetchInventory(retryCount + 1), 2500);
+ } else {
+ // S'il y a une vraie erreur persistante, on l'affiche au client
+ setError(err.message || "Impossible de récupérer la télémétrie des services.");
+ setIsLoading(false);
+ }
}
};
diff --git a/src/services/billing_api.js b/src/services/billing_api.js
index 2accc99..19a67fe 100644
--- a/src/services/billing_api.js
+++ b/src/services/billing_api.js
@@ -206,9 +206,7 @@ export const changeClientPassword = (current_password, new_password) =>
// Resiliation
// Action : Demande d'annulation (S'occupe de vérifier les 14 jours côté serveur)
export const cancelOrder = (orderId) => {
- // On utilise votre moteur apiCall existant, il transmettra automatiquement
- // le token "Bearer" dans le header Authorization !
- return apiCall(`${CUSTOM_API_URL}/cancel_subscription.php`, 'POST', {
+ return apiCall(`${CUSTOM_API_BASE_URL}/custom_api/cancel_subscription.php`, 'POST', {
order_id: orderId
});
};