From 27bf9750d1efb3dd99c5f9585b33b7dde75c31bc Mon Sep 17 00:00:00 2001 From: Arthur Puechberty Date: Sun, 18 Jan 2026 14:03:44 +0100 Subject: [PATCH] =?UTF-8?q?ajouter=20une=20section=20pour=20personnaliser?= =?UTF-8?q?=20l'apparence=20du=20bot=20avec=20pr=C3=A9visualisation=20et?= =?UTF-8?q?=20options=20de=20sauvegarde?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/public/guild.css | 71 ++++++++++++++++++ app/public/guild.html | 52 +++++++++++++ app/public/guild/botAppearanceForm.js | 104 ++++++++++++++++++++++++++ app/routes/api.js | 66 ++++++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 app/public/guild/botAppearanceForm.js diff --git a/app/public/guild.css b/app/public/guild.css index 054e543..4e074fd 100644 --- a/app/public/guild.css +++ b/app/public/guild.css @@ -964,3 +964,74 @@ body { overflow: hidden; text-overflow: ellipsis; } + +/* ===== Bot Appearance ===== */ +.bot-preview-card { + display: flex; + align-items: center; + gap: var(--spacing-md); + background: var(--bg-dark); + padding: var(--spacing-md); + border-radius: var(--radius-md); + max-width: 300px; +} + +.bot-preview-card img { + width: 64px; + height: 64px; + border-radius: 50%; +} + +.bot-preview-info { + display: flex; + align-items: center; + gap: var(--spacing-sm); +} + +.bot-preview-name { + font-weight: 600; + color: var(--text-primary); + font-size: 1.1rem; +} + +.bot-preview-tag { + background: var(--primary-color); + color: white; + font-size: 0.65rem; + padding: 2px 5px; + border-radius: 3px; + font-weight: 600; +} + +.alert { + padding: var(--spacing-md); + border-radius: var(--radius-sm); + margin-bottom: var(--spacing-md); +} + +.alert-warning { + background: rgba(240, 178, 50, 0.15); + border: 1px solid rgba(240, 178, 50, 0.3); + color: #F0B232; +} + +.alert-warning strong { + color: #F0B232; +} + +.avatar-preview-container { + display: flex; + align-items: center; + gap: var(--spacing-md); + background: var(--bg-dark); + padding: var(--spacing-md); + border-radius: var(--radius-md); +} + +.avatar-preview { + width: 80px; + height: 80px; + border-radius: 50%; + object-fit: cover; + display: none; +} diff --git a/app/public/guild.html b/app/public/guild.html index 58b7fe0..c9a8954 100644 --- a/app/public/guild.html +++ b/app/public/guild.html @@ -70,6 +70,10 @@ ✉️ Envoyer un message + + 🤖 + Apparence du bot + @@ -1062,6 +1066,53 @@ + +
+
+
+
+

🤖 Apparence du bot

+

Personnalisez le pseudo du bot sur ce serveur

+
+
+
+ + +
+ +
+ Avatar +
+
Chargement...
+
BOT
+
+
+
+ + +
+

📝 Pseudo sur ce serveur

+

Le pseudo du bot sera visible uniquement sur ce serveur.

