diff --git a/achievements.js b/achievements.js
new file mode 100644
index 0000000..a60f93d
--- /dev/null
+++ b/achievements.js
@@ -0,0 +1,168 @@
+// Achievement system
+const ACHIEVEMENTS = {
+ "first_visit": {
+ name: "Nováček",
+ description: "První návštěva na portálu",
+ icon: "fa-star",
+ color: "text-yellow-500"
+ },
+ "frequent_visitor": {
+ name: "Pravidelný návštěvník",
+ description: "10 návštěv za měsíc",
+ icon: "fa-clock-rotate-left",
+ color: "text-blue-500",
+ threshold: 10,
+ period: "monthly"
+ },
+ "power_user": {
+ name: "Power User",
+ description: "50 návštěv za měsíc",
+ icon: "fa-rocket",
+ color: "text-purple-500",
+ threshold: 50,
+ period: "monthly"
+ },
+ "super_fan": {
+ name: "Super Fan",
+ description: "100 návštěv za měsíc",
+ icon: "fa-award",
+ color: "text-gold",
+ threshold: 100,
+ period: "monthly"
+ }
+};
+
+let achievementsEnabled = false;
+
+// Hidden toggle for achievements
+function toggleAchievements() {
+ achievementsEnabled = !achievementsEnabled;
+ localStorage.setItem('achievementsEnabled', achievementsEnabled);
+
+ if (achievementsEnabled) {
+ checkAchievements();
+ showAchievements();
+ } else {
+ hideAchievements();
+ }
+}
+
+// Check if user has earned achievements
+async function checkAchievements() {
+ try {
+ const response = await fetch('/api/visitor-stats');
+ const stats = await response.json();
+
+ // Check for monthly achievements
+ Object.values(ACHIEVEMENTS).forEach(achievement => {
+ if (achievement.period === "monthly" && stats.monthly_visits >= achievement.threshold) {
+ showAchievementToast(achievement);
+ }
+ });
+
+ // First visit achievement
+ if (stats.total_visits === 1) {
+ showAchievementToast(ACHIEVEMENTS.first_visit);
+ }
+ } catch (error) {
+ console.error('Error checking achievements:', error);
+ }
+}
+
+// Show achievement toast
+function showAchievementToast(achievement) {
+ const toast = document.createElement('div');
+ toast.className = `fixed bottom-4 right-4 bg-white rounded-lg shadow-lg p-4 w-64 flex items-center ${achievement.color}`;
+
+ toast.innerHTML = `
+
+
${achievement.name}
+
${achievement.description}
+
+
+ `;
+
+ document.body.appendChild(toast);
+
+ setTimeout(() => {
+ toast.remove();
+ }, 5000);
+}
+
+// Show achievements display
+function showAchievements() {
+ const achievementsDisplay = document.getElementById('achievementsDisplay');
+ if (achievementsDisplay) {
+ achievementsDisplay.style.display = 'block';
+ }
+}
+
+// Hide achievements display
+function hideAchievements() {
+ const achievementsDisplay = document.getElementById('achievementsDisplay');
+ if (achievementsDisplay) {
+ achievementsDisplay.style.display = 'none';
+ }
+}
+
+// Initialize achievements
+function initializeAchievements() {
+ // Check if achievements were enabled before
+ achievementsEnabled = JSON.parse(localStorage.getItem('achievementsEnabled') || 'false');
+
+ // Add hidden toggle button
+ const hiddenToggle = document.createElement('button');
+ hiddenToggle.className = 'hidden';
+ hiddenToggle.style.cssText = `
+ position: fixed;
+ bottom: -100px;
+ right: -100px;
+ width: 50px;
+ height: 50px;
+ background: transparent;
+ border: none;
+ cursor: pointer;
+ transition: transform 0.3s;
+ `;
+
+ hiddenToggle.onclick = () => {
+ toggleAchievements();
+ hiddenToggle.style.transform = 'translate(-50px, -50px)';
+ setTimeout(() => {
+ hiddenToggle.style.transform = '';
+ }, 1000);
+ };
+
+ document.body.appendChild(hiddenToggle);
+
+ // Check achievements when enabled
+ if (achievementsEnabled) {
+ checkAchievements();
+ showAchievements();
+ }
+}
+
+// Add celebration animation
+function celebrate() {
+ const confetti = document.createElement('div');
+ confetti.className = 'absolute inset-0 pointer-events-none';
+ confetti.innerHTML = `
+
+ `;
+
+ document.body.appendChild(confetti);
+
+ setTimeout(() => {
+ confetti.remove();
+ }, 3000);
+}
+
+// Initialize when page loads
+document.addEventListener('DOMContentLoaded', initializeAchievements);
diff --git a/admin-dashboard.html b/admin-dashboard.html
index ce1fd88..17c12a4 100644
--- a/admin-dashboard.html
+++ b/admin-dashboard.html
@@ -1067,6 +1067,29 @@
Vítejte v administraci
+
+
+
Statistiky návštěvností
+
+
+
Správa aplikací
@@ -4291,6 +4314,19 @@ function applyTemplate(templateId) {
// Load apps when the page loads
document.addEventListener('DOMContentLoaded', function() {
+ // Load visitor statistics
+ fetch('/api/visitor-stats')
+ .then(response => response.json())
+ .then(stats => {
+ document.getElementById('totalVisits').textContent = stats.total_visits;
+ document.getElementById('todayVisits').textContent = stats.today_visits;
+ document.getElementById('weeklyVisits').textContent = stats.weekly_visits;
+ document.getElementById('monthlyVisits').textContent = stats.monthly_visits;
+ })
+ .catch(error => {
+ console.error('Error loading visitor stats:', error);
+ });
+
loadApps();
// Initialize banner image upload functionality
diff --git a/index.html b/index.html
index 4437cfa..134c108 100644
--- a/index.html
+++ b/index.html
@@ -14,6 +14,35 @@
transform: translateY(-5px);
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
+
+ /* Achievements styles */
+ #achievementsDisplay {
+ position: fixed;
+ top: 10px;
+ right: 10px;
+ background: white;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ display: none;
+ z-index: 1000;
+ }
+
+ .achievement-item {
+ display: flex;
+ align-items: center;
+ padding: 0.5rem;
+ border-bottom: 1px solid #eee;
+ }
+
+ .achievement-item:last-child {
+ border-bottom: none;
+ }
+
+ .achievement-icon {
+ font-size: 1.5rem;
+ margin-right: 0.75rem;
+ }
-