diff --git a/backend/src/db.js b/backend/src/db.js index ed29a4c..9b21446 100644 --- a/backend/src/db.js +++ b/backend/src/db.js @@ -35,12 +35,26 @@ db.exec(` team_members TEXT DEFAULT '[]', notes TEXT DEFAULT '', monthly_price REAL DEFAULT 0, + cloud_cost REAL DEFAULT 0, + website_cost REAL DEFAULT 0, + email_cost REAL DEFAULT 0, + user_cost REAL DEFAULT 0, created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now')), FOREIGN KEY (parent_id) REFERENCES domains(id) ); `); +// Migration: add cost columns if missing +const columns = db.prepare('PRAGMA table_info(domains)').all().map(c => c.name); +const addCostCol = (col) => { + if (!columns.includes(col)) db.exec('ALTER TABLE domains ADD COLUMN ' + col + ' REAL DEFAULT 0'); +}; +addCostCol('cloud_cost'); +addCostCol('website_cost'); +addCostCol('email_cost'); +addCostCol('user_cost'); + const userCount = db.prepare('SELECT COUNT(*) as count FROM users').get().count; if (userCount === 0) { const insert = db.prepare('INSERT INTO users (username, password_hash, name, role) VALUES (?, ?, ?, ?)'); diff --git a/backend/src/index.js b/backend/src/index.js index 2c31350..7987384 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -23,7 +23,7 @@ app.get('/api/domains', authMiddleware, (req, res) => { const parent = domains.find(d => !d.parent_id); const children = domains.filter(d => d.parent_id); if (req.user.role === 'client') { - domains.forEach(d => { delete d.monthly_price; }); + domains.forEach(d => { delete d.monthly_price; delete d.cloud_cost; delete d.website_cost; delete d.email_cost; delete d.user_cost; }); } res.json({ parent, children }); }); @@ -31,7 +31,7 @@ app.get('/api/domains', authMiddleware, (req, res) => { app.get('/api/domains/:id', authMiddleware, (req, res) => { const domain = db.prepare('SELECT * FROM domains WHERE id = ?').get(req.params.id); if (!domain) return res.status(404).json({ error: 'Domaine non trouve' }); - if (req.user.role === 'client') delete domain.monthly_price; + if (req.user.role === 'client') { delete domain.monthly_price; delete domain.cloud_cost; delete domain.website_cost; delete domain.email_cost; delete domain.user_cost; } res.json(domain); }); @@ -44,7 +44,7 @@ app.put('/api/domains/:id', authMiddleware, (req, res) => { 'website_managed_by', 'website_details', 'has_emails', 'email_count', 'email_addresses', 'has_team', 'team_members', 'notes' ]; - if (req.user.role === 'admin') fields.push('monthly_price'); + if (req.user.role === 'admin') fields.push('monthly_price', 'cloud_cost', 'website_cost', 'email_cost', 'user_cost'); const updates = {}; fields.forEach(f => { if (req.body[f] !== undefined) updates[f] = req.body[f]; }); @@ -56,7 +56,7 @@ app.put('/api/domains/:id', authMiddleware, (req, res) => { db.prepare('UPDATE domains SET ' + setClause + ' WHERE id = ?').run(...values); const updated = db.prepare('SELECT * FROM domains WHERE id = ?').get(req.params.id); - if (req.user.role === 'client') delete updated.monthly_price; + if (req.user.role === 'client') { delete updated.monthly_price; delete updated.cloud_cost; delete updated.website_cost; delete updated.email_cost; delete updated.user_cost; } res.json(updated); }); diff --git a/frontend/src/components/Dashboard.jsx b/frontend/src/components/Dashboard.jsx index 411c3c3..89d3a7b 100644 --- a/frontend/src/components/Dashboard.jsx +++ b/frontend/src/components/Dashboard.jsx @@ -40,13 +40,21 @@ export default function Dashboard({ token, user }) {
{domains.children.length + 1}
Domaines
{[domains.parent, ...domains.children].filter(d => d.has_cloud).length}
Cloud
{[domains.parent, ...domains.children].filter(d => d.has_website).length}
Sites web
{[domains.parent, ...domains.children].filter(d => d.has_emails).length}
Avec mails
{allDomains.length}
Domaines
{allDomains.filter(d => d.has_cloud).length}
Cloud
{allDomains.filter(d => d.has_website).length}
Sites web
{allDomains.filter(d => d.has_emails).length}
Avec mails
Aucun site web renseigne
} @@ -118,6 +137,7 @@ export default function DomainForm({ token, user }) { {d.has_emails ? (Aucun utilisateur renseigne
} - {user.role === 'admin' && ( -