🔒 Add privacy settings for leaderboard visibility

 Features:
- Added show_in_leaderboard column to players table (default: false)
- Replaced Quick Actions with Settings section in dashboard
- Added toggle switch for leaderboard visibility
- Created settings modal with privacy controls

🔧 API Changes:
- Added /api/v1/private/update-player-settings endpoint
- Updated best-times queries to filter by show_in_leaderboard
- Updated times-with-details to respect privacy settings
- Added updated_at column to players table

🎨 UI/UX:
- Modern toggle switch design
- Responsive settings modal
- Success/error notifications
- Clear privacy explanation

🔐 Privacy:
- Default: Times are NOT shown in global leaderboard
- Users can opt-in via settings
- Personal dashboard always shows own times
- Global leaderboard only shows opted-in users
This commit is contained in:
2025-09-08 19:14:17 +02:00
parent ecb6291c74
commit 70ceb2da25
4 changed files with 304 additions and 3 deletions

View File

@@ -941,6 +941,105 @@ setInterval(() => {
checkAchievementNotifications();
}, 30000);
// Settings Functions
function showSettings() {
const modal = document.getElementById('settingsModal');
if (modal) {
modal.style.display = 'block';
loadSettings();
}
}
async function loadSettings() {
try {
if (!currentPlayerId) {
console.error('No player ID available');
return;
}
// Load current player settings
const response = await fetch(`/api/v1/public/user-player/${currentUser.id}`);
const result = await response.json();
if (result.success && result.data) {
const showInLeaderboard = result.data.show_in_leaderboard || false;
document.getElementById('showInLeaderboard').checked = showInLeaderboard;
}
} catch (error) {
console.error('Error loading settings:', error);
}
}
function updateLeaderboardSetting() {
const checkbox = document.getElementById('showInLeaderboard');
console.log('Leaderboard setting changed:', checkbox.checked);
}
async function saveSettings() {
try {
if (!currentPlayerId) {
console.error('No player ID available');
return;
}
const showInLeaderboard = document.getElementById('showInLeaderboard').checked;
// Update player settings
const response = await fetch(`/api/v1/private/update-player-settings`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('apiKey')}`
},
body: JSON.stringify({
player_id: currentPlayerId,
show_in_leaderboard: showInLeaderboard
})
});
const result = await response.json();
if (result.success) {
showNotification('Einstellungen erfolgreich gespeichert!', 'success');
closeModal('settingsModal');
} else {
showNotification('Fehler beim Speichern der Einstellungen: ' + result.message, 'error');
}
} catch (error) {
console.error('Error saving settings:', error);
showNotification('Fehler beim Speichern der Einstellungen', 'error');
}
}
function showNotification(message, type = 'info') {
// Create notification element
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'};
color: white;
padding: 1rem 1.5rem;
border-radius: 0.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
z-index: 10000;
max-width: 300px;
font-weight: 500;
`;
notification.textContent = message;
document.body.appendChild(notification);
// Remove notification after 3 seconds
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 3000);
}
document.addEventListener('DOMContentLoaded', function() {
// Add cookie settings button functionality
const cookieSettingsBtn = document.getElementById('cookie-settings-footer');