Ajout couts par service (cloud, site, mail, user) + resume admin detaille HT
This commit is contained in:
@@ -40,13 +40,21 @@ export default function Dashboard({ token, user }) {
|
||||
<div className="flex flex-wrap gap-1.5">{tags}</div>
|
||||
{user.role === 'admin' && d.monthly_price > 0 && (
|
||||
<div className="mt-3 pt-3 border-t border-slate-700/30">
|
||||
<span className="text-emerald-400 font-semibold text-sm">{d.monthly_price} EUR/mois</span>
|
||||
<span className="text-emerald-400 font-semibold text-sm">{d.monthly_price} EUR/mois HT</span>
|
||||
</div>
|
||||
)}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
// Admin cost summary
|
||||
const allDomains = [domains.parent, ...domains.children].filter(Boolean)
|
||||
const totalCloud = allDomains.reduce((s, d) => s + (d.has_cloud ? (d.cloud_cost || 0) : 0), 0)
|
||||
const totalWebsite = allDomains.reduce((s, d) => s + (d.has_website ? (d.website_cost || 0) : 0), 0)
|
||||
const totalEmail = allDomains.reduce((s, d) => s + (d.has_emails ? (d.email_count || 0) * (d.email_cost || 0) : 0), 0)
|
||||
const totalUsers = allDomains.reduce((s, d) => s + (d.has_team ? JSON.parse(d.team_members || '[]').length * (d.user_cost || 0) : 0), 0)
|
||||
const totalAll = totalCloud + totalWebsite + totalEmail + totalUsers
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-8">
|
||||
@@ -63,13 +71,59 @@ export default function Dashboard({ token, user }) {
|
||||
</div>
|
||||
|
||||
{user.role === 'admin' && (
|
||||
<div className="mt-8 p-5 bg-slate-800/30 rounded-2xl border border-slate-700/30">
|
||||
<h3 className="text-white font-semibold mb-3">Resume</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
|
||||
<div><p className="text-2xl font-bold text-white">{domains.children.length + 1}</p><p className="text-slate-400 text-xs">Domaines</p></div>
|
||||
<div><p className="text-2xl font-bold text-sky-400">{[domains.parent, ...domains.children].filter(d => d.has_cloud).length}</p><p className="text-slate-400 text-xs">Cloud</p></div>
|
||||
<div><p className="text-2xl font-bold text-violet-400">{[domains.parent, ...domains.children].filter(d => d.has_website).length}</p><p className="text-slate-400 text-xs">Sites web</p></div>
|
||||
<div><p className="text-2xl font-bold text-emerald-400">{[domains.parent, ...domains.children].filter(d => d.has_emails).length}</p><p className="text-slate-400 text-xs">Avec mails</p></div>
|
||||
<div className="mt-8 space-y-4">
|
||||
{/* Vue d'ensemble */}
|
||||
<div className="p-5 bg-slate-800/30 rounded-2xl border border-slate-700/30">
|
||||
<h3 className="text-white font-semibold mb-3">Resume</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
|
||||
<div><p className="text-2xl font-bold text-white">{allDomains.length}</p><p className="text-slate-400 text-xs">Domaines</p></div>
|
||||
<div><p className="text-2xl font-bold text-sky-400">{allDomains.filter(d => d.has_cloud).length}</p><p className="text-slate-400 text-xs">Cloud</p></div>
|
||||
<div><p className="text-2xl font-bold text-violet-400">{allDomains.filter(d => d.has_website).length}</p><p className="text-slate-400 text-xs">Sites web</p></div>
|
||||
<div><p className="text-2xl font-bold text-emerald-400">{allDomains.filter(d => d.has_emails).length}</p><p className="text-slate-400 text-xs">Avec mails</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Detail des couts */}
|
||||
<div className="p-5 bg-slate-800/30 rounded-2xl border border-slate-700/30">
|
||||
<h3 className="text-white font-semibold mb-4">Detail des couts mensuels HT</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between py-2 border-b border-slate-700/30">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-sky-400" />
|
||||
<span className="text-slate-300 text-sm">Cloud</span>
|
||||
<span className="text-slate-500 text-xs">({allDomains.filter(d => d.has_cloud).length})</span>
|
||||
</div>
|
||||
<span className="text-white font-mono text-sm">{totalCloud.toFixed(2)} EUR</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between py-2 border-b border-slate-700/30">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-violet-400" />
|
||||
<span className="text-slate-300 text-sm">Sites web</span>
|
||||
<span className="text-slate-500 text-xs">({allDomains.filter(d => d.has_website).length})</span>
|
||||
</div>
|
||||
<span className="text-white font-mono text-sm">{totalWebsite.toFixed(2)} EUR</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between py-2 border-b border-slate-700/30">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-amber-400" />
|
||||
<span className="text-slate-300 text-sm">Adresses mail</span>
|
||||
<span className="text-slate-500 text-xs">({allDomains.reduce((s, d) => s + (d.has_emails ? d.email_count || 0 : 0), 0)})</span>
|
||||
</div>
|
||||
<span className="text-white font-mono text-sm">{totalEmail.toFixed(2)} EUR</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between py-2 border-b border-slate-700/30">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-emerald-400" />
|
||||
<span className="text-slate-300 text-sm">Utilisateurs</span>
|
||||
<span className="text-slate-500 text-xs">({allDomains.reduce((s, d) => s + (d.has_team ? JSON.parse(d.team_members || '[]').length : 0), 0)})</span>
|
||||
</div>
|
||||
<span className="text-white font-mono text-sm">{totalUsers.toFixed(2)} EUR</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between py-3 border-t border-slate-600/50">
|
||||
<span className="text-white font-semibold">Total mensuel HT</span>
|
||||
<span className="text-emerald-400 font-bold font-mono text-lg">{totalAll.toFixed(2)} EUR/mois</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user