Files
portail-gise/src/pages/app/Store.jsx
T
LathanDevers 15213bba21 change api
2026-07-16 14:51:57 +02:00

80 lines
3.4 KiB
React

// src/pages/app/Store.jsx
import { useState, useEffect } from 'react';
import { Server, Database, Cloud, Globe, Loader, AlertCircle } from 'lucide-react';
import { getProductList } from '../../services/billing_api';
import CategorySection from '../../components/store/CategorySection';
export default function Store() {
const [groupedProducts, setGroupedProducts] = useState({});
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const CATEGORY_ORDER = ["Web Hosting", "VPS", "Database", "Cloud"];
const CATEGORY_MAP = { 1: "Web Hosting", 4: "VPS", 3: "Database", 2: "Cloud" };
useEffect(() => {
const fetchCatalog = async () => {
try {
const data = await getProductList();
const products = data.list || [];
const grid = products.reduce((acc, product) => {
const catId = product.product_category_id;
const catName = CATEGORY_MAP[catId] || 'Autres Services';
if (!acc[catName]) acc[catName] = [];
acc[catName].push(product);
return acc;
}, {});
setGroupedProducts(grid);
} catch (err) {
setError("Impossible de contacter le serveur d'approvisionnement.");
} finally {
setIsLoading(false);
}
};
fetchCatalog();
}, []);
const getCategoryIcon = (text) => {
const t = text.toLowerCase();
if (t.includes('vps') || t.includes('serveur')) return <Server className="w-8 h-8 text-cyan-400" />;
if (t.includes('cloud') || t.includes('nextcloud')) return <Cloud className="w-8 h-8 text-blue-400" />;
if (t.includes('data') || t.includes('db') || t.includes('base')) return <Database className="w-8 h-8 text-purple-400" />;
return <Globe className="w-8 h-8 text-emerald-400" />;
};
const sortedCategoryNames = Object.keys(groupedProducts).sort((a, b) => {
let indexA = CATEGORY_ORDER.indexOf(a);
let indexB = CATEGORY_ORDER.indexOf(b);
if (indexA === -1) indexA = 999;
if (indexB === -1) indexB = 999;
return indexA - indexB;
});
return (
<div className="w-full max-w-7xl p-6 mx-auto">
<header className="mb-12 text-center pt-8">
<h1 className="text-4xl md:text-5xl font-black text-white tracking-widest mb-4">
CATALOGUE <span className="text-cyan-400">NEXUS</span>
</h1>
<p className="text-gray-400 max-w-2xl mx-auto text-lg">
Déployez de nouvelles instances et étendez votre infrastructure. Facturation flexible.
</p>
</header>
{isLoading && <div className="flex justify-center text-cyan-400 my-20"><Loader className="w-10 h-10 animate-spin" /></div>}
{error && <div className="flex justify-center text-red-400 my-20"><AlertCircle className="w-10 h-10 mr-2" /> {error}</div>}
{!isLoading && !error && sortedCategoryNames.map((categoryName) => (
<CategorySection
key={categoryName}
categoryName={categoryName}
products={groupedProducts[categoryName]}
getCategoryIcon={getCategoryIcon}
/>
))}
</div>
);
}