tkquest-reflowed / script.js
Krydev32's picture
If something's missing why it's not showing anything in the preview, check this other code.
865f3dd verified
// Initialize Firebase
const firebaseConfig = {
apiKey: "AIzaSyDKL-6WhEMKBEeWepYlYEMf3QiHwFNgkSk",
authDomain: "yonggi-students.firebaseapp.com",
projectId: "yonggi-students",
storageBucket: "yonggi-students.appspot.com",
messagingSenderId: "140729683331",
appId: "1:140729683331:web:4c644c61c01eea78e2bab6"
};
// Initialize Firebase
const app = firebase.initializeApp(firebaseConfig);
const auth = firebase.auth();
const db = firebase.firestore();
const storage = firebase.storage();
// App state
let currentUser = null;
let currentUserData = null;
let isSidebarCollapsed = false;
// DOM elements
const authView = document.getElementById('auth-view');
const mainAppView = document.getElementById('main-app-view');
const loginForm = document.getElementById('login-form-element');
const registerForm = document.getElementById('register-form-element');
const logoutBtn = document.getElementById('logout-btn');
const sidebarToggleBtn = document.getElementById('sidebar-toggle-btn');
const sidebar = document.getElementById('sidebar');
// Auth state listener
auth.onAuthStateChanged(async (user) => {
currentUser = user;
if (user) {
// User is signed in
authView.classList.add('hidden');
mainAppView.classList.remove('hidden');
// Get user data from Firestore
const userDoc = await db.collection('artifacts/tkquest-preview/public/data/users').doc(user.uid).get();
if (userDoc.exists) {
currentUserData = userDoc.data();
updateUI();
} else {
// Create new user doc if doesn't exist
currentUserData = {
name: user.email.split('@')[0],
email: user.email,
role: 'student',
beltLevel: 'White'
};
await db.collection('artifacts/tkquest-preview/public/data/users').doc(user.uid).set(currentUserData);
updateUI();
}
} else {
// User is signed out
authView.classList.remove('hidden');
mainAppView.classList.add('hidden');
}
});
// Auth handlers
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const email = document.getElementById('login-email').value;
const password = document.getElementById('login-password').value;
try {
await auth.signInWithEmailAndPassword(email, password);
loginForm.reset();
} catch (error) {
document.getElementById('login-error').textContent = error.message;
document.getElementById('login-error').classList.remove('hidden');
}
});
registerForm.addEventListener('submit', async (e) => {
e.preventDefault();
const email = document.getElementById('register-email').value;
const password = document.getElementById('register-password').value;
const name = document.getElementById('register-name').value;
const beltLevel = document.getElementById('register-belt').value;
try {
const userCredential = await auth.createUserWithEmailAndPassword(email, password);
const user = userCredential.user;
// Create user document
await db.collection('artifacts/tkquest-preview/public/data/users').doc(user.uid).set({
name: name,
email: email,
role: 'student',
beltLevel: beltLevel,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
});
// Initialize progress document
await db.collection('artifacts/tkquest-preview/public/data/progress').doc(user.uid).set({
completedLessonIds: [],
checklistProgress: {},
taskProgress: {},
challengeProgress: {}
});
registerForm.reset();
} catch (error) {
document.getElementById('register-error').textContent = error.message;
document.getElementById('register-error').classList.remove('hidden');
}
});
logoutBtn.addEventListener('click', () => {
auth.signOut();
});
// Sidebar toggle
sidebarToggleBtn.addEventListener('click', () => {
isSidebarCollapsed = !isSidebarCollapsed;
if (isSidebarCollapsed) {
sidebar.classList.remove('w-64');
sidebar.classList.add('w-16');
document.body.classList.add('sidebar-collapsed');
} else {
sidebar.classList.remove('w-16');
sidebar.classList.add('w-64');
document.body.classList.remove('sidebar-collapsed');
}
});
// Update UI based on user data
function updateUI() {
if (!currentUser || !currentUserData) return;
// Update user display
document.getElementById('user-display').textContent = `Hi, ${currentUserData.name}`;
document.getElementById('user-id-kbd').textContent = currentUser.uid.substring(0, 8);
document.getElementById('update-name').value = currentUserData.name;
// Update floating user info (student only)
if (currentUserData.role === 'student') {
document.getElementById('floating-user-info').classList.remove('hidden');
document.getElementById('float-user-name').textContent = currentUserData.name;
document.getElementById('float-user-belt').textContent = currentUserData.beltLevel;
document.getElementById('float-user-number').textContent = currentUser.uid.substring(0, 8);
} else {
document.getElementById('floating-user-info').classList.add('hidden');
}
// Setup sidebar menu
setupSidebarMenu();
// Show/hide instructor UI elements
toggleInstructorUI(currentUserData.role === 'instructor');
// Load initial data
loadInitialData();
}
// Setup sidebar menu
function setupSidebarMenu() {
const menu = document.getElementById('sidebar-menu');
if (!menu || !currentUserData) return;
const isInstructor = currentUserData.role === 'instructor';
let menuItems = [
{ id: 'dashboard-page', icon: 'dashboard', text: 'Dashboard' },
{ id: 'lessons-page', icon: 'curriculum', text: 'Curriculum' },
];
if (isInstructor) {
menuItems.push(
{ id: 'manage-users-page', icon: 'manage-users', text: 'Manage Students' }
);
} else {
menuItems.push(
{ id: 'my-progress-page', icon: 'progress', text: 'My Progress' }
);
}
menuItems.push(
{ id: 'tasks-page', icon: 'tasks', text: 'Tasks & Exercises' },
{ id: 'events-page', icon: 'events', text: 'Events' },
{ id: 'settings-page', icon: 'settings', text: 'Settings' },
{ id: 'about-page', icon: 'info', text: 'About', href: 'about.html' }
);
menu.innerHTML = menuItems.map(item => `
<li>
<a data-page="${item.id}" class="nav-link">
${ICONS[item.icon] || ''}
<span class="sidebar-link-text">${item.text}</span>
</a>
</li>
`).join('');
// Add click listeners to navigation links
document.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
showPage(link.dataset.page);
});
});
// Show dashboard by default
showPage('dashboard-page');
}
// Show a specific page
function showPage(pageId) {
document.querySelectorAll('.app-page').forEach(page => {
page.classList.add('hidden');
});
const pageToShow = document.getElementById(pageId);
if (pageToShow) {
pageToShow.classList.remove('hidden');
document.getElementById('main-header').textContent = pageHeaders[pageId] || 'Dashboard';
}
}
// Toggle instructor UI elements
function toggleInstructorUI(isInstructor) {
document.querySelectorAll('[id^="instructor-actions"]').forEach(el => {
el.style.display = isInstructor ? 'flex' : 'none';
});
document.getElementById('dashboard-progress-overview').style.display = isInstructor ? 'none' : 'block';
}
// Load initial data
function loadInitialData() {
if (!currentUser || !currentUserData) return;
// Update dashboard stats
if (currentUserData.role === 'student') {
document.getElementById('stat-current-belt').textContent = currentUserData.beltLevel;
document.getElementById('stat-lessons-completed').textContent = '3/15'; // Example data
// Set progress bar
document.getElementById('dashboard-progress-bar-fill').style.width = '25%';
document.getElementById('dashboard-progress-text').textContent = '25%';
// Show progress overview for students
document.getElementById('dashboard-progress-overview').classList.remove('hidden');
}
// Set mock next event
const nextEventEl = document.getElementById('dashboard-next-event');
nextEventEl.innerHTML = `
<p class="font-medium">Belt Testing Seminar</p>
<p class="text-sm">December 10, 2023</p>
<p class="text-sm">10:00 AM - 12:00 PM</p>
<button class="btn btn-sm btn-secondary mt-2">View Details</button>
`;
// Set mock recent activity
const activityEl = document.getElementById('dashboard-notifications');
activityEl.innerHTML = `
<div class="flex items-start gap-3">
<div class="avatar">
<div class="w-8 rounded-full bg-primary text-white flex items-center justify-center">
<span>Y</span>
</div>
</div>
<div>
<p>Completed <strong>Basic Stances</strong> lesson</p>
<p class="text-xs text-gray-500">Today, 3:45 PM</p>
</div>
</div>
<div class="flex items-start gap-3">
<div class="avatar">
<div class="w-8 rounded-full bg-secondary text-white flex items-center justify-center">
<span>M</span>
</div>
</div>
<div>
<p>Received feedback on <strong>Kicking Techniques</strong></p>
<p class="text-xs text-gray-500">Yesterday, 10:30 AM</p>
</div>
</div>
`;
}
// ICONS constant (copied from original)
const ICONS = {
// ... (same as in original)
};
// Page headers constant
const pageHeaders = {
'dashboard-page': 'Dashboard',
'lessons-page': 'Curriculum',
'my-progress-page': 'My Progress',
'tasks-page': 'Tasks & Exercises',
'events-page': 'Events',
'manage-users-page': 'Manage Users',
'settings-page': 'Settings'
};
// Initialize the app
document.addEventListener('DOMContentLoaded', () => {
// Sidebar initially expanded
sidebar.classList.add('w-64');
document.body.classList.remove('sidebar-collapsed');
});