Diverse Fixes nach refactoring
This commit is contained in:
@@ -105,24 +105,97 @@ body {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================================
|
||||||
|
NAVIGATION BUTTONS - COMPLETE REDESIGN
|
||||||
|
============================================================================ */
|
||||||
|
|
||||||
|
/* Base button styles */
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary button (Dashboard) */
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
background: linear-gradient(135deg, #00d4ff, #0891b2);
|
background: #2563eb;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
|
background: #1d4ed8;
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 10px 25px rgba(0, 212, 255, 0.3);
|
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Logout button */
|
||||||
.btn-logout {
|
.btn-logout {
|
||||||
background: linear-gradient(135deg, #dc3545, #c82333);
|
background: #dc2626;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-logout:hover {
|
.btn-logout:hover {
|
||||||
|
background: #b91c1c;
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 10px 25px rgba(220, 53, 69, 0.3);
|
box-shadow: 0 4px 12px rgba(220, 38, 38, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile navigation container */
|
||||||
|
.mobile-nav-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin: 1rem 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Login button */
|
||||||
|
.admin-login-btn {
|
||||||
|
background: #f59e0b;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-login-btn:hover {
|
||||||
|
background: #d97706;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dashboard button */
|
||||||
|
.dashboard-btn {
|
||||||
|
background: #2563eb;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-btn:hover {
|
||||||
|
background: #1d4ed8;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logout button */
|
||||||
|
.logout-btn {
|
||||||
|
background: #dc2626;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-btn:hover {
|
||||||
|
background: #b91c1c;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(220, 38, 38, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-grid {
|
.dashboard-grid {
|
||||||
|
|||||||
@@ -32,6 +32,70 @@ body {
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mobile Navigation Buttons */
|
||||||
|
.mobile-nav-buttons {
|
||||||
|
position: fixed;
|
||||||
|
top: 2rem;
|
||||||
|
right: 2rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .admin-login-btn,
|
||||||
|
.mobile-nav-buttons .dashboard-btn,
|
||||||
|
.mobile-nav-buttons .logout-btn {
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .admin-login-btn {
|
||||||
|
background: #f59e0b;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .dashboard-btn {
|
||||||
|
background: #2563eb;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .logout-btn {
|
||||||
|
background: #dc2626;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .admin-login-btn:hover,
|
||||||
|
.mobile-nav-buttons .dashboard-btn:hover,
|
||||||
|
.mobile-nav-buttons .logout-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .admin-login-btn:hover {
|
||||||
|
background: #d97706;
|
||||||
|
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .dashboard-btn:hover {
|
||||||
|
background: #1d4ed8;
|
||||||
|
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-buttons .logout-btn:hover {
|
||||||
|
background: #b91c1c;
|
||||||
|
box-shadow: 0 4px 12px rgba(220, 38, 38, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
.language-selector select {
|
.language-selector select {
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
background: rgba(15, 23, 42, 0.9);
|
background: rgba(15, 23, 42, 0.9);
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
<title>SPEEDRUN ARENA - Admin Dashboard</title>
|
<title>SPEEDRUN ARENA - Admin Dashboard</title>
|
||||||
<link rel="icon" type="image/x-icon" href="/pictures/favicon.ico">
|
<link rel="icon" type="image/x-icon" href="/pictures/favicon.ico">
|
||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/manifest.json">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
<meta name="apple-mobile-web-app-title" content="Ninja Cross">
|
<meta name="apple-mobile-web-app-title" content="Ninja Cross">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<link rel="icon" type="image/x-icon" href="/pictures/favicon.ico">
|
<link rel="icon" type="image/x-icon" href="/pictures/favicon.ico">
|
||||||
<script src="/js/page-tracking.js"></script>
|
<script src="/js/page-tracking.js"></script>
|
||||||
<script src="/js/cookie-utils.js"></script>
|
<script src="/js/cookie-utils.js"></script>
|
||||||
<link rel="stylesheet" href="/css/leaderboard.css">
|
<link rel="stylesheet" href="/css/index.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Notification Bubble -->
|
<!-- Notification Bubble -->
|
||||||
@@ -138,6 +138,6 @@
|
|||||||
|
|
||||||
<!-- Application JavaScript -->
|
<!-- Application JavaScript -->
|
||||||
<script src="/js/cookie-consent.js"></script>
|
<script src="/js/cookie-consent.js"></script>
|
||||||
<script src="/js/leaderboard.js"></script>
|
<script src="/js/index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ async function initDashboard() {
|
|||||||
|
|
||||||
// User is authenticated, show dashboard
|
// User is authenticated, show dashboard
|
||||||
if (session.user) {
|
if (session.user) {
|
||||||
console.log('User data:', session.user);
|
|
||||||
currentUser = session.user;
|
currentUser = session.user;
|
||||||
displayUserInfo(session.user);
|
displayUserInfo(session.user);
|
||||||
} else {
|
} else {
|
||||||
@@ -1041,6 +1041,8 @@ async function loadPlayerAchievements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
|
|
||||||
window.allAchievements = result.data;
|
window.allAchievements = result.data;
|
||||||
playerAchievements = result.data.filter(achievement => achievement.is_completed);
|
playerAchievements = result.data.filter(achievement => achievement.is_completed);
|
||||||
|
|
||||||
@@ -1126,10 +1128,6 @@ function displayAchievements() {
|
|||||||
// Translate achievement
|
// Translate achievement
|
||||||
const translatedAchievement = translateAchievement(achievement);
|
const translatedAchievement = translateAchievement(achievement);
|
||||||
|
|
||||||
// Debug logging
|
|
||||||
if (achievement.name === 'Tageskönig') {
|
|
||||||
console.log('Tageskönig Debug:', { isCompleted, progress, earnedAt, completionCount });
|
|
||||||
}
|
|
||||||
|
|
||||||
let progressText = '';
|
let progressText = '';
|
||||||
if (isCompleted) {
|
if (isCompleted) {
|
||||||
@@ -1155,6 +1153,7 @@ function displayAchievements() {
|
|||||||
const pointsText = currentLanguage === 'de' ? 'Punkte' : 'Points';
|
const pointsText = currentLanguage === 'de' ? 'Punkte' : 'Points';
|
||||||
const totalPoints = completionCount > 0 ? achievement.points * completionCount : achievement.points;
|
const totalPoints = completionCount > 0 ? achievement.points * completionCount : achievement.points;
|
||||||
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="achievement-card ${isCompleted ? 'completed' : 'incomplete'}"
|
<div class="achievement-card ${isCompleted ? 'completed' : 'incomplete'}"
|
||||||
onclick="showAchievementDetails('${achievement.id}')">
|
onclick="showAchievementDetails('${achievement.id}')">
|
||||||
|
|||||||
BIN
public/pictures/icon-192.png
Normal file
BIN
public/pictures/icon-192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
@@ -3457,11 +3457,11 @@ router.get('/achievements/player/:playerId', async (req, res) => {
|
|||||||
MAX(pa.earned_at) as earned_at,
|
MAX(pa.earned_at) as earned_at,
|
||||||
COUNT(pa.id) as completion_count
|
COUNT(pa.id) as completion_count
|
||||||
FROM achievements a
|
FROM achievements a
|
||||||
LEFT JOIN player_achievements pa ON a.id = pa.achievement_id AND pa.player_id = $1 AND pa.is_completed = true
|
LEFT JOIN player_achievements pa ON a.id = pa.achievement_id AND pa.player_id = $1
|
||||||
WHERE a.is_active = true
|
WHERE a.is_active = true
|
||||||
GROUP BY a.id, a.name, a.name_en, a.description, a.description_en, a.category, a.icon, a.points
|
GROUP BY a.id, a.name, a.name_en, a.description, a.description_en, a.category, a.icon, a.points
|
||||||
ORDER BY
|
ORDER BY
|
||||||
is_completed DESC,
|
COALESCE(COUNT(pa.id) > 0, false) DESC,
|
||||||
a.category,
|
a.category,
|
||||||
a.points DESC
|
a.points DESC
|
||||||
`, [playerId]);
|
`, [playerId]);
|
||||||
@@ -3549,8 +3549,11 @@ router.post('/achievements/check/:playerId', async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run achievement check
|
// Run achievement check using AchievementSystem
|
||||||
await pool.query('SELECT check_all_achievements($1)', [playerId]);
|
const AchievementSystem = require('../lib/achievementSystem');
|
||||||
|
const achievementSystem = new AchievementSystem();
|
||||||
|
await achievementSystem.loadAchievements();
|
||||||
|
const newAchievementsFromCheck = await achievementSystem.checkAllAchievements(playerId);
|
||||||
|
|
||||||
// Get newly earned achievements
|
// Get newly earned achievements
|
||||||
const newAchievements = await pool.query(`
|
const newAchievements = await pool.query(`
|
||||||
|
|||||||
Reference in New Issue
Block a user