Update v1.1.1-beta1
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing

This commit is contained in:
2025-06-14 22:01:39 +02:00
parent 440cc4b9eb
commit de8c5ccb84
24 changed files with 8037 additions and 1292 deletions

2169
public/js/dashboard-old.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

268
public/js/profile.script.js Normal file
View File

@@ -0,0 +1,268 @@
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
});
}