mirror of
https://github.com/arthur-pbty/LazyBot.git
synced 2026-06-16 08:12:25 +02:00
refonte css of site
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
const autoroleNewUserForm = document.getElementById("autorole-newuser-form");
|
||||
const autoroleEnabled = document.getElementById("autorole-enabled");
|
||||
const autoroleRole = document.getElementById("autorole-role");
|
||||
const statusAutoroleForm = document.getElementById("status-autorole-form");
|
||||
const saveAutorole = document.getElementById("save-autorole");
|
||||
|
||||
// Charger la config
|
||||
fetch(`/api/bot/get-autorole-newuser-config/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
@@ -10,20 +10,32 @@ fetch(`/api/bot/get-autorole-newuser-config/${guildId}`)
|
||||
autoroleRole.value = cfg.roleId;
|
||||
});
|
||||
|
||||
autoroleNewUserForm.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
// Sauvegarder
|
||||
saveAutorole.addEventListener("click", async () => {
|
||||
saveAutorole.disabled = true;
|
||||
saveAutorole.textContent = "Sauvegarde...";
|
||||
|
||||
const res = await fetch("/api/bot/save-autorole-newuser-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
enabled: autoroleEnabled.checked,
|
||||
roleId: autoroleRole.value
|
||||
})
|
||||
});
|
||||
try {
|
||||
const res = await fetch("/api/bot/save-autorole-newuser-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
enabled: autoroleEnabled.checked,
|
||||
roleId: autoroleRole.value
|
||||
})
|
||||
});
|
||||
|
||||
statusAutoroleForm.textContent = (await res.json()).success
|
||||
? "Auto-rôle sauvegardé ✅"
|
||||
: "Erreur ❌";
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showStatus("status-autorole-form", "Configuration sauvegardée ✅", "success");
|
||||
} else {
|
||||
showStatus("status-autorole-form", "Erreur lors de la sauvegarde ❌", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
showStatus("status-autorole-form", "Erreur de connexion ❌", "error");
|
||||
}
|
||||
|
||||
saveAutorole.disabled = false;
|
||||
saveAutorole.textContent = "Sauvegarder";
|
||||
});
|
||||
|
||||
@@ -1,43 +1,50 @@
|
||||
const autoroleVocalForm = document.getElementById("autorole-vocal-form");
|
||||
const autoroleVocalEnabled = document.getElementById("autorole-vocal-enabled");
|
||||
const autoroleVocalRole = document.getElementById("autorole-vocal-role");
|
||||
const excludeSelect = document.getElementById("autorole-vocal-exclude-channel");
|
||||
const statusAutoroleVocalForm = document.getElementById("status-autorole-vocal-form");
|
||||
const saveAutoroleVocal = document.getElementById("save-autorole-vocal");
|
||||
|
||||
fetch(`/api/bot/get-voice-channels/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(channels => {
|
||||
channels.forEach(c => {
|
||||
excludeSelect.appendChild(new Option(`#${c.name}`, c.id));
|
||||
// Charger la config après que les channels soient chargés
|
||||
setTimeout(() => {
|
||||
fetch(`/api/bot/get-autorole-vocal-config/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
autoroleVocalEnabled.checked = cfg.enabled;
|
||||
autoroleVocalRole.value = cfg.roleId;
|
||||
Array.from(excludeSelect.options).forEach(opt => {
|
||||
opt.selected = cfg.excludeChannelIds?.includes(opt.value);
|
||||
});
|
||||
});
|
||||
return fetch(`/api/bot/get-autorole-vocal-config/${guildId}`);
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
autoroleVocalEnabled.checked = cfg.enabled;
|
||||
autoroleVocalRole.value = cfg.roleId;
|
||||
Array.from(excludeSelect.options).forEach(opt => {
|
||||
opt.selected = cfg.excludeChannelIds?.includes(opt.value);
|
||||
}, 500);
|
||||
|
||||
// Sauvegarder
|
||||
saveAutoroleVocal.addEventListener("click", async () => {
|
||||
saveAutoroleVocal.disabled = true;
|
||||
saveAutoroleVocal.textContent = "Sauvegarde...";
|
||||
|
||||
try {
|
||||
const exclude = Array.from(excludeSelect.selectedOptions).map(o => o.value);
|
||||
|
||||
const res = await fetch("/api/bot/save-autorole-vocal-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
enabled: autoroleVocalEnabled.checked,
|
||||
roleId: autoroleVocalRole.value,
|
||||
excludeChannelId: exclude
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
autoroleVocalForm.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showStatus("status-autorole-vocal-form", "Configuration sauvegardée ✅", "success");
|
||||
} else {
|
||||
showStatus("status-autorole-vocal-form", "Erreur lors de la sauvegarde ❌", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
showStatus("status-autorole-vocal-form", "Erreur de connexion ❌", "error");
|
||||
}
|
||||
|
||||
const exclude = Array.from(excludeSelect.selectedOptions).map(o => o.value);
|
||||
|
||||
const res = await fetch("/api/bot/save-autorole-vocal-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
enabled: autoroleVocalEnabled.checked,
|
||||
roleId: autoroleVocalRole.value,
|
||||
excludeChannelId: exclude
|
||||
})
|
||||
});
|
||||
|
||||
statusAutoroleVocalForm.textContent = (await res.json()).success
|
||||
? "Auto-rôle vocal sauvegardé ✅"
|
||||
: "Erreur ❌";
|
||||
saveAutoroleVocal.disabled = false;
|
||||
saveAutoroleVocal.textContent = "Sauvegarder";
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const economyForm = document.getElementById("economy-form");
|
||||
const economyEnabled = document.getElementById("economy-enabled");
|
||||
const currencyName = document.getElementById("economy-currency-name");
|
||||
const currencySymbol = document.getElementById("economy-currency-symbol");
|
||||
@@ -42,7 +41,7 @@ const voiceMoneyMin = document.getElementById("economy-voice-money-min");
|
||||
const voiceMoneyMax = document.getElementById("economy-voice-money-max");
|
||||
const voiceMoneyInterval = document.getElementById("economy-voice-money-interval");
|
||||
|
||||
const statusEconomyForm = document.getElementById("status-economy-form");
|
||||
const saveEconomy = document.getElementById("save-economy");
|
||||
|
||||
// Charger la config existante
|
||||
fetch(`/api/bot/get-economy-config/${guildId}`)
|
||||
@@ -94,60 +93,71 @@ fetch(`/api/bot/get-economy-config/${guildId}`)
|
||||
.catch(console.error);
|
||||
|
||||
// Sauvegarder la config
|
||||
economyForm.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
saveEconomy.addEventListener("click", async () => {
|
||||
saveEconomy.disabled = true;
|
||||
saveEconomy.textContent = "Sauvegarde...";
|
||||
|
||||
const res = await fetch("/api/bot/save-economy-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
economyEnabled: economyEnabled.checked,
|
||||
currencyName: currencyName.value,
|
||||
currencySymbol: currencySymbol.value,
|
||||
startingBalance: parseInt(startingBalance.value, 10),
|
||||
try {
|
||||
const res = await fetch("/api/bot/save-economy-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
economyEnabled: economyEnabled.checked,
|
||||
currencyName: currencyName.value,
|
||||
currencySymbol: currencySymbol.value,
|
||||
startingBalance: parseInt(startingBalance.value, 10),
|
||||
|
||||
// Daily
|
||||
dailyEnabled: dailyEnabled.checked,
|
||||
dailyAmount: parseInt(dailyAmount.value, 10),
|
||||
dailyCooldownHours: parseInt(dailyCooldown.value, 10),
|
||||
// Daily
|
||||
dailyEnabled: dailyEnabled.checked,
|
||||
dailyAmount: parseInt(dailyAmount.value, 10),
|
||||
dailyCooldownHours: parseInt(dailyCooldown.value, 10),
|
||||
|
||||
// Work
|
||||
workEnabled: workEnabled.checked,
|
||||
workMinAmount: parseInt(workMin.value, 10),
|
||||
workMaxAmount: parseInt(workMax.value, 10),
|
||||
workCooldownMinutes: parseInt(workCooldown.value, 10),
|
||||
// Work
|
||||
workEnabled: workEnabled.checked,
|
||||
workMinAmount: parseInt(workMin.value, 10),
|
||||
workMaxAmount: parseInt(workMax.value, 10),
|
||||
workCooldownMinutes: parseInt(workCooldown.value, 10),
|
||||
|
||||
// Crime
|
||||
crimeEnabled: crimeEnabled.checked,
|
||||
crimeMinAmount: parseInt(crimeMin.value, 10),
|
||||
crimeMaxAmount: parseInt(crimeMax.value, 10),
|
||||
crimeSuccessRate: parseInt(crimeSuccess.value, 10),
|
||||
crimeFinePercent: parseInt(crimeFine.value, 10),
|
||||
crimeCooldownMinutes: parseInt(crimeCooldown.value, 10),
|
||||
// Crime
|
||||
crimeEnabled: crimeEnabled.checked,
|
||||
crimeMinAmount: parseInt(crimeMin.value, 10),
|
||||
crimeMaxAmount: parseInt(crimeMax.value, 10),
|
||||
crimeSuccessRate: parseInt(crimeSuccess.value, 10),
|
||||
crimeFinePercent: parseInt(crimeFine.value, 10),
|
||||
crimeCooldownMinutes: parseInt(crimeCooldown.value, 10),
|
||||
|
||||
// Steal
|
||||
stealEnabled: stealEnabled.checked,
|
||||
stealSuccessRate: parseInt(stealSuccess.value, 10),
|
||||
stealMaxPercent: parseInt(stealMaxPercent.value, 10),
|
||||
stealFinePercent: parseInt(stealFine.value, 10),
|
||||
stealCooldownMinutes: parseInt(stealCooldown.value, 10),
|
||||
// Steal
|
||||
stealEnabled: stealEnabled.checked,
|
||||
stealSuccessRate: parseInt(stealSuccess.value, 10),
|
||||
stealMaxPercent: parseInt(stealMaxPercent.value, 10),
|
||||
stealFinePercent: parseInt(stealFine.value, 10),
|
||||
stealCooldownMinutes: parseInt(stealCooldown.value, 10),
|
||||
|
||||
// Message Money
|
||||
messageMoneyEnabled: messageMoneyEnabled.checked,
|
||||
messageMoneyMin: parseInt(messageMoneyMin.value, 10),
|
||||
messageMoneyMax: parseInt(messageMoneyMax.value, 10),
|
||||
messageMoneyCooldownSeconds: parseInt(messageMoneyCooldown.value, 10),
|
||||
// Message Money
|
||||
messageMoneyEnabled: messageMoneyEnabled.checked,
|
||||
messageMoneyMin: parseInt(messageMoneyMin.value, 10),
|
||||
messageMoneyMax: parseInt(messageMoneyMax.value, 10),
|
||||
messageMoneyCooldownSeconds: parseInt(messageMoneyCooldown.value, 10),
|
||||
|
||||
// Voice Money
|
||||
voiceMoneyEnabled: voiceMoneyEnabled.checked,
|
||||
voiceMoneyMin: parseInt(voiceMoneyMin.value, 10),
|
||||
voiceMoneyMax: parseInt(voiceMoneyMax.value, 10),
|
||||
voiceMoneyIntervalMinutes: parseInt(voiceMoneyInterval.value, 10)
|
||||
})
|
||||
});
|
||||
// Voice Money
|
||||
voiceMoneyEnabled: voiceMoneyEnabled.checked,
|
||||
voiceMoneyMin: parseInt(voiceMoneyMin.value, 10),
|
||||
voiceMoneyMax: parseInt(voiceMoneyMax.value, 10),
|
||||
voiceMoneyIntervalMinutes: parseInt(voiceMoneyInterval.value, 10)
|
||||
})
|
||||
});
|
||||
|
||||
statusEconomyForm.textContent = (await res.json()).success
|
||||
? "Config économie sauvegardée ✅"
|
||||
: "Erreur ❌";
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showStatus("status-economy-form", "Configuration sauvegardée ✅", "success");
|
||||
} else {
|
||||
showStatus("status-economy-form", "Erreur lors de la sauvegarde ❌", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
showStatus("status-economy-form", "Erreur de connexion ❌", "error");
|
||||
}
|
||||
|
||||
saveEconomy.disabled = false;
|
||||
saveEconomy.textContent = "Sauvegarder";
|
||||
});
|
||||
|
||||
@@ -1,32 +1,47 @@
|
||||
const goodbyeForm = document.getElementById("goodbye-form");
|
||||
const goodbyeEnabled = document.getElementById("goodbye-enabled");
|
||||
const goodbyeChannel = document.getElementById("goodbye-channel");
|
||||
const goodbyeMessage = document.getElementById("goodbye-message");
|
||||
const statusGoodbyeForm = document.getElementById("status-goodbye-form");
|
||||
const saveGoodbye = document.getElementById("save-goodbye");
|
||||
|
||||
// Message par défaut
|
||||
const defaultGoodbyeMessage = "Au revoir **{user}**, on espère te revoir sur **{server}** ! 👋";
|
||||
|
||||
// Charger la config
|
||||
fetch(`/api/bot/get-goodbye-config/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
goodbyeEnabled.checked = cfg.enabled;
|
||||
goodbyeChannel.value = cfg.channelId;
|
||||
goodbyeMessage.value = cfg.message;
|
||||
goodbyeMessage.value = cfg.message || defaultGoodbyeMessage;
|
||||
});
|
||||
|
||||
goodbyeForm.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
// Sauvegarder
|
||||
saveGoodbye.addEventListener("click", async () => {
|
||||
saveGoodbye.disabled = true;
|
||||
saveGoodbye.textContent = "Sauvegarde...";
|
||||
|
||||
const res = await fetch("/api/bot/save-goodbye-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
goodbyeEnabled: goodbyeEnabled.checked,
|
||||
channelId: goodbyeChannel.value,
|
||||
goodbyeMessage: goodbyeMessage.value
|
||||
})
|
||||
});
|
||||
try {
|
||||
const res = await fetch("/api/bot/save-goodbye-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
goodbyeEnabled: goodbyeEnabled.checked,
|
||||
channelId: goodbyeChannel.value,
|
||||
goodbyeMessage: goodbyeMessage.value
|
||||
})
|
||||
});
|
||||
|
||||
statusGoodbyeForm.textContent = (await res.json()).success
|
||||
? "Config au revoir sauvegardée ✅"
|
||||
: "Erreur ❌";
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showStatus("status-goodbye-form", "Configuration sauvegardée ✅", "success");
|
||||
} else {
|
||||
showStatus("status-goodbye-form", "Erreur lors de la sauvegarde ❌", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
showStatus("status-goodbye-form", "Erreur de connexion ❌", "error");
|
||||
}
|
||||
|
||||
saveGoodbye.disabled = false;
|
||||
saveGoodbye.textContent = "Sauvegarder";
|
||||
});
|
||||
|
||||
@@ -1,12 +1,55 @@
|
||||
window.guildId = window.location.pathname.split("/")[2];
|
||||
|
||||
// Nom du serveur
|
||||
// Charger les infos du bot
|
||||
fetch("/api/bot-info")
|
||||
.then(res => res.json())
|
||||
.then(bot => {
|
||||
const botAvatar = document.getElementById("bot-avatar");
|
||||
if (botAvatar) {
|
||||
botAvatar.src = `https://cdn.discordapp.com/avatars/${bot.id}/${bot.avatar}.png`;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
// Charger les infos utilisateur
|
||||
fetch("/api/user")
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("Non connecté");
|
||||
return res.json();
|
||||
})
|
||||
.then(user => {
|
||||
const avatarUrl = `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`;
|
||||
const userAvatar = document.getElementById("user-avatar");
|
||||
const userName = document.getElementById("user-name");
|
||||
|
||||
if (userAvatar) userAvatar.src = avatarUrl;
|
||||
if (userName) userName.textContent = user.username;
|
||||
})
|
||||
.catch(() => {
|
||||
window.location.href = "/auth/login";
|
||||
});
|
||||
|
||||
// Nom et icône du serveur
|
||||
fetch("/api/guilds")
|
||||
.then(res => res.json())
|
||||
.then(guilds => {
|
||||
const guild = guilds.find(g => g.id === guildId);
|
||||
document.getElementById("guild-name").textContent =
|
||||
guild ? `Dashboard : ${guild.name}` : "Serveur introuvable";
|
||||
const guildName = document.getElementById("guild-name");
|
||||
const guildIcon = document.getElementById("guild-icon");
|
||||
const guildIdEl = document.getElementById("guild-id");
|
||||
const breadcrumbGuild = document.getElementById("breadcrumb-guild");
|
||||
|
||||
if (guild) {
|
||||
if (guildName) guildName.textContent = guild.name;
|
||||
if (breadcrumbGuild) breadcrumbGuild.textContent = guild.name;
|
||||
if (guildIdEl) guildIdEl.textContent = `ID: ${guild.id}`;
|
||||
if (guildIcon && guild.icon) {
|
||||
guildIcon.src = `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png`;
|
||||
}
|
||||
document.title = `${guild.name} - LazyBot`;
|
||||
} else {
|
||||
if (guildName) guildName.textContent = "Serveur introuvable";
|
||||
}
|
||||
});
|
||||
|
||||
// Channels texte
|
||||
@@ -16,12 +59,26 @@ fetch(`/api/bot/get-text-channels/${guildId}`)
|
||||
const welcome = document.getElementById("welcome-channel");
|
||||
const goodbye = document.getElementById("goodbye-channel");
|
||||
const levelAnnouncements = document.getElementById("level-announcements-channel");
|
||||
const levelChannelRestrict = document.getElementById("level-channel-with-or-without-xp");
|
||||
|
||||
channels.forEach(c => {
|
||||
const opt = new Option(`#${c.name}`, c.id);
|
||||
welcome?.appendChild(opt);
|
||||
goodbye?.appendChild(opt.cloneNode(true));
|
||||
levelAnnouncements?.appendChild(opt.cloneNode(true));
|
||||
levelChannelRestrict?.appendChild(opt.cloneNode(true));
|
||||
});
|
||||
});
|
||||
|
||||
// Channels vocaux
|
||||
fetch(`/api/bot/get-voice-channels/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(channels => {
|
||||
const vocalExclude = document.getElementById("autorole-vocal-exclude-channel");
|
||||
|
||||
channels.forEach(c => {
|
||||
const opt = new Option(`🔊 ${c.name}`, c.id);
|
||||
vocalExclude?.appendChild(opt);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,10 +88,12 @@ fetch(`/api/bot/get-roles/${guildId}`)
|
||||
.then(roles => {
|
||||
const newUser = document.getElementById("autorole-role");
|
||||
const vocal = document.getElementById("autorole-vocal-role");
|
||||
const levelRoleRestrict = document.getElementById("level-role-with-or-without-xp");
|
||||
|
||||
roles.forEach(r => {
|
||||
const opt = new Option(r.name, r.id);
|
||||
newUser?.appendChild(opt);
|
||||
vocal?.appendChild(opt.cloneNode(true));
|
||||
levelRoleRestrict?.appendChild(opt.cloneNode(true));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const levelForm = document.getElementById("level-form");
|
||||
const levelEnabled = document.getElementById("level-enabled");
|
||||
const levelAnnouncementsEnabled = document.getElementById("level-announcement-enabled");
|
||||
const levelAnnouncementsChannel = document.getElementById("level-announcements-channel");
|
||||
@@ -18,102 +17,91 @@ const cooldownXpMessageSeconds = document.getElementById("level-xp-cooldown");
|
||||
const gainXpOnVoice = document.getElementById("voice-xp-enabled");
|
||||
const gainVoiceXpLowerBound = document.getElementById("level-xp-per-voice-min");
|
||||
const gainVoiceXpUpperBound = document.getElementById("level-xp-per-voice-max");
|
||||
const statusLevelForm = document.getElementById("status-level-form");
|
||||
const saveLevel = document.getElementById("save-level");
|
||||
|
||||
// 1️⃣ RÔLES
|
||||
fetch(`/api/bot/get-roles/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(roles => {
|
||||
roles.forEach(r => {
|
||||
roleWithWithoutXp?.appendChild(new Option(r.name, r.id));
|
||||
});
|
||||
// Message par défaut
|
||||
const defaultLevelMessage = "Félicitations {mention}, tu es maintenant niveau **{level}** ! 🎉";
|
||||
|
||||
// 2️⃣ SALONS TEXTE
|
||||
return fetch(`/api/bot/get-text-channels/${guildId}`);
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(textSalons => {
|
||||
textSalons.forEach(c => {
|
||||
salonWithWithoutXp?.appendChild(new Option(`#${c.name}`, c.id));
|
||||
});
|
||||
// Charger la config après que les channels/roles soient chargés
|
||||
setTimeout(() => {
|
||||
fetch(`/api/bot/get-level-config/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
levelEnabled.checked = cfg.enabled;
|
||||
levelAnnouncementsEnabled.checked = cfg.levelAnnouncementsEnabled;
|
||||
levelAnnouncementsChannel.value = cfg.levelAnnouncementsChannelId;
|
||||
levelAnnouncementsMessage.value = cfg.levelAnnouncementsMessage || defaultLevelMessage;
|
||||
|
||||
// 3️⃣ SALONS VOCAUX
|
||||
return fetch(`/api/bot/get-voice-channels/${guildId}`);
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(voiceSalons => {
|
||||
voiceSalons.forEach(c => {
|
||||
salonWithWithoutXp?.appendChild(new Option(`🔊 ${c.name}`, c.id));
|
||||
});
|
||||
xpCourbeType.value = cfg.xpCourbeType;
|
||||
multiplierCourbeForLevel.value = cfg.multiplierCourbeForLevel;
|
||||
levelAnnouncementEveryLevel.value = cfg.levelAnnouncementEveryLevel;
|
||||
levelMax.value = cfg.levelMax;
|
||||
|
||||
// 4️⃣ CONFIG (APRÈS QUE TOUT EST CHARGÉ)
|
||||
return fetch(`/api/bot/get-level-config/${guildId}`);
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
levelEnabled.checked = cfg.enabled;
|
||||
levelAnnouncementsEnabled.checked = cfg.levelAnnouncementsEnabled;
|
||||
levelAnnouncementsChannel.value = cfg.levelAnnouncementsChannelId;
|
||||
levelAnnouncementsMessage.value = cfg.levelAnnouncementsMessage;
|
||||
roleWithWithoutType.value = cfg.roleWithWithoutType;
|
||||
Array.from(roleWithWithoutXp.options).forEach(opt => {
|
||||
opt.selected = cfg.roleWithWithoutXp?.includes(opt.value);
|
||||
});
|
||||
|
||||
xpCourbeType.value = cfg.xpCourbeType;
|
||||
multiplierCourbeForLevel.value = cfg.multiplierCourbeForLevel;
|
||||
levelAnnouncementEveryLevel.value = cfg.levelAnnouncementEveryLevel;
|
||||
levelMax.value = cfg.levelMax;
|
||||
salonWithWithoutType.value = cfg.salonWithWithoutType;
|
||||
Array.from(salonWithWithoutXp.options).forEach(opt => {
|
||||
opt.selected = cfg.salonWithWithoutXp?.includes(opt.value);
|
||||
});
|
||||
|
||||
roleWithWithoutType.value = cfg.roleWithWithoutType;
|
||||
Array.from(roleWithWithoutXp.options).forEach(opt => {
|
||||
opt.selected = cfg.roleWithWithoutXp?.includes(opt.value);
|
||||
});
|
||||
gainXpOnMessage.checked = cfg.gainXpOnMessage;
|
||||
gainXpMessageLowerBound.value = cfg.gainXpMessageLowerBound;
|
||||
gainXpMessageUpperBound.value = cfg.gainXpMessageUpperBound;
|
||||
cooldownXpMessageSeconds.value = cfg.cooldownXpMessageSeconds;
|
||||
|
||||
salonWithWithoutType.value = cfg.salonWithWithoutType;
|
||||
Array.from(salonWithWithoutXp.options).forEach(opt => {
|
||||
opt.selected = cfg.salonWithWithoutXp?.includes(opt.value);
|
||||
});
|
||||
|
||||
gainXpOnMessage.checked = cfg.gainXpOnMessage;
|
||||
gainXpMessageLowerBound.value = cfg.gainXpMessageLowerBound;
|
||||
gainXpMessageUpperBound.value = cfg.gainXpMessageUpperBound;
|
||||
cooldownXpMessageSeconds.value = cfg.cooldownXpMessageSeconds;
|
||||
|
||||
gainXpOnVoice.checked = cfg.gainXpOnVoice;
|
||||
gainVoiceXpLowerBound.value = cfg.gainVoiceXpLowerBound;
|
||||
gainVoiceXpUpperBound.value = cfg.gainVoiceXpUpperBound;
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
|
||||
levelForm.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
|
||||
const res = await fetch("/api/bot/save-level-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
levelEnabled: levelEnabled.checked,
|
||||
levelAnnouncementsEnabled: levelAnnouncementsEnabled.checked,
|
||||
levelAnnouncementsChannelId: levelAnnouncementsChannel.value,
|
||||
levelAnnouncementsMessage: levelAnnouncementsMessage.value,
|
||||
xpCourbeType: xpCourbeType.value,
|
||||
multiplierCourbeForLevel: parseInt(multiplierCourbeForLevel.value, 10),
|
||||
levelAnnouncementEveryLevel: parseInt(levelAnnouncementEveryLevel.value, 10),
|
||||
levelMax: parseInt(levelMax.value, 10),
|
||||
roleWithWithoutType: roleWithWithoutType.value,
|
||||
roleWithWithoutXp: Array.from(roleWithWithoutXp.selectedOptions).map(opt => opt.value),
|
||||
salonWithWithoutType: salonWithWithoutType.value,
|
||||
salonWithWithoutXp: Array.from(salonWithWithoutXp.selectedOptions).map(opt => opt.value),
|
||||
gainXpOnMessage: gainXpOnMessage.checked,
|
||||
gainXpMessageLowerBound: parseInt(gainXpMessageLowerBound.value, 10),
|
||||
gainXpMessageUpperBound: parseInt(gainXpMessageUpperBound.value, 10),
|
||||
cooldownXpMessageSeconds: parseInt(cooldownXpMessageSeconds.value, 10),
|
||||
gainXpOnVoice: gainXpOnVoice.checked,
|
||||
gainVoiceXpLowerBound: parseInt(gainVoiceXpLowerBound.value, 10),
|
||||
gainVoiceXpUpperBound: parseInt(gainVoiceXpUpperBound.value, 10)
|
||||
gainXpOnVoice.checked = cfg.gainXpOnVoice;
|
||||
gainVoiceXpLowerBound.value = cfg.gainVoiceXpLowerBound;
|
||||
gainVoiceXpUpperBound.value = cfg.gainVoiceXpUpperBound;
|
||||
})
|
||||
});
|
||||
.catch(console.error);
|
||||
}, 500);
|
||||
|
||||
statusLevelForm.textContent = (await res.json()).success
|
||||
? "Config niveaux sauvegardée ✅"
|
||||
: "Erreur ❌";
|
||||
// Sauvegarder
|
||||
saveLevel.addEventListener("click", async () => {
|
||||
saveLevel.disabled = true;
|
||||
saveLevel.textContent = "Sauvegarde...";
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/bot/save-level-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
levelEnabled: levelEnabled.checked,
|
||||
levelAnnouncementsEnabled: levelAnnouncementsEnabled.checked,
|
||||
levelAnnouncementsChannelId: levelAnnouncementsChannel.value,
|
||||
levelAnnouncementsMessage: levelAnnouncementsMessage.value,
|
||||
xpCourbeType: xpCourbeType.value,
|
||||
multiplierCourbeForLevel: parseInt(multiplierCourbeForLevel.value, 10),
|
||||
levelAnnouncementEveryLevel: parseInt(levelAnnouncementEveryLevel.value, 10),
|
||||
levelMax: parseInt(levelMax.value, 10),
|
||||
roleWithWithoutType: roleWithWithoutType.value,
|
||||
roleWithWithoutXp: Array.from(roleWithWithoutXp.selectedOptions).map(opt => opt.value),
|
||||
salonWithWithoutType: salonWithWithoutType.value,
|
||||
salonWithWithoutXp: Array.from(salonWithWithoutXp.selectedOptions).map(opt => opt.value),
|
||||
gainXpOnMessage: gainXpOnMessage.checked,
|
||||
gainXpMessageLowerBound: parseInt(gainXpMessageLowerBound.value, 10),
|
||||
gainXpMessageUpperBound: parseInt(gainXpMessageUpperBound.value, 10),
|
||||
cooldownXpMessageSeconds: parseInt(cooldownXpMessageSeconds.value, 10),
|
||||
gainXpOnVoice: gainXpOnVoice.checked,
|
||||
gainVoiceXpLowerBound: parseInt(gainVoiceXpLowerBound.value, 10),
|
||||
gainVoiceXpUpperBound: parseInt(gainVoiceXpUpperBound.value, 10)
|
||||
})
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showStatus("status-level-form", "Configuration sauvegardée ✅", "success");
|
||||
} else {
|
||||
showStatus("status-level-form", "Erreur lors de la sauvegarde ❌", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
showStatus("status-level-form", "Erreur de connexion ❌", "error");
|
||||
}
|
||||
|
||||
saveLevel.disabled = false;
|
||||
saveLevel.textContent = "Sauvegarder";
|
||||
});
|
||||
@@ -0,0 +1,100 @@
|
||||
// Navigation sidebar avec hash routing
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const navItems = document.querySelectorAll('.nav-item[data-section]');
|
||||
const sections = document.querySelectorAll('.config-section');
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const mobileToggle = document.getElementById('mobile-toggle');
|
||||
|
||||
// Fonction pour changer de section
|
||||
function showSection(sectionId) {
|
||||
// Masquer toutes les sections
|
||||
sections.forEach(section => {
|
||||
section.classList.remove('active');
|
||||
});
|
||||
|
||||
// Retirer la classe active de tous les nav items
|
||||
navItems.forEach(item => {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
|
||||
// Afficher la section cible
|
||||
const targetSection = document.getElementById(`section-${sectionId}`);
|
||||
if (targetSection) {
|
||||
targetSection.classList.add('active');
|
||||
}
|
||||
|
||||
// Activer le nav item correspondant
|
||||
const targetNav = document.querySelector(`.nav-item[data-section="${sectionId}"]`);
|
||||
if (targetNav) {
|
||||
targetNav.classList.add('active');
|
||||
}
|
||||
|
||||
// Fermer la sidebar sur mobile
|
||||
if (window.innerWidth <= 900) {
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
|
||||
// Mettre à jour l'URL
|
||||
window.location.hash = sectionId;
|
||||
}
|
||||
|
||||
// Ajouter les listeners sur les nav items
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const sectionId = item.dataset.section;
|
||||
showSection(sectionId);
|
||||
});
|
||||
});
|
||||
|
||||
// Gérer le hash au chargement de la page
|
||||
function handleHash() {
|
||||
const hash = window.location.hash.slice(1); // Enlever le #
|
||||
if (hash && document.getElementById(`section-${hash}`)) {
|
||||
showSection(hash);
|
||||
} else {
|
||||
// Par défaut, afficher la première section
|
||||
const firstNavItem = navItems[0];
|
||||
if (firstNavItem) {
|
||||
showSection(firstNavItem.dataset.section);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Écouter les changements de hash
|
||||
window.addEventListener('hashchange', handleHash);
|
||||
|
||||
// Charger la section initiale
|
||||
handleHash();
|
||||
|
||||
// Toggle sidebar sur mobile
|
||||
if (mobileToggle) {
|
||||
mobileToggle.addEventListener('click', () => {
|
||||
sidebar.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Fermer la sidebar en cliquant à l'extérieur sur mobile
|
||||
document.addEventListener('click', (e) => {
|
||||
if (window.innerWidth <= 900) {
|
||||
if (!sidebar.contains(e.target) && !mobileToggle.contains(e.target)) {
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Helper function pour afficher les messages de statut
|
||||
window.showStatus = function(elementId, message, type = 'success') {
|
||||
const element = document.getElementById(elementId);
|
||||
if (element) {
|
||||
element.textContent = message;
|
||||
element.className = `status-message show ${type}`;
|
||||
|
||||
// Masquer après 5 secondes
|
||||
setTimeout(() => {
|
||||
element.classList.remove('show');
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
@@ -1,32 +1,47 @@
|
||||
const welcomeForm = document.getElementById("welcome-form");
|
||||
const welcomeEnabled = document.getElementById("welcome-enabled");
|
||||
const welcomeChannel = document.getElementById("welcome-channel");
|
||||
const welcomeMessage = document.getElementById("welcome-message");
|
||||
const statusWelcomeForm = document.getElementById("status-welcome-form");
|
||||
const saveWelcome = document.getElementById("save-welcome");
|
||||
|
||||
// Message par défaut
|
||||
const defaultWelcomeMessage = "Bienvenue {mention} sur **{server}** ! 🎉";
|
||||
|
||||
// Charger la config
|
||||
fetch(`/api/bot/get-welcome-config/${guildId}`)
|
||||
.then(res => res.json())
|
||||
.then(cfg => {
|
||||
welcomeEnabled.checked = cfg.enabled;
|
||||
welcomeChannel.value = cfg.channelId;
|
||||
welcomeMessage.value = cfg.message;
|
||||
welcomeMessage.value = cfg.message || defaultWelcomeMessage;
|
||||
});
|
||||
|
||||
welcomeForm.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
// Sauvegarder
|
||||
saveWelcome.addEventListener("click", async () => {
|
||||
saveWelcome.disabled = true;
|
||||
saveWelcome.textContent = "Sauvegarde...";
|
||||
|
||||
const res = await fetch("/api/bot/save-welcome-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
welcomeEnabled: welcomeEnabled.checked,
|
||||
channelId: welcomeChannel.value,
|
||||
welcomeMessage: welcomeMessage.value
|
||||
})
|
||||
});
|
||||
try {
|
||||
const res = await fetch("/api/bot/save-welcome-config", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
guildId,
|
||||
welcomeEnabled: welcomeEnabled.checked,
|
||||
channelId: welcomeChannel.value,
|
||||
welcomeMessage: welcomeMessage.value
|
||||
})
|
||||
});
|
||||
|
||||
statusWelcomeForm.textContent = (await res.json()).success
|
||||
? "Config bienvenue sauvegardée ✅"
|
||||
: "Erreur ❌";
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showStatus("status-welcome-form", "Configuration sauvegardée ✅", "success");
|
||||
} else {
|
||||
showStatus("status-welcome-form", "Erreur lors de la sauvegarde ❌", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
showStatus("status-welcome-form", "Erreur de connexion ❌", "error");
|
||||
}
|
||||
|
||||
saveWelcome.disabled = false;
|
||||
saveWelcome.textContent = "Sauvegarder";
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user