269 lines
9.1 KiB
JavaScript
269 lines
9.1 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
initTheme();
|
|
initTabs();
|
|
initForms();
|
|
updateTokenDisplay();
|
|
});
|
|
|
|
// Gestion du thème
|
|
function initTheme() {
|
|
const body = document.body;
|
|
const themeSwitcher = document.getElementById('themeSwitcher');
|
|
|
|
function setTheme(theme) {
|
|
if (theme === 'dark') {
|
|
body.classList.add('dark');
|
|
} else {
|
|
body.classList.remove('dark');
|
|
}
|
|
localStorage.setItem('theme', theme);
|
|
updateThemeIcon(theme);
|
|
}
|
|
|
|
function updateThemeIcon(theme) {
|
|
const icon = themeSwitcher.querySelector('i');
|
|
icon.className = theme === 'dark' ? 'fas fa-moon' : 'fas fa-sun';
|
|
}
|
|
|
|
const savedTheme = localStorage.getItem('theme');
|
|
if (savedTheme) {
|
|
setTheme(savedTheme);
|
|
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
setTheme('dark');
|
|
}
|
|
|
|
themeSwitcher.addEventListener('click', () => {
|
|
setTheme(body.classList.contains('dark') ? 'light' : 'dark');
|
|
});
|
|
}
|
|
|
|
// Gestion des onglets
|
|
function initTabs() {
|
|
const tabs = document.querySelectorAll('.tab');
|
|
tabs.forEach(tab => {
|
|
tab.addEventListener('click', () => switchTab(tab));
|
|
});
|
|
}
|
|
|
|
function switchTab(selectedTab) {
|
|
document.querySelectorAll('.tab, .tab-content').forEach(el => {
|
|
el.classList.remove('active');
|
|
});
|
|
|
|
selectedTab.classList.add('active');
|
|
const targetContent = document.querySelector(`[data-tab-content="${selectedTab.dataset.tab}"]`);
|
|
targetContent.classList.add('active');
|
|
}
|
|
|
|
// Gestion des formulaires et actions
|
|
function initForms() {
|
|
const profileCustomizationForm = document.getElementById('profileCustomization');
|
|
|
|
if (profileCustomizationForm) {
|
|
profileCustomizationForm.addEventListener('submit', handleProfileCustomizationUpdate);
|
|
}
|
|
}
|
|
|
|
async function handleProfileCustomizationUpdate(e) {
|
|
e.preventDefault();
|
|
const wallpaperUrl = document.getElementById('wallpaperUrl').value;
|
|
const profilePictureUrl = document.getElementById('profilePictureUrl').value;
|
|
|
|
try {
|
|
let promises = []; // Mise à jour du fond d'écran si l'URL est fournie
|
|
if (wallpaperUrl && wallpaperUrl.trim()) {
|
|
promises.push(
|
|
fetch('/api/dpanel/dashboard/backgroundcustom/wallpaper', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
wallpaperUrl: wallpaperUrl
|
|
})
|
|
})
|
|
);
|
|
}
|
|
|
|
// Mise à jour de la photo de profil si l'URL est fournie
|
|
if (profilePictureUrl && profilePictureUrl.trim()) {
|
|
promises.push(
|
|
fetch('/api/dpanel/dashboard/profilpicture', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
profilePictureUrl: profilePictureUrl
|
|
})
|
|
})
|
|
);
|
|
}
|
|
|
|
if (promises.length === 0) {
|
|
showToast('error', 'Veuillez remplir au moins un champ');
|
|
return;
|
|
}
|
|
|
|
// Attendre toutes les requêtes
|
|
const responses = await Promise.all(promises);
|
|
// Vérifier toutes les réponses
|
|
let wallpaperData = null;
|
|
let profilePictureData = null;
|
|
|
|
for (let i = 0; i < responses.length; i++) {
|
|
const response = responses[i];
|
|
|
|
// Vérifier le type de contenu
|
|
const contentType = response.headers.get('content-type');
|
|
if (!contentType || !contentType.includes('application/json')) {
|
|
throw new Error('Le serveur a renvoyé une réponse non-JSON. Vérifiez votre authentification.');
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
throw new Error(data.error || `Erreur ${response.status}: ${response.statusText}`);
|
|
}
|
|
|
|
// Identifier quelle réponse correspond à quoi
|
|
if (data.wallpaper) {
|
|
wallpaperData = data;
|
|
} else if (data.profilePicture) {
|
|
profilePictureData = data;
|
|
}
|
|
}
|
|
|
|
// Appliquer les changements visuels
|
|
if (wallpaperData) {
|
|
document.body.style.backgroundImage = `url('${wallpaperData.wallpaper}')`;
|
|
}
|
|
|
|
if (profilePictureData) {
|
|
const profileImages = document.querySelectorAll('.avatar-container img, .profile-picture img, .user-avatar');
|
|
profileImages.forEach(img => {
|
|
img.src = profilePictureData.profilePicture;
|
|
});
|
|
}
|
|
|
|
showToast('success', 'Profil mis à jour avec succès');
|
|
|
|
// Vider les champs après la mise à jour réussie
|
|
document.getElementById('wallpaperUrl').value = '';
|
|
document.getElementById('profilePictureUrl').value = '';
|
|
|
|
} catch (error) {
|
|
showToast('error', error.message);
|
|
}
|
|
}
|
|
|
|
// Fonctions utilitaires
|
|
function maskToken(token) {
|
|
if (!token || token === 'Aucun token') return 'Aucun token';
|
|
// Prendre les 8 premiers caractères et remplacer le reste par des points
|
|
return token.substring(0, 8) + '••••••••••••';
|
|
}
|
|
|
|
function updateTokenDisplay() {
|
|
const tokenDisplay = document.querySelector('.token-display code');
|
|
const fullToken = tokenDisplay.getAttribute('data-full-token');
|
|
|
|
if (!fullToken || fullToken === 'Aucun token') {
|
|
tokenDisplay.textContent = 'Aucun token';
|
|
} else {
|
|
// Afficher la version masquée mais conserver le token complet dans data-full-token
|
|
tokenDisplay.textContent = maskToken(fullToken);
|
|
}
|
|
}
|
|
|
|
function copyToken() {
|
|
const tokenElement = document.querySelector('.token-display code');
|
|
const fullToken = tokenElement.getAttribute('data-full-token'); // Récupère le token complet depuis l'attribut data-full-token
|
|
|
|
if (!fullToken || fullToken === 'Aucun token') {
|
|
showToast('error', 'Aucun token à copier');
|
|
return;
|
|
}
|
|
|
|
// Copier le token complet, pas le texte affiché
|
|
navigator.clipboard.writeText(fullToken);
|
|
showToast('success', 'Token complet copié !');
|
|
}
|
|
|
|
async function regenerateToken() {
|
|
const userName = document.querySelector('meta[name="user-name"]').content;
|
|
const userId = document.querySelector('meta[name="user-id"]').content;
|
|
|
|
const result = await Swal.fire({
|
|
title: 'Êtes-vous sûr ?',
|
|
text: "Cette action va générer un nouveau token",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#3085d6',
|
|
cancelButtonColor: '#d33',
|
|
confirmButtonText: 'Oui, continuer',
|
|
cancelButtonText: 'Annuler'
|
|
});
|
|
|
|
if (result.isConfirmed) {
|
|
try {
|
|
const response = await fetch('/api/dpanel/generate-token', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
name: userName,
|
|
id: userId
|
|
})
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.token) {
|
|
const tokenDisplay = document.querySelector('.token-display code');
|
|
// D'abord stocker le token complet dans l'attribut
|
|
tokenDisplay.setAttribute('data-full-token', data.token);
|
|
// Ensuite afficher la version masquée
|
|
tokenDisplay.textContent = maskToken(data.token);
|
|
|
|
// Mettre à jour les boutons
|
|
const securityContent = document.querySelector('[data-tab-content="security"] .settings-card-content .flex');
|
|
securityContent.innerHTML = `
|
|
<button onclick="copyToken()" class="btn btn-secondary flex-1">
|
|
<i class="fas fa-copy mr-2"></i>Copier
|
|
</button>
|
|
<button onclick="regenerateToken()" class="btn btn-warning flex-1">
|
|
<i class="fas fa-sync-alt mr-2"></i>Régénérer
|
|
</button>
|
|
`;
|
|
|
|
// Copier le token complet
|
|
navigator.clipboard.writeText(data.token);
|
|
|
|
Swal.fire({
|
|
title: 'Token généré avec succès',
|
|
text: 'Le token complet a été copié dans votre presse-papiers.',
|
|
icon: 'success',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
} else {
|
|
throw new Error(data.error || 'Erreur lors de la génération du token');
|
|
}
|
|
} catch (error) {
|
|
Swal.fire('Erreur', error.message, 'error');
|
|
}
|
|
}
|
|
}
|
|
|
|
function showToast(icon, title) {
|
|
Swal.fire({
|
|
icon,
|
|
title,
|
|
toast: true,
|
|
position: 'top-end',
|
|
showConfirmButton: false,
|
|
timer: 3000
|
|
});
|
|
}
|