Initial commit: Club DynaSQY
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
const pool = require('../config/db');
|
||||
const { logActivity } = require('../services/activityLog');
|
||||
const sharp = require('sharp');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
exports.list = async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.query(`
|
||||
SELECT u.id, u.prenom, u.nom, u.societe, u.activite, u.email, u.telephone,
|
||||
u.photo_url, u.merged_display_name, u.site_web, u.role, u.date_adhesion, u.date_echeance,
|
||||
u.invite_par_id, ip.prenom AS invite_par_prenom, ip.nom AS invite_par_nom,
|
||||
u.date_postulation, u.reception_connu, u.reception_inconnu,
|
||||
rc.prenom AS reception_connu_prenom, rc.nom AS reception_connu_nom,
|
||||
ri.prenom AS reception_inconnu_prenom, ri.nom AS reception_inconnu_nom,
|
||||
u.date_entretien_postulation, u.date_demande_whatsapp,
|
||||
u.fonction, u.fonction_emoji, u.kdrive_link
|
||||
FROM users u
|
||||
LEFT JOIN users ip ON ip.id = u.invite_par_id
|
||||
LEFT JOIN users rc ON rc.id = u.reception_connu
|
||||
LEFT JOIN users ri ON ri.id = u.reception_inconnu
|
||||
WHERE u.actif = 1
|
||||
ORDER BY u.prenom ASC
|
||||
`);
|
||||
res.json(rows);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Erreur serveur' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.getById = async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.query(`
|
||||
SELECT u.*,
|
||||
ip.prenom AS invite_par_prenom, ip.nom AS invite_par_nom,
|
||||
rc.prenom AS reception_connu_prenom, rc.nom AS reception_connu_nom,
|
||||
ri.prenom AS reception_inconnu_prenom, ri.nom AS reception_inconnu_nom
|
||||
FROM users u
|
||||
LEFT JOIN users ip ON ip.id = u.invite_par_id
|
||||
LEFT JOIN users rc ON rc.id = u.reception_connu
|
||||
LEFT JOIN users ri ON ri.id = u.reception_inconnu
|
||||
WHERE u.id = ?
|
||||
`, [req.params.id]);
|
||||
if (rows.length === 0) return res.status(404).json({ error: 'Not found' });
|
||||
const { password_hash, ...member } = rows[0];
|
||||
res.json(member);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
const memberId = req.params.id;
|
||||
if (Number(memberId) !== req.user.id && req.user.role !== 'admin') {
|
||||
return res.status(403).json({ error: 'Unauthorized' });
|
||||
}
|
||||
const { prenom, nom, societe, activite, email, telephone, site_web,
|
||||
date_adhesion, date_echeance,
|
||||
invite_par_id, date_postulation, reception_connu, reception_inconnu,
|
||||
date_entretien_postulation, date_demande_whatsapp,
|
||||
fonction, fonction_emoji, kdrive_link, merged_display_name } = req.body;
|
||||
if (!prenom || !nom) return res.status(400).json({ error: 'Prénom et nom requis' });
|
||||
const isAdmin = req.user.role === 'admin';
|
||||
const adminFields = isAdmin ? {
|
||||
date_adhesion: date_adhesion || null,
|
||||
date_echeance: date_echeance || null,
|
||||
invite_par_id: invite_par_id || null,
|
||||
date_postulation: date_postulation || null,
|
||||
reception_connu: reception_connu || null,
|
||||
reception_inconnu: reception_inconnu || null,
|
||||
date_entretien_postulation: date_entretien_postulation || null,
|
||||
date_demande_whatsapp: date_demande_whatsapp || null,
|
||||
fonction: fonction || null,
|
||||
fonction_emoji: fonction_emoji || null,
|
||||
kdrive_link: kdrive_link || null,
|
||||
merged_display_name: merged_display_name || null,
|
||||
} : {};
|
||||
await pool.query(
|
||||
`UPDATE users SET prenom=?, nom=?, societe=?, activite=?, email=?, telephone=?, site_web=?,
|
||||
date_adhesion=?, date_echeance=?, invite_par_id=?, date_postulation=?,
|
||||
reception_connu=?, reception_inconnu=?, date_entretien_postulation=?,
|
||||
date_demande_whatsapp=?, fonction=?, fonction_emoji=?, kdrive_link=?, merged_display_name=? WHERE id=?`,
|
||||
[prenom, nom, societe || null, activite || null, email || null, telephone || null, site_web || null,
|
||||
adminFields.date_adhesion, adminFields.date_echeance,
|
||||
adminFields.invite_par_id, adminFields.date_postulation,
|
||||
adminFields.reception_connu, adminFields.reception_inconnu,
|
||||
adminFields.date_entretien_postulation, adminFields.date_demande_whatsapp,
|
||||
adminFields.fonction, adminFields.fonction_emoji, adminFields.kdrive_link,
|
||||
adminFields.merged_display_name,
|
||||
memberId]
|
||||
);
|
||||
logActivity(req, 'membre_modification', { memberId });
|
||||
res.json({ message: 'Mis à jour' });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Erreur serveur' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.uploadPhoto = async (req, res) => {
|
||||
try {
|
||||
if (!req.file) return res.status(400).json({ error: 'No file uploaded' });
|
||||
const filePath = req.file.path;
|
||||
const ext = path.extname(filePath);
|
||||
const jpgPath = ext === '.jpg' ? filePath : filePath.replace(ext, '.jpg');
|
||||
try {
|
||||
await sharp(filePath).resize(400, 400, { fit: 'cover', position: 'centre' }).jpeg({ quality: 85 }).toFile(jpgPath);
|
||||
if (jpgPath !== filePath) fs.unlinkSync(filePath);
|
||||
} catch (sharpErr) {
|
||||
console.error('Sharp error, fallback:', sharpErr);
|
||||
if (jpgPath !== filePath) fs.renameSync(filePath, jpgPath);
|
||||
}
|
||||
const finalUrl = `/uploads/${path.basename(jpgPath)}`;
|
||||
const [existing] = await pool.query('SELECT photo_url FROM users WHERE id = ?', [req.user.id]);
|
||||
if (existing[0]?.photo_url) {
|
||||
const oldRelativePath = existing[0].photo_url.replace(/^\//, '');
|
||||
const oldPath = path.join(__dirname, '..', oldRelativePath);
|
||||
if (fs.existsSync(oldPath)) fs.unlinkSync(oldPath);
|
||||
}
|
||||
await pool.query('UPDATE users SET photo_url = ? WHERE id = ?', [finalUrl, req.user.id]);
|
||||
logActivity(req, 'photo_changement');
|
||||
res.json({ photo_url: finalUrl });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.create = async (req, res) => {
|
||||
try {
|
||||
const { prenom, nom, societe, activite, email, telephone, role } = req.body;
|
||||
if (!prenom || !nom || !email) {
|
||||
return res.status(400).json({ error: 'Prénom, nom et email requis' });
|
||||
}
|
||||
const defaultPassword = 'Bienvenue2026';
|
||||
const bcrypt = require('bcrypt');
|
||||
const hash = await bcrypt.hash(defaultPassword, 10);
|
||||
const [result] = await pool.query(
|
||||
'INSERT INTO users (prenom, nom, societe, activite, email, telephone, role, password_hash, date_adhesion, actif) VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURDATE(), 1)',
|
||||
[prenom, nom, societe || null, activite || null, email, telephone || null, role || 'member', hash]
|
||||
);
|
||||
res.status(201).json({
|
||||
id: result.insertId,
|
||||
message: 'Membre créé',
|
||||
defaultPassword: 'Bienvenue2026',
|
||||
});
|
||||
logActivity(req, 'membre_ajout', { prenom, nom });
|
||||
} catch (err) {
|
||||
if (err.code === 'ER_DUP_ENTRY') {
|
||||
return res.status(400).json({ error: 'Cet email est déjà utilisé' });
|
||||
}
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.remove = async (req, res) => {
|
||||
try {
|
||||
if (req.user.role !== 'admin') return res.status(403).json({ error: 'Admin seulement' });
|
||||
const memberId = req.params.id;
|
||||
if (Number(memberId) === req.user.id) return res.status(400).json({ error: 'Vous ne pouvez pas vous supprimer vous-même' });
|
||||
await pool.query('UPDATE users SET actif = 0 WHERE id = ?', [memberId]);
|
||||
logActivity(req, 'membre_desactivation', { memberId });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user