+ +
+ + +
+ +
+ + +
+
+ +
+
+
+ @@ -1081,5 +1132,6 @@ + diff --git a/app/public/guild/botAppearanceForm.js b/app/public/guild/botAppearanceForm.js new file mode 100644 index 0000000..acc9988 --- /dev/null +++ b/app/public/guild/botAppearanceForm.js @@ -0,0 +1,104 @@ +// ===== BOT APPEARANCE FORM ===== +(async function () { + const previewAvatar = document.getElementById("bot-preview-avatar"); + const previewName = document.getElementById("bot-preview-name"); + const nicknameInput = document.getElementById("bot-nickname"); + const nicknameSaveBtn = document.getElementById("bot-nickname-save"); + const nicknameResetBtn = document.getElementById("bot-nickname-reset"); + + let botData = null; + + // Charger les infos du bot + async function loadBotInfo() { + try { + const res = await fetch(`/api/bot/get-bot-appearance/${window.guildId}`); + const data = await res.json(); + + if (data.success) { + botData = data; + + // Mettre à jour l'aperçu + if (data.avatarUrl) { + previewAvatar.src = data.avatarUrl; + } + previewName.textContent = data.nickname || data.username; + + // Remplir les champs + nicknameInput.value = data.nickname || ""; + nicknameInput.placeholder = data.username + " (par défaut)"; + } + } catch (err) { + console.error("Erreur chargement bot info:", err); + } + } + + // Sauvegarder le pseudo + nicknameSaveBtn.addEventListener("click", async () => { + const nickname = nicknameInput.value.trim(); + + nicknameSaveBtn.disabled = true; + nicknameSaveBtn.textContent = "⏳ Sauvegarde..."; + + try { + const res = await fetch("/api/bot/set-nickname", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + guildId: window.guildId, + nickname: nickname || null + }) + }); + + const data = await res.json(); + + if (data.success) { + alert("✅ Pseudo mis à jour avec succès !"); + previewName.textContent = nickname || botData.username; + } else { + alert("❌ Erreur: " + (data.error || "Erreur inconnue")); + } + } catch (err) { + console.error(err); + alert("❌ Erreur lors de la mise à jour du pseudo."); + } + + nicknameSaveBtn.disabled = false; + nicknameSaveBtn.textContent = "💾 Sauvegarder le pseudo"; + }); + + // Réinitialiser le pseudo + nicknameResetBtn.addEventListener("click", async () => { + nicknameResetBtn.disabled = true; + nicknameResetBtn.textContent = "⏳ Réinitialisation..."; + + try { + const res = await fetch("/api/bot/set-nickname", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + guildId: window.guildId, + nickname: null + }) + }); + + const data = await res.json(); + + if (data.success) { + alert("✅ Pseudo réinitialisé !"); + nicknameInput.value = ""; + previewName.textContent = botData.username; + } else { + alert("❌ Erreur: " + (data.error || "Erreur inconnue")); + } + } catch (err) { + console.error(err); + alert("❌ Erreur lors de la réinitialisation."); + } + + nicknameResetBtn.disabled = false; + nicknameResetBtn.textContent = "🔄 Réinitialiser"; + }); + + // Initialiser + loadBotInfo(); +})(); diff --git a/app/routes/api.js b/app/routes/api.js index 1f581d5..5c0c821 100644 --- a/app/routes/api.js +++ b/app/routes/api.js @@ -1215,5 +1215,71 @@ module.exports = (app, db, client) => { } }); + // ===== BOT APPEARANCE ===== + + // Obtenir les infos d'apparence du bot + router.get("/bot/get-bot-appearance/:guildId", async (req, res) => { + const { guildId } = req.params; + + if (!req.session.guilds) { + return res.status(401).json({ success: false, error: "Non connecté" }); + } + + try { + const guild = client.guilds.cache.get(guildId); + if (!guild) { + return res.status(404).json({ success: false, error: "Serveur non trouvé" }); + } + + const botMember = guild.members.me; + const bot = client.user; + + res.json({ + success: true, + username: bot.username, + nickname: botMember?.nickname || null, + avatarUrl: bot.displayAvatarURL({ size: 256 }), + discriminator: bot.discriminator + }); + + } catch (err) { + console.error("Erreur get bot appearance:", err); + res.status(500).json({ success: false, error: err.message }); + } + }); + + // Changer le pseudo du bot sur un serveur + router.post("/bot/set-nickname", express.json(), async (req, res) => { + const { guildId, nickname } = req.body; + + if (!req.session.guilds) { + return res.status(401).json({ success: false, error: "Non connecté" }); + } + + const isAdmin = req.session.guilds.find( + g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n + ); + + if (!isAdmin) { + return res.status(403).json({ success: false, error: "Permission refusée" }); + } + + try { + const guild = client.guilds.cache.get(guildId); + if (!guild) { + return res.status(404).json({ success: false, error: "Serveur non trouvé" }); + } + + const botMember = guild.members.me; + await botMember.setNickname(nickname || null); + + res.json({ success: true }); + + } catch (err) { + console.error("Erreur set nickname:", err); + res.status(500).json({ success: false, error: err.message }); + } + }); + app.use("/api", router); };