Initial commit: charles.secourit.fr - App de suivi maintenance 360 Partners
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export default function Dashboard({ token, user }) {
|
||||
const [domains, setDomains] = useState({ parent: null, children: [] })
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/api/domains', { headers: { Authorization: 'Bearer ' + token } })
|
||||
.then(r => r.json()).then(d => { setDomains(d); setLoading(false) })
|
||||
}, [token])
|
||||
|
||||
if (loading) return <div className="text-slate-400 text-center py-12">Chargement...</div>
|
||||
|
||||
const count = (d) => [d.has_cloud, d.has_website, d.has_emails, d.has_team].filter(Boolean).length
|
||||
const color = (n) => n === 0 ? 'bg-slate-600' : n < 3 ? 'bg-amber-500' : 'bg-emerald-500'
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-8">
|
||||
<h2 className="text-xl font-bold text-white mb-1">Domaines & Services</h2>
|
||||
<p className="text-slate-400 text-sm">
|
||||
{user.role === 'admin' ? 'Gerez les besoins de Charles pour chaque societe.' : 'Renseignez vos besoins pour chaque domaine.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{domains.parent && (
|
||||
<div className="mb-6 p-5 bg-slate-800/30 rounded-2xl border border-slate-700/30">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-blue-600/20 flex items-center justify-center">
|
||||
<svg className="w-5 h-5 text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-white font-semibold">{domains.parent.company_name}</h3>
|
||||
<p className="text-slate-400 text-xs">{domains.parent.name} — Entreprise maitre</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{domains.children.map(d => {
|
||||
const n = count(d)
|
||||
const tags = []
|
||||
if (d.has_cloud) tags.push(<span key="c" className="px-2 py-0.5 bg-sky-500/10 text-sky-400 text-xs rounded-md">Cloud</span>)
|
||||
if (d.has_website) tags.push(<span key="w" className="px-2 py-0.5 bg-violet-500/10 text-violet-400 text-xs rounded-md">Site{d.website_wordpress ? ' WP' : ''}</span>)
|
||||
if (d.has_emails) tags.push(<span key="e" className="px-2 py-0.5 bg-amber-500/10 text-amber-400 text-xs rounded-md">{d.email_count} mail{d.email_count > 1 ? 's' : ''}</span>)
|
||||
if (d.has_team) { const m = JSON.parse(d.team_members || '[]'); tags.push(<span key="t" className="px-2 py-0.5 bg-emerald-500/10 text-emerald-400 text-xs rounded-md">{m.length} user{m.length > 1 ? 's' : ''}</span>) }
|
||||
if (n === 0) tags.push(<span key="x" className="text-slate-500 text-xs italic">Aucun besoin renseigne</span>)
|
||||
|
||||
return (
|
||||
<Link key={d.id} to={'/domain/' + d.id}
|
||||
className="group p-5 bg-slate-800/40 hover:bg-slate-800/60 rounded-2xl border border-slate-700/30 hover:border-slate-600/50 transition-all duration-200 hover:shadow-lg hover:shadow-black/20">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<h3 className="text-white font-semibold group-hover:text-blue-400 transition-colors">{d.company_name}</h3>
|
||||
<p className="text-slate-400 text-xs mt-0.5">{d.name}</p>
|
||||
</div>
|
||||
<div className={'w-2.5 h-2.5 rounded-full mt-1 ' + color(n)} />
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
)}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</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}</p><p className="text-slate-400 text-xs">Domaines</p></div>
|
||||
<div><p className="text-2xl font-bold text-sky-400">{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.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.children.filter(d => d.has_emails).length}</p><p className="text-slate-400 text-xs">Avec mails</p></div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user