Feat/manage webservices #2
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { CreditCard, Check, Globe, Loader, ToggleLeft, ShieldAlert, Calendar, TrendingUp, TrendingDown, RefreshCcw } from 'lucide-react';
|
import { CreditCard, Check, Globe, Loader, ToggleLeft, ShieldAlert, Calendar, TrendingUp, TrendingDown, RefreshCcw } from 'lucide-react';
|
||||||
import { getProductList, getHostingServiceDetails } from '../../services/api';
|
import { getProductList, getServiceDetails } from '../../services/api';
|
||||||
const CUSTOM_API_BASE_URL = import.meta.env.VITE_CUSTOM_API_BASE_URL || '';
|
const CUSTOM_API_BASE_URL = import.meta.env.VITE_CUSTOM_API_BASE_URL || '';
|
||||||
|
|
||||||
export default function SubscriptionManager({ order, onClose, onRefresh, onAlert }) {
|
export default function WebServiceSubscriptionManager({ order, onClose, onRefresh, onAlert }) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [cancelLoading, setCancelLoading] = useState(false);
|
const [cancelLoading, setCancelLoading] = useState(false);
|
||||||
const [catalog, setCatalog] = useState([]);
|
const [catalog, setCatalog] = useState([]);
|
||||||
@@ -20,7 +20,7 @@ export default function SubscriptionManager({ order, onClose, onRefresh, onAlert
|
|||||||
const fetchDetails = async () => {
|
const fetchDetails = async () => {
|
||||||
setIsDetailsLoading(true);
|
setIsDetailsLoading(true);
|
||||||
try {
|
try {
|
||||||
const data = await getHostingServiceDetails(order.id);
|
const data = await getServiceDetails(order.id);
|
||||||
setServiceDetails(data);
|
setServiceDetails(data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Erreur détails service:", err);
|
console.error("Erreur détails service:", err);
|
||||||
+95
-45
@@ -1,11 +1,13 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { getClientOrders } from '../../services/api';
|
import { getClientOrders } from '../../services/api';
|
||||||
import { AlertCircle, Loader } from 'lucide-react';
|
import { AlertCircle, Loader, FileText, X } from 'lucide-react';
|
||||||
|
|
||||||
// Importation des composants isolés
|
// Importation des composants
|
||||||
import DashboardServiceCard from '../../components/dashboard/DashboardServiceCard';
|
import DashboardServiceCard from '../../components/dashboard/DashboardServiceCard';
|
||||||
import NewServiceCard from '../../components/dashboard/NewServiceCard';
|
import NewServiceCard from '../../components/dashboard/NewServiceCard';
|
||||||
|
import NotificationModal from '../../components/ui/NotificationModal';
|
||||||
|
import WebServiceSubscriptionManager from '../../components/dashboard/WebServiceSubscriptionManager';
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -13,54 +15,82 @@ export default function Dashboard() {
|
|||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
// Chargement des données à l'ouverture du Sas
|
const [activeSubscriptionModal, setActiveSubscriptionModal] = useState(null);
|
||||||
useEffect(() => {
|
const [customAlert, setCustomAlert] = useState(null);
|
||||||
const fetchInventory = async () => {
|
|
||||||
try {
|
|
||||||
const data = await getClientOrders();
|
|
||||||
|
|
||||||
if (data.list) {
|
|
||||||
// LE FILTRE CHIRURGICAL PAR PREFIXE
|
|
||||||
const filteredOrders = data.list.filter(order => {
|
|
||||||
const title = (order.title || '').toLowerCase();
|
|
||||||
const type = (order.type || '').toLowerCase();
|
|
||||||
|
|
||||||
const isGhostProduct =
|
const triggerAlert = (title, message, type = "info") => setCustomAlert({ title, message, type });
|
||||||
type === 'domain' ||
|
|
||||||
title.startsWith('domain ') ||
|
|
||||||
title.startsWith('domaine ') ||
|
|
||||||
title.startsWith('enregistrement ');
|
|
||||||
|
|
||||||
return !isGhostProduct;
|
|
||||||
});
|
|
||||||
|
|
||||||
setOrders(filteredOrders);
|
const fetchInventory = async () => {
|
||||||
} else {
|
setIsLoading(true);
|
||||||
setOrders([]);
|
try {
|
||||||
}
|
const data = await getClientOrders();
|
||||||
} catch (err) {
|
|
||||||
setError(err.message || "Impossible de récupérer la télémétrie des services.");
|
if (data.list) {
|
||||||
} finally {
|
// LE FILTRE CHIRURGICAL PAR PREFIXE
|
||||||
setIsLoading(false);
|
const filteredOrders = data.list.filter(order => {
|
||||||
|
const title = (order.title || '').toLowerCase();
|
||||||
|
const type = (order.type || '').toLowerCase();
|
||||||
|
|
||||||
|
const isGhostProduct =
|
||||||
|
type === 'domain' ||
|
||||||
|
title.startsWith('domain ') ||
|
||||||
|
title.startsWith('domaine ') ||
|
||||||
|
title.startsWith('enregistrement ');
|
||||||
|
|
||||||
|
return !isGhostProduct;
|
||||||
|
});
|
||||||
|
|
||||||
|
setOrders(filteredOrders);
|
||||||
|
} else {
|
||||||
|
setOrders([]);
|
||||||
}
|
}
|
||||||
};
|
} catch (err) {
|
||||||
|
setError(err.message || "Impossible de récupérer la télémétrie des services.");
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
fetchInventory();
|
fetchInventory();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 🌟 Plus besoin de charger les IPs, on ouvre juste la modale comptable !
|
||||||
|
const handleManageSubscription = (order) => {
|
||||||
|
// 1. Détection du type de service
|
||||||
|
const titleLower = (order.title || '').toLowerCase();
|
||||||
|
const isVPS = titleLower.includes('vps') || titleLower.includes('compute');
|
||||||
|
const isCloud = titleLower.includes('cloud') || titleLower.includes('nextcloud');
|
||||||
|
const isDB = titleLower.includes('db') || titleLower.includes('base') || titleLower.includes('sql');
|
||||||
|
|
||||||
|
// C'est un hébergement web s'il ne correspond à aucun des cas ci-dessus
|
||||||
|
const isWeb = !isVPS && !isCloud && !isDB;
|
||||||
|
|
||||||
|
// 2. Logique de blocage
|
||||||
|
if (isWeb) {
|
||||||
|
// On ouvre la modale comptable uniquement pour le WEB
|
||||||
|
setActiveSubscriptionModal(order);
|
||||||
|
} else {
|
||||||
|
// On affiche une notification pour les autres types d'instances
|
||||||
|
triggerAlert(
|
||||||
|
"Action non disponible",
|
||||||
|
"La modification autonome d'abonnement est actuellement exclusive aux Hébergements Web. Pour restructurer cette instance, veuillez contacter les ingénieurs via le Centre de Support.",
|
||||||
|
"info"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full max-w-6xl p-6 mx-auto">
|
<div className="w-full max-w-6xl p-6 mx-auto relative">
|
||||||
|
|
||||||
<header className="mb-8">
|
<header className="mb-8">
|
||||||
<h1 className="text-3xl font-black text-white tracking-wider">TABLEAU DE <span className="text-cyan-400">BORD</span></h1>
|
<h1 className="text-3xl font-black text-white tracking-wider">TABLEAU DE <span className="text-cyan-400">BORD</span></h1>
|
||||||
<p className="text-gray-400 mt-2">Aperçu de vos accréditations réseau et infrastructures.</p>
|
<p className="text-gray-400 mt-2">Gestion financière et accréditations de vos infrastructures.</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* GESTION DES ERREURS & CHARGEMENT */}
|
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<div className="flex items-center space-x-3 text-cyan-400">
|
<div className="flex items-center space-x-3 text-cyan-400">
|
||||||
<Loader className="w-6 h-6 animate-spin" />
|
<Loader className="w-6 h-6 animate-spin" />
|
||||||
<span>Synchronisation avec l'orchestrateur en cours...</span>
|
<span>Synchronisation avec le registre comptable...</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -71,24 +101,44 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* GRILLE DES SERVICES */}
|
|
||||||
{!isLoading && !error && (
|
{!isLoading && !error && (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
||||||
|
|
||||||
{/* Boucle sur les composants isolés */}
|
|
||||||
{orders.map((order) => (
|
{orders.map((order) => (
|
||||||
<DashboardServiceCard
|
<DashboardServiceCard
|
||||||
key={order.id}
|
key={order.id}
|
||||||
order={order}
|
order={order}
|
||||||
onClick={() => navigate(`/services/${order.id}`)}
|
onClick={() => handleManageSubscription(order)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Le composant carte d'ajout */}
|
|
||||||
<NewServiceCard onClick={() => navigate('/store')} />
|
<NewServiceCard onClick={() => navigate('/store')} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 🌟 LA MODALE DE GESTION D'ABONNEMENT */}
|
||||||
|
{activeSubscriptionModal && (
|
||||||
|
<div className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
|
||||||
|
<div className="bg-gray-900 border border-cyan-500/50 shadow-2xl shadow-cyan-500/10 rounded-lg max-w-xxl w-full p-6 text-gray-200">
|
||||||
|
<div className="flex justify-between items-center mb-6 border-b border-gray-800 pb-4">
|
||||||
|
<h3 className="text-xl font-bold text-white tracking-wider flex items-center gap-3">
|
||||||
|
<FileText className="w-6 h-6 text-cyan-400" />
|
||||||
|
GESTION DE L'ABONNEMENT
|
||||||
|
</h3>
|
||||||
|
<button onClick={() => setActiveSubscriptionModal(null)} className="p-2 text-gray-500 hover:text-white bg-gray-900 hover:bg-gray-800 rounded-lg transition-colors">
|
||||||
|
<X className="w-5 h-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<WebServiceSubscriptionManager
|
||||||
|
order={activeSubscriptionModal}
|
||||||
|
onClose={() => setActiveSubscriptionModal(null)}
|
||||||
|
onRefresh={fetchInventory}
|
||||||
|
onAlert={triggerAlert}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<NotificationModal notification={customAlert} onClose={() => setCustomAlert(null)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { getMyServices, getHostingServiceDetails } from '../../services/api';
|
import { getClientOrders, getOrderDetails } from '../../services/api';
|
||||||
import { useVPC } from '../../services/useVPC';
|
import { useVPC } from '../../services/useVPC';
|
||||||
import { Server, Globe, Folder, Trash2, Loader, Plus, AlertCircle } from 'lucide-react';
|
import { Server, Globe, Folder, Trash2, Loader, Plus, AlertCircle } from 'lucide-react';
|
||||||
|
|
||||||
@@ -25,12 +25,12 @@ export default function Services() {
|
|||||||
|
|
||||||
const fetchServices = useCallback(async () => {
|
const fetchServices = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const data = await getMyServices();
|
const data = await getClientOrders();
|
||||||
if (data.list && data.list.length > 0) {
|
if (data.list && data.list.length > 0) {
|
||||||
const detailedServices = await Promise.all(data.list.map(async (order) => {
|
const detailedServices = await Promise.all(data.list.map(async (order) => {
|
||||||
let hDetails = null;
|
let hDetails = null;
|
||||||
if (order.status === 'active' && (order.plugin === 'hosting' || (order.title || '').toLowerCase().includes('vps'))) {
|
if (order.status === 'active' && (order.plugin === 'hosting' || (order.title || '').toLowerCase().includes('vps'))) {
|
||||||
try { hDetails = await getHostingServiceDetails(order.id); } catch (e) {}
|
try { hDetails = await getOrderDetails(order.id); } catch (e) {}
|
||||||
}
|
}
|
||||||
return { ...order, hostingDetails: hDetails };
|
return { ...order, hostingDetails: hDetails };
|
||||||
}));
|
}));
|
||||||
@@ -65,7 +65,7 @@ export default function Services() {
|
|||||||
} else if (isDB) {
|
} else if (isDB) {
|
||||||
window.open('https://pma.gise.be/', '_blank');
|
window.open('https://pma.gise.be/', '_blank');
|
||||||
} else if (isVPS || isWeb) {
|
} else if (isVPS || isWeb) {
|
||||||
const freshDetails = await getHostingServiceDetails(service.id);
|
const freshDetails = await getOrderDetails(service.id);
|
||||||
setActiveServiceModal({ type: isVPS ? 'vps' : 'web', data: service, details: freshDetails });
|
setActiveServiceModal({ type: isVPS ? 'vps' : 'web', data: service, details: freshDetails });
|
||||||
}
|
}
|
||||||
} catch (err) { triggerAlert("Erreur", err.message, "error"); }
|
} catch (err) { triggerAlert("Erreur", err.message, "error"); }
|
||||||
|
|||||||
+151
-61
@@ -1,7 +1,7 @@
|
|||||||
const BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
|
const BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
|
||||||
const CUSTOM_API_BASE_URL = import.meta.env.VITE_CUSTOM_API_BASE_URL || '';
|
const CUSTOM_API_BASE_URL = import.meta.env.VITE_CUSTOM_API_BASE_URL || '';
|
||||||
|
|
||||||
// Le moteur de requête unifié et intelligent
|
// Le moteur de requête
|
||||||
const apiCall = async (endpoint, param2 = 'GET', param3 = null) => {
|
const apiCall = async (endpoint, param2 = 'GET', param3 = null) => {
|
||||||
let method = 'GET';
|
let method = 'GET';
|
||||||
let body = null;
|
let body = null;
|
||||||
@@ -64,24 +64,6 @@ const apiCall = async (endpoint, param2 = 'GET', param3 = null) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// ROUTES FOSSBILLING NATIVES (BACKTICKS INTÉGRÉS)
|
|
||||||
// ==========================================
|
|
||||||
|
|
||||||
export const loginClient = (email, password) =>
|
|
||||||
apiCall(`${BASE_URL}/api/guest/client/login`, { email, password });
|
|
||||||
|
|
||||||
// Récupère la liste des services/commandes du client
|
|
||||||
export const getClientOrders = () =>
|
|
||||||
apiCall(`${BASE_URL}/api/client/order/get_list`);
|
|
||||||
|
|
||||||
// Récupère les détails techniques du service rattaché à une commande
|
|
||||||
export const getOrderService = (order_id) =>
|
|
||||||
apiCall(`${BASE_URL}/api/client/order/service`, { id: order_id });
|
|
||||||
|
|
||||||
// Récupère le catalogue public des produits FOSSBilling
|
|
||||||
export const getProductList = () =>
|
|
||||||
apiCall(`${BASE_URL}/api/guest/product/get_list`);
|
|
||||||
|
|
||||||
// Vide le panier (Action PUBLIQUE : on passe par l'API Guest)
|
// Vide le panier (Action PUBLIQUE : on passe par l'API Guest)
|
||||||
export const resetCart = async () => {
|
export const resetCart = async () => {
|
||||||
@@ -100,22 +82,6 @@ export const resetCart = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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)
|
// ROUTES PERSONNALISÉES (CUSTOM API)
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@@ -144,18 +110,6 @@ export const registerUnifiedClient = async (email, username, password, firstName
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
// Force la réinitialisation du mot de passe sur le serveur distant (HestiaCP)
|
||||||
export const resetHostingPassword = (orderId, newPassword) =>
|
export const resetHostingPassword = (orderId, newPassword) =>
|
||||||
apiCall(`${BASE_URL}/api/client/servicehosting/change_password`, 'POST', {
|
apiCall(`${BASE_URL}/api/client/servicehosting/change_password`, 'POST', {
|
||||||
@@ -191,33 +145,169 @@ export const launchSSOGateway = (username, password) => {
|
|||||||
document.body.removeChild(form);
|
document.body.removeChild(form);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #######################################################################################
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// ROUTES SUPPORT FOSSBILLING (NATIVES)
|
// GESTION DES ACCES
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
||||||
// Récupère la liste de tous les tickets du client
|
// Connexion
|
||||||
export const getClientTickets = () =>
|
export const loginClient = (email, password) =>
|
||||||
apiCall(`${BASE_URL}/api/client/support/ticket_get_list`, 'GET');
|
apiCall(`${BASE_URL}/api/guest/client/login`, { email, password });
|
||||||
|
|
||||||
// Récupère le contenu et les messages d'un ticket spécifique
|
// Deconnexion
|
||||||
export const getTicketDetails = (ticketId) =>
|
export const logoutClient = () =>
|
||||||
apiCall(`${BASE_URL}/api/client/support/ticket_get`, 'POST', { id: ticketId });
|
apiCall(`${BASE_URL}/api/client/profile/logout`);
|
||||||
|
|
||||||
// Crée un nouveau ticket de support
|
|
||||||
|
// ==========================================
|
||||||
|
// GESTION DU CLIENT
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
// Recuperer les informations du client
|
||||||
|
export const getClientProfile = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/profile/get`, 'GET');
|
||||||
|
|
||||||
|
// Update les informations du client
|
||||||
|
export const updateClientProfile = (email, last_name, aid, gender, country, city, birthday, company, company_vat, company_number, type, address_1, address_2, postcode, state, phone, phone_cc, document_type, document_nr, notes, lang, custom_1, custom_2, custom_3, custom_4, custom_5, custom_6, custom_7, custom_8, custom_9, custom_10) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/profile/update`, {
|
||||||
|
email: email,
|
||||||
|
last_name: last_name,
|
||||||
|
aid: aid,
|
||||||
|
gender: gender,
|
||||||
|
country: country,
|
||||||
|
city: city,
|
||||||
|
birthday: birthday,
|
||||||
|
company: company,
|
||||||
|
company_vat: company_vat,
|
||||||
|
company_number: company_number,
|
||||||
|
type: type,
|
||||||
|
address_1: address_1,
|
||||||
|
address_2: address_2,
|
||||||
|
postcode: postcode,
|
||||||
|
state: state,
|
||||||
|
phone: phone,
|
||||||
|
phone_cc: phone_cc,
|
||||||
|
document_type: document_type,
|
||||||
|
document_nr: document_nr,
|
||||||
|
notes: notes,
|
||||||
|
lang: lang,
|
||||||
|
custom_1: custom_1,
|
||||||
|
custom_2: custom_2,
|
||||||
|
custom_3: custom_3,
|
||||||
|
custom_4: custom_4,
|
||||||
|
custom_5: custom_5,
|
||||||
|
custom_6: custom_6,
|
||||||
|
custom_7: custom_7,
|
||||||
|
custom_8: custom_8,
|
||||||
|
custom_9: custom_9,
|
||||||
|
custom_10: custom_10
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Changer le mot de passe
|
||||||
|
export const changeClientPassword = (current_password, new_password, confirm_password) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/profile/change_password`, {current_password:current_password, new_password:new_password, confirm_password:confirm_password});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// GESTION DES ABONNEMENTS
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
// Souscription
|
||||||
|
|
||||||
|
// Resiliation
|
||||||
|
|
||||||
|
// Suppression
|
||||||
|
export const deleteWrongOrder = (order_id) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/order/delete`, { id: order_id });
|
||||||
|
|
||||||
|
// Promotion (Surclassement)
|
||||||
|
// Lister
|
||||||
|
export const getUpgrades = (order_id) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/order/upgradables`, { id: order_id });
|
||||||
|
|
||||||
|
// Demotion (Declassement)
|
||||||
|
|
||||||
|
// Lister les abonnements du client
|
||||||
|
export const getClientOrders = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/order/get_list`);
|
||||||
|
|
||||||
|
// Lister les produits disponibles
|
||||||
|
export const getProductList = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/guest/product/get_list`);
|
||||||
|
|
||||||
|
// Recuperer les details d'un abonnement
|
||||||
|
export const getOrderDetails = (order_id) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/order/service`, { id: order_id });
|
||||||
|
|
||||||
|
// Recuperer les details secrets d'un abonnement
|
||||||
|
export const getServiceDetails = (orderId) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/order/get`, 'POST', { id: orderId });
|
||||||
|
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// GESTION DU PANIER
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
// Ajouter au panier
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
// Checkout
|
||||||
|
export const checkoutCart = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/cart/checkout`, 'POST');
|
||||||
|
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// GESTION DES FACTURES
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
// Creation
|
||||||
|
// Suppression
|
||||||
|
// Modification
|
||||||
|
// Lister
|
||||||
|
export const getInvoiceList = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/invoice/get_list`, 'GET');
|
||||||
|
|
||||||
|
// Lire
|
||||||
|
export const getInvoiceDetails = (InvoiceHash) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/invoice/get`, 'GET');
|
||||||
|
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// GESTION DES TICKETS
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
// Creation
|
||||||
export const createTicket = (subject, message, helpdesk_id) =>
|
export const createTicket = (subject, message, helpdesk_id) =>
|
||||||
apiCall(`${BASE_URL}/api/client/support/ticket_create`, 'POST', {
|
apiCall(`${BASE_URL}/api/client/support/ticket_create`, 'POST', {
|
||||||
support_helpdesk_id: helpdesk_id,
|
support_helpdesk_id: helpdesk_id,
|
||||||
subject: subject,
|
subject: subject,
|
||||||
content: message
|
content: message
|
||||||
});
|
});
|
||||||
|
// Suppression
|
||||||
|
|
||||||
// Répond à un ticket existant
|
// Lister les tickets
|
||||||
|
export const getClientTickets = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/support/ticket_get_list`, 'GET');
|
||||||
|
|
||||||
|
// Lister les helpdesks
|
||||||
|
export const getHelpdesks = () =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/support/helpdesk_get_pairs`, 'GET');
|
||||||
|
|
||||||
|
// Lire
|
||||||
|
export const getTicketDetails = (ticketId) =>
|
||||||
|
apiCall(`${BASE_URL}/api/client/support/ticket_get`, 'POST', { id: ticketId });
|
||||||
|
|
||||||
|
// Repondre
|
||||||
export const replyTicket = (ticketId, message) =>
|
export const replyTicket = (ticketId, message) =>
|
||||||
apiCall(`${BASE_URL}/api/client/support/ticket_reply`, 'POST', {
|
apiCall(`${BASE_URL}/api/client/support/ticket_reply`, 'POST', {
|
||||||
id: ticketId,
|
id: ticketId,
|
||||||
content: message
|
content: message
|
||||||
});
|
});
|
||||||
|
|
||||||
// Récupère la liste dynamique des départements (Helpdesks) configurés sur FOSSBilling
|
|
||||||
export const getHelpdesks = () =>
|
|
||||||
apiCall(`${BASE_URL}/api/client/support/helpdesk_get_pairs`, 'GET');
|
|
||||||
Reference in New Issue
Block a user