Krydev32/tkquest-reflowed
0
1 2// Initialize Firebase3const firebaseConfig = {4 apiKey: "AIzaSyDKL-6WhEMKBEeWepYlYEMf3QiHwFNgkSk",5 authDomain: "yonggi-students.firebaseapp.com",6 projectId: "yonggi-students",7 storageBucket: "yonggi-students.appspot.com",8 messagingSenderId: "140729683331",9 appId: "1:140729683331:web:4c644c61c01eea78e2bab6"10};11// Initialize Firebase12const app = firebase.initializeApp(firebaseConfig);13const auth = firebase.auth();14const db = firebase.firestore();15const storage = firebase.storage();16 17// App state18let currentUser = null;19let currentUserData = null;20let isSidebarCollapsed = false;21 22// DOM elements23const authView = document.getElementById('auth-view');24const mainAppView = document.getElementById('main-app-view');25const loginForm = document.getElementById('login-form-element');26const registerForm = document.getElementById('register-form-element');27const logoutBtn = document.getElementById('logout-btn');28const sidebarToggleBtn = document.getElementById('sidebar-toggle-btn');29const sidebar = document.getElementById('sidebar');30 31// Auth state listener32auth.onAuthStateChanged(async (user) => {33 currentUser = user;34 35 if (user) {36 // User is signed in37 authView.classList.add('hidden');38 mainAppView.classList.remove('hidden');39 40 // Get user data from Firestore41 const userDoc = await db.collection('artifacts/tkquest-preview/public/data/users').doc(user.uid).get();42 if (userDoc.exists) {43 currentUserData = userDoc.data();44 updateUI();45 } else {46 // Create new user doc if doesn't exist47 currentUserData = {48 name: user.email.split('@')[0],49 email: user.email,50 role: 'student',51 beltLevel: 'White'52 };53 await db.collection('artifacts/tkquest-preview/public/data/users').doc(user.uid).set(currentUserData);54 updateUI();55 }56 } else {57 // User is signed out58 authView.classList.remove('hidden');59 mainAppView.classList.add('hidden');60 }61});62 63// Auth handlers64loginForm.addEventListener('submit', async (e) => {65 e.preventDefault();66 const email = document.getElementById('login-email').value;67 const password = document.getElementById('login-password').value;68 69 try {70 await auth.signInWithEmailAndPassword(email, password);71 loginForm.reset();72 } catch (error) {73 document.getElementById('login-error').textContent = error.message;74 document.getElementById('login-error').classList.remove('hidden');75 }76});77 78registerForm.addEventListener('submit', async (e) => {79 e.preventDefault();80 const email = document.getElementById('register-email').value;81 const password = document.getElementById('register-password').value;82 const name = document.getElementById('register-name').value;83 const beltLevel = document.getElementById('register-belt').value;84 85 try {86 const userCredential = await auth.createUserWithEmailAndPassword(email, password);87 const user = userCredential.user;88 89 // Create user document90 await db.collection('artifacts/tkquest-preview/public/data/users').doc(user.uid).set({91 name: name,92 email: email,93 role: 'student',94 beltLevel: beltLevel,95 createdAt: firebase.firestore.FieldValue.serverTimestamp()96 });97 98 // Initialize progress document99 await db.collection('artifacts/tkquest-preview/public/data/progress').doc(user.uid).set({100 completedLessonIds: [],101 checklistProgress: {},102 taskProgress: {},103 challengeProgress: {}104 });105 106 registerForm.reset();107 } catch (error) {108 document.getElementById('register-error').textContent = error.message;109 document.getElementById('register-error').classList.remove('hidden');110 }111});112 113logoutBtn.addEventListener('click', () => {114 auth.signOut();115});116 117// Sidebar toggle118sidebarToggleBtn.addEventListener('click', () => {119 isSidebarCollapsed = !isSidebarCollapsed;120 if (isSidebarCollapsed) {121 sidebar.classList.remove('w-64');122 sidebar.classList.add('w-16');123 document.body.classList.add('sidebar-collapsed');124 } else {125 sidebar.classList.remove('w-16');126 sidebar.classList.add('w-64');127 document.body.classList.remove('sidebar-collapsed');128 }129});130 131// Update UI based on user data132function updateUI() {133 if (!currentUser || !currentUserData) return;134 135 // Update user display136 document.getElementById('user-display').textContent = `Hi, ${currentUserData.name}`;137 document.getElementById('user-id-kbd').textContent = currentUser.uid.substring(0, 8);138 document.getElementById('update-name').value = currentUserData.name;139 140 // Update floating user info (student only)141 if (currentUserData.role === 'student') {142 document.getElementById('floating-user-info').classList.remove('hidden');143 document.getElementById('float-user-name').textContent = currentUserData.name;144 document.getElementById('float-user-belt').textContent = currentUserData.beltLevel;145 document.getElementById('float-user-number').textContent = currentUser.uid.substring(0, 8);146 } else {147 document.getElementById('floating-user-info').classList.add('hidden');148 }149 150 // Setup sidebar menu151 setupSidebarMenu();152 153 // Show/hide instructor UI elements154 toggleInstructorUI(currentUserData.role === 'instructor');155 156 // Load initial data157 loadInitialData();158}159 160// Setup sidebar menu161function setupSidebarMenu() {162 const menu = document.getElementById('sidebar-menu');163 if (!menu || !currentUserData) return;164 165 const isInstructor = currentUserData.role === 'instructor';166 let menuItems = [167 { id: 'dashboard-page', icon: 'dashboard', text: 'Dashboard' },168 { id: 'lessons-page', icon: 'curriculum', text: 'Curriculum' },169 ];170 171 if (isInstructor) {172 menuItems.push(173 { id: 'manage-users-page', icon: 'manage-users', text: 'Manage Students' }174 );175 } else {176 menuItems.push(177 { id: 'my-progress-page', icon: 'progress', text: 'My Progress' }178 );179 }180 menuItems.push(181 { id: 'tasks-page', icon: 'tasks', text: 'Tasks & Exercises' },182 { id: 'events-page', icon: 'events', text: 'Events' },183 { id: 'settings-page', icon: 'settings', text: 'Settings' },184 { id: 'about-page', icon: 'info', text: 'About', href: 'about.html' }185 );186menu.innerHTML = menuItems.map(item => `187 <li>188 <a data-page="${item.id}" class="nav-link">189 ${ICONS[item.icon] || ''}190 <span class="sidebar-link-text">${item.text}</span>191 </a>192 </li>193 `).join('');194 195 // Add click listeners to navigation links196 document.querySelectorAll('.nav-link').forEach(link => {197 link.addEventListener('click', (e) => {198 e.preventDefault();199 showPage(link.dataset.page);200 });201 });202 203 // Show dashboard by default204 showPage('dashboard-page');205}206 207// Show a specific page208function showPage(pageId) {209 document.querySelectorAll('.app-page').forEach(page => {210 page.classList.add('hidden');211 });212 213 const pageToShow = document.getElementById(pageId);214 if (pageToShow) {215 pageToShow.classList.remove('hidden');216 document.getElementById('main-header').textContent = pageHeaders[pageId] || 'Dashboard';217 }218}219 220// Toggle instructor UI elements221function toggleInstructorUI(isInstructor) {222 document.querySelectorAll('[id^="instructor-actions"]').forEach(el => {223 el.style.display = isInstructor ? 'flex' : 'none';224 });225 document.getElementById('dashboard-progress-overview').style.display = isInstructor ? 'none' : 'block';226}227// Load initial data228function loadInitialData() {229 if (!currentUser || !currentUserData) return;230 231 // Update dashboard stats232 if (currentUserData.role === 'student') {233 document.getElementById('stat-current-belt').textContent = currentUserData.beltLevel;234 document.getElementById('stat-lessons-completed').textContent = '3/15'; // Example data235 236 // Set progress bar237 document.getElementById('dashboard-progress-bar-fill').style.width = '25%';238 document.getElementById('dashboard-progress-text').textContent = '25%';239 240 // Show progress overview for students241 document.getElementById('dashboard-progress-overview').classList.remove('hidden');242 }243 244 // Set mock next event245 const nextEventEl = document.getElementById('dashboard-next-event');246 nextEventEl.innerHTML = `247 <p class="font-medium">Belt Testing Seminar</p>248 <p class="text-sm">December 10, 2023</p>249 <p class="text-sm">10:00 AM - 12:00 PM</p>250 <button class="btn btn-sm btn-secondary mt-2">View Details</button>251 `;252 253 // Set mock recent activity254 const activityEl = document.getElementById('dashboard-notifications');255 activityEl.innerHTML = `256 <div class="flex items-start gap-3">257 <div class="avatar">258 <div class="w-8 rounded-full bg-primary text-white flex items-center justify-center">259 <span>Y</span>260 </div>261 </div>262 <div>263 <p>Completed <strong>Basic Stances</strong> lesson</p>264 <p class="text-xs text-gray-500">Today, 3:45 PM</p>265 </div>266 </div>267 <div class="flex items-start gap-3">268 <div class="avatar">269 <div class="w-8 rounded-full bg-secondary text-white flex items-center justify-center">270 <span>M</span>271 </div>272 </div>273 <div>274 <p>Received feedback on <strong>Kicking Techniques</strong></p>275 <p class="text-xs text-gray-500">Yesterday, 10:30 AM</p>276 </div>277 </div>278 `;279}280// ICONS constant (copied from original)281const ICONS = {282 // ... (same as in original)283};284 285// Page headers constant286const pageHeaders = {287 'dashboard-page': 'Dashboard',288 'lessons-page': 'Curriculum',289 'my-progress-page': 'My Progress',290 'tasks-page': 'Tasks & Exercises',291 'events-page': 'Events',292 'manage-users-page': 'Manage Users',293 'settings-page': 'Settings'294};295 296// Initialize the app297document.addEventListener('DOMContentLoaded', () => {298 // Sidebar initially expanded299 sidebar.classList.add('w-64');300 document.body.classList.remove('sidebar-collapsed');301});