Files
homeschool/public/index.html
T
nmemmert d860df7de6 ✨ Major code cleanup and optimization
- Removed unnecessary dependencies (fs, path - built-in modules)
- Organized debug files into /debug folder
- Reduced excessive console logging for cleaner output
- Fixed README formatting issues
- Added comprehensive .gitignore
- Removed redundant backup files (game.js.new)
- Fixed duplicate code patterns in analytics
- Created CLEANUP_SUMMARY.md documentation
- Regenerated clean package-lock.json

No breaking changes - all functionality preserved
2025-10-13 07:42:36 -04:00

1012 lines
54 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="format-detection" content="telephone=no">
<title>✨ Modern Spelling Practice</title>
<link href="styles.css" rel="stylesheet"/>
<link href="mobile.css" rel="stylesheet"/>
<link href="tablet.css" rel="stylesheet"/>
<link href="tablet-menu.css" rel="stylesheet"/>
<link href="handwriting.css" rel="stylesheet"/>
<link href="native-recognition.css" rel="stylesheet"/>
<link href="unified-write.css" rel="stylesheet"/>
<link href="tab-contrast.css" rel="stylesheet"/>
<link href="badges.css" rel="stylesheet"/>
<link href="analytics.css" rel="stylesheet"/>
<link href="gamification.css" rel="stylesheet"/>
<link href="spaced-repetition.css" rel="stylesheet"/>
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/3.3.1/sha.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- TensorFlow.js for better handwriting recognition -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.10.0/dist/tf.min.js"></script>
<!-- Fallback for jsSHA library if CDN fails -->
<script>
window.addEventListener('DOMContentLoaded', function() {
if (typeof jsSHA === 'undefined') {
console.warn('jsSHA not loaded from CDN, using fallback');
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/jssha@3.3.0/dist/sha.js';
document.head.appendChild(script);
} else {
console.log('jsSHA loaded successfully');
}
});
</script>
<script src="js/auth.js"></script>
<script src="js/ui.js"></script>
<script src="js/themes.js"></script>
<script src="js/game.js"></script>
<script src="js/typing.js"></script>
<script src="js/bible.js"></script>
<script src="js/charts.js"></script>
<script src="js/export.js"></script>
<script src="js/session-helpers.js"></script>
<script src="js/sessions.js"></script>
<script src="js/admin-badges.js"></script>
<script src="js/analytics.js"></script>
<script src="js/gamification.js"></script>
<script src="js/spaced-repetition.js"></script>
<script src="js/native-handwriting.js"></script>
<script src="js/handwriting.js"></script>
<script src="js/unified-write.js"></script>
<script src="js/tablet-menu.js"></script>
<script src="js/tablet-utils.js"></script>
<script src="js/draggable-cards.js"></script>
<script src="js/main.js"></script>
<!-- Initialization script - loads last -->
<script src="js/chart-safety.js"></script>
<script src="js/user-dropdown-health.js"></script>
<script src="js/input-fix.js"></script>
<script src="js/init.js"></script>
<!-- Production scripts only -->
<script src="js/cleanup.js"></script>
</head>
<body>
<div class="container">
<h1>✨ Spelling Practice</h1>
<!-- Role Banner -->
<div class="banner hidden" id="roleBanner"></div>
<!-- Login Panel -->
<div id="loginPanel" class="card">
<div class="card-header">
<h2 class="text-center">Welcome Back</h2>
<p class="text-center" style="color: var(--text-secondary);">Sign in to continue your spelling practice</p>
</div>
<form onsubmit="event.preventDefault(); verifyLogin();">
<input id="username" placeholder="Username" required type="text"/>
<input id="password" placeholder="Password" required type="password"/>
<button type="submit">Sign In</button>
</form>
<p id="loginMessage" style="margin-top: 1rem; text-align: center;"></p>
</div>
<!-- Enhanced Navigation Menu -->
<div id="nav" class="hidden">
<div class="nav-header">
<p><strong id="userInfo"></strong></p>
<div class="user-badge" id="userBadge"></div>
</div>
<!-- Student Menu Items -->
<div id="studentNavItems" class="nav-section hidden">
<h4>🎓 Activities</h4>
<div class="nav-grid">
<button onclick="startGame(); closeMenuIfTablet();" class="nav-activity-btn">
<span class="nav-icon">🎮</span>
<div>
<div class="nav-title">Spelling Game</div>
<div class="nav-subtitle">Interactive challenges</div>
</div>
</button>
<button onclick="startTypingPractice(); closeMenuIfTablet();" class="nav-activity-btn">
<span class="nav-icon">⌨️</span>
<div>
<div class="nav-title">Typing Practice</div>
<div class="nav-subtitle">Improve speed & accuracy</div>
</div>
</button>
<button onclick="startBibleTyping(); closeMenuIfTablet();" class="nav-activity-btn">
<span class="nav-icon">📖</span>
<div>
<div class="nav-title">Bible Typing</div>
<div class="nav-subtitle">Spiritual practice</div>
</div>
</button>
<button onclick="startSpacedReview(); closeMenuIfTablet();" class="nav-activity-btn">
<span class="nav-icon">🔄</span>
<div>
<div class="nav-title">Spaced Review</div>
<div class="nav-subtitle">Smart learning</div>
</div>
</button>
</div>
<h4>📊 Progress</h4>
<div class="nav-list">
<button onclick="showStudent(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">📈</span>Dashboard
</button>
<button onclick="showChallenges(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🎯</span>Challenges
</button>
<button onclick="showLeaderboards(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🏆</span>Leaderboards
</button>
<button onclick="showBadges(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🏅</span>My Badges
</button>
</div>
<h4>⚙️ Settings</h4>
<div class="nav-list">
<button onclick="showThemeSelector(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🎨</span>Themes
</button>
<button onclick="showInputSettings(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">✏️</span>Input Method
</button>
</div>
</div>
<!-- Admin Menu Items -->
<div id="adminNavItems" class="nav-section hidden">
<h4>👨‍💼 Administration</h4>
<div class="nav-list">
<button onclick="showAdmin(); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🏠</span>Dashboard
</button>
<button onclick="showAdminTab('tabUsers'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">👤</span>User Management
</button>
<button onclick="showAdminTab('tabWords'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">📝</span>Word Lists
</button>
<button onclick="showAdminTab('tabAnalytics'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">📊</span>Analytics
</button>
<button onclick="showAdminTab('tabResults'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">📋</span>Results
</button>
<button onclick="showAdminTab('tabReports'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">📘</span>Reports
</button>
<button onclick="showAdminTab('tabSessions'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">📅</span>Sessions
</button>
<button onclick="showAdminTab('tabBadges'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">�</span>Badge System
</button>
<button onclick="showAdminTab('tabPasswords'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🔐</span>Passwords
</button>
<button onclick="showAdminTab('tabTheme'); closeMenuIfTablet();" class="nav-list-btn">
<span class="nav-icon">🎨</span>Themes
</button>
</div>
</div>
<!-- Common Actions -->
<div class="nav-section nav-footer">
<button id="logoutBtn" onclick="logoutUser()" class="nav-logout-btn">
<span class="nav-icon">🚪</span>Sign Out
</button>
</div>
</div>
<!-- Admin Panel -->
<div class="hidden" id="adminPanel">
<!-- Admin Dashboard Overview -->
<div class="card">
<div class="card-header">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<h2>👨‍💼 Admin Dashboard</h2>
<p style="color: var(--text-secondary); margin: 0;">System overview and quick access to admin functions</p>
</div>
<button id="refreshDashboardBtn" class="btn btn-secondary" onclick="loadAdminDashboardStats()" title="Refresh statistics">
🔄 Refresh
</button>
</div>
</div>
<!-- Quick Stats Overview -->
<div class="admin-overview">
<div class="overview-grid">
<div class="stat-card">
<div class="stat-icon">👥</div>
<div class="stat-content">
<div class="stat-number" id="totalUsers">-</div>
<div class="stat-label">Total Users</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">📝</div>
<div class="stat-content">
<div class="stat-number" id="totalWordLists">-</div>
<div class="stat-label">Word Lists</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">🎯</div>
<div class="stat-content">
<div class="stat-number" id="totalSessions">-</div>
<div class="stat-label">Active Sessions</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">🏆</div>
<div class="stat-content">
<div class="stat-number" id="totalBadges">-</div>
<div class="stat-label">Badges Awarded</div>
</div>
</div>
</div>
<!-- Last Updated Timestamp -->
<div style="text-align: center; margin-top: 1rem; opacity: 0.7;">
<small id="lastUpdated">Last updated: Loading...</small>
</div>
</div>
<!-- Help Bubble for Admin Functions -->
<div class="help-bubble-container">
<button class="help-bubble" id="adminHelpBubble" title="View admin functions guide">
<span class="help-icon">?</span>
</button>
</div>
<!-- Hidden Menu Instructions (shown in popup) -->
<div class="menu-instructions hidden" id="adminHelpContent">
<h3>📱 Access Admin Functions</h3>
<p>Use the menu button (<strong>☰</strong>) in the top-right corner to access all admin functions:</p>
<div class="instruction-grid">
<div class="instruction-item">
<span class="instruction-icon">👤</span>
<span><strong>User Management</strong> - Add/remove users</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">📝</span>
<span><strong>Word Lists</strong> - Manage spelling lists</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">📊</span>
<span><strong>Analytics</strong> - View detailed statistics</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">📋</span>
<span><strong>Results</strong> - Check student performance</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">📘</span>
<span><strong>Reports</strong> - Generate reports</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">⚙️</span>
<span><strong>Settings</strong> - System configuration</span>
</div>
</div>
</div>
</div>
<!-- Hidden Admin Tabs - Accessed via Menu -->
<div style="display: none;">
<div id="adminTabs">
<button class="active" data-tab="tabUsers" data-emoji="👤">Users</button>
<button data-tab="tabWords" data-emoji="📝">Word Lists</button>
<button data-tab="tabAnalytics" data-emoji="📊">Analytics</button>
<button data-tab="tabResults" data-emoji="📋">Results</button>
<button data-tab="tabReports" data-emoji="📘">Reports</button>
<button data-tab="tabSessions" data-emoji="📅">Sessions</button>
<button data-tab="tabBadges" data-emoji="🏅">Badges</button>
<button data-tab="tabPasswords" data-emoji="🔐">Passwords</button>
<button data-tab="tabTheme" data-emoji="🎨">Themes</button>
</div>
</div>
<!-- Users Tab -->
<div id="tabUsers" class="adminTab">
<h3>👤 User Management</h3>
<div class="admin-grid">
<div class="card">
<h4>Add New User</h4>
<form onsubmit="event.preventDefault(); addNewUser();" class="form-group">
<input id="newUsername" placeholder="Username" required type="text"/>
<input id="newPassword" placeholder="Password" required type="password"/>
<select id="newRole">
<option value="student">🎓 Student</option>
<option value="admin">👨‍💼 Admin</option>
</select>
<div class="btn-group">
<button type="submit" class="btn-success">➕ Add User</button>
</div>
</form>
<p id="userAddMessage" style="margin-top: 1rem;"></p>
<small id="hashPreview" style="color: var(--text-secondary);"></small>
</div>
<div class="card">
<h4>Remove User</h4>
<select id="userDropdown" onchange="selectUserAction(this.value)" style="width: 100%;">
<option value="">-- Select a user to remove --</option>
</select>
</div>
</div>
</div>
<!-- Word Lists Tab -->
<div class="adminTab hidden" id="tabWords">
<div class="admin-grid">
<div class="card">
<h4>Select User</h4>
<select class="word-user-dropdown" id="wordUserSelect" onchange="loadWordsForSelectedUser()" style="width: 100%;">
<option value="">-- Select a user --</option>
</select>
</div>
<div class="card">
<h4>Manage Word List</h4>
<div id="weeksInputSection">
<h4>Enter Weeks</h4>
<div id="weeksContainer"></div>
<button onclick="addWeekInput()" class="btn-secondary" style="margin-top: 1rem;">➕ Add Week</button>
<div style="display: flex; gap: 1rem; margin-top: 1rem;">
<button onclick="saveWeeks()" class="btn-success">💾 Save Weeks</button>
<button onclick="clearWeeks()" class="btn-error">🗑️ Clear All Weeks</button>
</div>
<div style="margin-top:2rem;">
<label for="activeWeekSelect"><strong>Set Active Week for Student:</strong></label>
<select id="activeWeekSelect" style="width:100%; margin-top:0.5rem;"></select>
<button onclick="setActiveWeek()" class="btn-primary" style="margin-top:0.5rem;">Set Active Week</button>
</div>
</div>
<div style="margin-top: 1.5rem;">
<h5>Upload Word File</h5>
<input accept=".txt,.csv" onchange="handleFileUpload(event)" type="file" style="margin: 0.5rem 0;"/>
</div>
</div>
<div class="card">
<h4>Current Word List</h4>
<ul id="wordListDisplay" style="max-height: 200px; overflow-y: auto;"></ul>
</div>
</div>
<!-- View by Student - Separate section -->
<div class="admin-grid" style="margin-top: 2rem;">
<div class="card">
<h4>View by Student</h4>
<select class="word-user-dropdown" id="viewUserSelect" onchange="displayWordListForSelectedUser()" style="width: 100%;">
<option value="">-- Select a student --</option>
</select>
<ul id="userWordListDisplay" style="max-height: 200px; overflow-y: auto; margin-top: 1rem;"></ul>
</div>
</div>
</div>
<!-- Results Tab -->
<div class="adminTab hidden" id="tabResults">
<div class="card">
<div class="card-header">
<h3>📋 Student Results Overview</h3>
<button onclick="loadStudentResults()" class="btn-primary">🔄 Refresh Results</button>
</div>
<ul id="resultsList" style="max-height: 400px; overflow-y: auto;"></ul>
</div>
</div>
<!-- Analytics Tab -->
<div class="adminTab hidden" id="tabAnalytics">
<div class="card">
<div class="card-header">
<h3>📊 Performance Analytics</h3>
<div class="flex gap-3">
<select id="analyticsUserSelect" class="form-control">
<option value="all">All Users</option>
<!-- Additional users will be added here dynamically -->
</select>
<select id="analyticsTimeRange" class="form-control">
<option value="all">All Time</option>
<option value="week">Last Week</option>
<option value="month">Last Month</option>
<option value="quarter">Last 3 Months</option>
</select>
<button onclick="window.analyticsRefresh ? window.analyticsRefresh() : refreshAnalytics()" class="btn-primary">🔄 Refresh Analytics</button>
</div>
</div>
<div class="analytics-grid">
<!-- Dashboard Summary Cards -->
<div class="stat-card">
<h5>Total Sessions</h5>
<div class="stat-value" id="statTotalSessions">-</div>
<div class="stat-change" id="statSessionsChange"></div>
</div>
<div class="stat-card">
<h5>Overall Accuracy</h5>
<div class="stat-value" id="statOverallAccuracy">-</div>
<div class="stat-change" id="statAccuracyChange"></div>
</div>
<div class="stat-card">
<h5>Total Words</h5>
<div class="stat-value" id="statTotalWords">-</div>
</div>
<div class="stat-card">
<h5>Average Score</h5>
<div class="stat-value" id="statAverageScore">-</div>
</div>
<!-- Progress Over Time Chart -->
<div class="chart-container">
<h4>Progress Over Time</h4>
<div id="progressChartContainer" class="chart"></div>
</div>
<!-- Activity Heatmap -->
<div class="chart-container">
<h4>Activity Calendar</h4>
<div id="activityHeatmap" class="chart"></div>
</div>
<!-- Problem Words -->
<div class="chart-container">
<h4>Most Challenging Words</h4>
<div id="problemWordsContainer">
<div id="problemWordsList"></div>
</div>
</div>
<!-- User Performance Comparison -->
<div class="chart-container">
<h4>User Performance Comparison</h4>
<div id="userComparisonChart" class="chart"></div>
</div>
<!-- Student Breakdown (Updated) -->
<div class="chart-container">
<h4>Student Performance</h4>
<div id="studentBreakdownContainer">
<table id="studentBreakdownTable" class="data-table">
<thead>
<tr>
<th>Student</th>
<th>Sessions</th>
<th>Words</th>
<th>Accuracy</th>
<th>Trend</th>
</tr>
</thead>
<tbody id="studentBreakdown">
</tbody>
</table>
</div>
</div>
<!-- Recent Activity -->
<div class="chart-container">
<h4>Recent Activity</h4>
<div id="recentActivityList" class="activity-feed"></div>
</div>
</div>
</div>
</div>
<!-- Enhanced Badges Tab -->
<div class="adminTab hidden" id="tabBadges">
<div class="card">
<h3>🏅 Student Achievement System</h3>
<p class="badge-system-intro">Track student progress and celebrate achievements through badges and rewards.</p>
<div class="badge-admin-layout">
<div class="badge-student-selector">
<h4>Select Student</h4>
<div class="badge-search">
<input type="text" id="badgeStudentSearch" placeholder="Search students..." class="form-control">
</div>
<div class="badge-student-list">
<ul id="badgeUserList"></ul>
</div>
</div>
<div class="hidden" id="badgeDetails">
<div class="badge-user-header">
<h3 id="badgeUserTitle"></h3>
<div class="badge-filters">
<button class="btn-sm btn-secondary active" data-filter="all">All</button>
<button class="btn-sm btn-secondary" data-filter="achievement">Achievement</button>
<button class="btn-sm btn-secondary" data-filter="speed">Speed</button>
<button class="btn-sm btn-secondary" data-filter="mastery">Mastery</button>
<button class="btn-sm btn-secondary" data-filter="consistency">Consistency</button>
</div>
</div>
<div id="badgeUserBadges" class="badge-user-collection"></div>
<div class="badge-user-actions">
<button id="printBadges" class="btn-secondary">Print Certificate</button>
<button id="awardCustomBadge" class="btn-primary">Award Custom Badge</button>
</div>
</div>
</div>
</div>
<!-- Badge Statistics -->
<div class="card mt-4">
<h3>📊 Badge Statistics</h3>
<div class="badge-stats-grid">
<div class="badge-stat-card">
<div class="stat-icon">🏆</div>
<div class="stat-value" id="totalBadgesAwarded">0</div>
<div class="stat-label">Total Badges</div>
</div>
<div class="badge-stat-card">
<div class="stat-icon">👑</div>
<div class="stat-value" id="mostBadgesStudent">-</div>
<div class="stat-label">Most Badges</div>
</div>
<div class="badge-stat-card">
<div class="stat-icon">⭐</div>
<div class="stat-value" id="mostCommonBadge">-</div>
<div class="stat-label">Popular Badge</div>
</div>
<div class="badge-stat-card">
<div class="stat-icon">🆕</div>
<div class="stat-value" id="badgesThisWeek">0</div>
<div class="stat-label">This Week</div>
</div>
</div>
</div>
</div>
<!-- Theme Tab -->
<!-- Passwords Tab -->
<div class="adminTab hidden" id="tabPasswords">
<div class="card">
<div class="card-header">
<h3>🔐 Password Management</h3>
<p style="color: var(--text-secondary);">Change user passwords</p>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
<!-- Change Password Form -->
<div class="card">
<h4>Change User Password</h4>
<form onsubmit="event.preventDefault(); changeUserPassword();" style="display: flex; flex-direction: column; gap: 1rem;">
<label for="passwordUsername">Select User:</label>
<select id="passwordUsername" required style="width: 100%;">
<option value="">-- Select a user --</option>
</select>
<label for="newUserPassword">New Password:</label>
<input id="newUserPassword" placeholder="Enter new password" required type="password"/>
<label for="confirmPassword">Confirm Password:</label>
<input id="confirmPassword" placeholder="Confirm new password" required type="password"/>
<button type="submit" class="btn-warning">🔐 Change Password</button>
</form>
</div>
<!-- Password History -->
<div class="card">
<h4>Password Change Log</h4>
<div id="passwordLog" style="max-height: 300px; overflow-y: auto; background: var(--bg-secondary); padding: 1rem; border-radius: var(--radius);">
<p style="color: var(--text-secondary); font-style: italic;">No password changes recorded yet.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Themes Tab -->
<div class="adminTab hidden" id="tabTheme">
<div class="card">
<h3>🎨 Application Themes</h3>
<p style="color: var(--text-secondary); margin-bottom: 1.5rem;">Choose a visual theme for the application</p>
<select id="themeSelect" onchange="changeTheme(this.value)" style="width: 100%; max-width: 300px;">
<option value="default">✨ Modern (Default)</option>
<option value="playground">🎪 Playground</option>
<option value="chalkboard">🎓 Chalkboard</option>
<option value="galaxy">🌌 Galaxy</option>
<option value="nature">🌿 Nature</option>
</select>
</div>
</div>
<!-- Reports Tab -->
<div class="adminTab hidden" id="tabReports">
<div class="card">
<h3>📘 Student Progress Reports</h3>
<div style="margin-bottom: 2rem;">
<label for="reportUser">Select Student:</label>
<select id="reportUser" onchange="loadStudentReport(this.value)" style="width: 100%; max-width: 300px;">
<option value="">-- Select a student --</option>
</select>
</div>
<div class="hidden" id="reportContent">
<div class="card" style="background: var(--bg-secondary);">
<h4 id="reportTitle"></h4>
<p><strong>Latest Score:</strong> <span id="reportScore"></span></p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; margin-top: 1.5rem;">
<div>
<h5>Words Attempted</h5>
<ul id="reportWords" style="max-height: 200px; overflow-y: auto;"></ul>
</div>
<div>
<h5>Badges Earned</h5>
<ul id="reportBadges"></ul>
</div>
</div>
<div style="margin-top: 2rem;">
<h4>📈 Progress Visualization</h4>
<div style="display: grid; grid-template-columns: 1fr; gap: 2rem; margin-top: 1rem;">
<div>
<h5>Progress Over Time</h5>
<div id="progressChart" style="width: 100%; height: 250px; margin-top: 1rem;"></div>
</div>
<div>
<h5>Word Difficulty Analysis</h5>
<div id="wordDifficultyChart" style="width: 100%; height: 300px; margin-top: 1rem;"></div>
</div>
</div>
</div>
<div style="margin-top: 2rem; display: flex; gap: 1rem; flex-wrap: wrap;">
<button onclick="window.print()" class="btn-secondary">🖨️ Print Report</button>
<button onclick="copyReportToClipboard()" class="btn-primary">📋 Copy to Clipboard</button>
<button onclick="exportToPDF()" class="btn-primary">📄 Export as PDF</button>
<button onclick="exportToCSV()" class="btn-secondary">📊 Export Data (CSV)</button>
</div>
</div>
</div>
</div>
</div>
<!-- Sessions Tab -->
<div class="adminTab hidden" id="tabSessions">
<div class="card">
<h3>📅 Session History</h3>
<div style="margin-bottom: 2rem;">
<label for="sessionUserSelect">Select Student:</label>
<select id="sessionUserSelect" onchange="loadUserSessions(this.value)" style="width: 100%; max-width: 300px;">
<option value="">-- Select a student --</option>
</select>
</div>
<div style="margin-bottom: 1rem;">
<button onclick="exportAllSessionsCSV()" class="btn-secondary">📊 Export All Sessions (CSV)</button>
</div>
<ul id="userSessionList" style="max-height: 400px; overflow-y: auto;"></ul>
</div>
</div>
</div>
<!-- Student Panel -->
<div class="hidden" id="studentPanel">
<div class="card">
<div class="card-header">
<h2>🎓 Student Dashboard</h2>
<p style="color: var(--text-secondary);">Your learning journey starts here</p>
</div>
<!-- Streak & User Stats Section -->
<div class="dashboard-section">
<div id="streakContainer" class="card dashboard-card"></div>
<div id="userStatsContainer" class="card dashboard-card"></div>
</div>
<!-- Quick Start Section -->
<div class="quick-start-section">
<h3>🚀 Quick Start</h3>
<p>Jump right into your favorite activity:</p>
<div class="quick-actions-grid">
<button onclick="startGame()" class="quick-action-card">
<span class="quick-icon">🎮</span>
<span class="quick-title">Spelling Game</span>
</button>
<button onclick="startTypingPractice()" class="quick-action-card">
<span class="quick-icon">⌨️</span>
<span class="quick-title">Typing Practice</span>
</button>
<button onclick="startBibleTyping()" class="quick-action-card">
<span class="quick-icon">📖</span>
<span class="quick-title">Bible Typing</span>
</button>
<button onclick="startSpacedReview()" class="quick-action-card">
<span class="quick-icon">🔄</span>
<span class="quick-title">Spaced Review</span>
</button>
</div>
</div>
<!-- Menu Instructions for Students -->
<div class="menu-instructions student-instructions">
<h3>📱 Explore More Features</h3>
<p>Use the menu button (<strong>☰</strong>) to access:</p>
<div class="instruction-grid">
<div class="instruction-item">
<span class="instruction-icon">🎯</span>
<span><strong>Challenges</strong> - Track your goals</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">🏆</span>
<span><strong>Leaderboards</strong> - Compare progress</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">🏅</span>
<span><strong>Badges</strong> - View achievements</span>
</div>
<div class="instruction-item">
<span class="instruction-icon">🎨</span>
<span><strong>Themes</strong> - Customize appearance</span>
</div>
</div>
</div>
<!-- Hidden original content for backwards compatibility -->
<div style="display: none;">
<!-- Theme Selection for Students -->
<div class="card" style="margin-bottom: 1.5rem;">
<h4>🎨 Choose Your Theme</h4>
<select id="studentThemeSelect" onchange="changeTheme(this.value)" style="width: 100%; max-width: 300px;">
<option value="default">✨ Modern (Default)</option>
<option value="playground">🎪 Playground</option>
<option value="chalkboard">🎓 Chalkboard</option>
<option value="galaxy">🌌 Galaxy</option>
<option value="nature">🌿 Nature</option>
</select>
</div>
</div>
<!-- Challenges Section -->
<div class="card dashboard-section" style="margin-top: 1.5rem;">
<div class="section-header">
<h3>🎯 Active Challenges</h3>
</div>
<div id="challengesContainer" class="challenges-section"></div>
</div>
<!-- Leaderboards Section -->
<div class="card dashboard-section" style="margin-top: 1.5rem;">
<div class="section-header">
<h3>🏆 Leaderboards</h3>
</div>
<div id="leaderboardsContainer" class="leaderboards-section"></div>
</div>
<!-- Spaced Repetition Section -->
<div class="card dashboard-section" style="margin-top: 1.5rem;">
<div class="section-header">
<h3>📚 Spaced Repetition</h3>
</div>
<div class="sr-info">
<h4>How Spaced Repetition Works</h4>
<p>Words you find difficult will appear more frequently, while words you know well will appear less often. This helps you learn more efficiently!</p>
</div>
<!-- SR Stats -->
<div id="srStatsContainer" class="sr-stats-container"></div>
<!-- SR Actions -->
<div class="sr-actions">
<button id="startSpacedReviewBtn" class="btn-primary" onclick="startSpacedReview()">🔄 Start Review</button>
<button class="btn-secondary" onclick="importWordsToSR()">📥 Import Words</button>
</div>
<!-- SR Progress -->
<div id="srProgressContainer" class="sr-progress-container"></div>
</div>
</div>
</div>
<!-- Game Section -->
<div class="hidden" id="gameSection">
<div class="card">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h3>🎮 Spelling Challenge</h3>
<button onclick="backToStudentDashboard()" class="btn-secondary" style="padding: 0.5rem 1rem;">
← Back to Dashboard
</button>
</div>
<div class="word-box" id="wordBox"></div>
<div class="hidden" id="inputSection" style="text-align: center;">
<!-- Unified Write Mode Container -->
<div id="unifiedWriteContainer"></div>
<!-- Legacy input (hidden, for compatibility) -->
<input id="userInput" type="hidden"/>
<!-- Recognized Text Display -->
<div id="recognizedText" class="recognized-text">Draw to see recognized text here</div>
<!-- Handwriting Tips -->
<div class="handwriting-hints">
<h4>💡 Tips for better recognition:</h4>
<ul>
<li>Write clearly with consistent letter size</li>
<li>Use print letters rather than cursive</li>
<li>Write one word at a time</li>
<li>Allow space between letters</li>
<li>Press firmly but write smoothly</li>
</ul>
</div>
</div>
<button onclick="submitAnswer()" class="btn-primary">Submit Answer</button>
<div id="wordFeedback" style="margin-top: 10px; font-weight: bold; min-height: 24px;"></div>
</div>
<!-- Game Summary -->
<div id="summary" class="card hidden">
<h3>Game Results</h3>
<div class="summary-stats">
<div class="stat-item">
<label>Total Words:</label>
<span id="totalWords">0</span>
</div>
<div class="stat-item">
<label>Correct Words:</label>
<span id="correctWords">0</span>
</div>
<div class="stat-item">
<label>Accuracy:</label>
<span id="accuracy">0%</span>
</div>
</div>
<h4>Incorrect Words</h4>
<ul id="incorrectList" class="incorrect-list"></ul>
<div class="summary-actions">
<button onclick="returnToStudentPanel()" class="btn-secondary">Return to Dashboard</button>
<button onclick="startGame()" class="btn-primary">Try Again</button>
</div>
</div>
<!-- Enhanced Badge Display -->
<div id="badgeDisplay" class="hidden card badge-celebration">
<h2>🎊 Achievement Unlocked! 🎊</h2>
<div id="badgeList" class="badge-showcase"></div>
<div class="badge-actions">
<button onclick="document.getElementById('badgeDisplay').classList.add('hidden')" class="btn-secondary">Continue</button>
<button onclick="window.location.reload()" class="btn-primary">Play Again</button>
</div>
</div>
</div>
</div>
<!-- Typing Practice Section -->
<div class="hidden" id="typingSection">
<div class="card">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h3>⌨️ Typing Practice</h3>
<button onclick="backToStudentDashboard()" class="btn-secondary" style="padding: 0.5rem 1rem;">
← Back to Dashboard
</button>
</div>
<div id="typingPrompt">Get ready to type...</div>
<!-- Input Mode Toggle for Typing Practice -->
<div class="input-mode-toggle">
<button class="active" data-mode="typing" onclick="toggleInputMode('typing')">
⌨️ Type
</button>
<button data-mode="handwriting" onclick="toggleInputMode('handwriting')">
✏️ Write
</button>
</div>
<div style="text-align: center; margin: 2rem 0;">
<!-- Typing Input -->
<input id="typingInput" type="text" style="max-width: 500px;"/>
<!-- Handwriting Input for Typing Practice -->
<div id="typingHandwritingContainer" class="handwriting-container" style="display: none;">
<h4>✏️ Write your response:</h4>
<!-- Canvas for handwriting in typing practice -->
<canvas id="typingHandwritingCanvas" width="600" height="300" style="width: 100%; max-width: 600px; height: 250px; border: 3px solid var(--primary); border-radius: 12px; background: white; display: block; margin: 1rem auto;"></canvas>
<!-- Canvas Controls for typing practice -->
<div class="canvas-controls">
<button onclick="clearTypingHandwriting()" class="clear-btn">🗑️ Clear</button>
<button onclick="recognizeTypingHandwriting()" class="recognize-btn">🔍 Recognize</button>
<button onclick="undoTypingHandwritingStroke()" class="undo-btn">↶ Undo</button>
</div>
<!-- Recognition Status for typing practice -->
<div id="typingRecognitionStatus" class="recognition-status empty"></div>
<!-- Recognized Text Display for typing practice -->
<div id="typingRecognizedText" class="recognized-text">Draw to see recognized text here</div>
</div>
<button onclick="submitTyping()" class="btn-primary">Submit</button>
</div>
<p id="typingFeedback" style="text-align: center; font-weight: 600;"></p>
</div>
</div>
<!-- Bible Typing Section -->
<div class="hidden" id="bibleSection">
<div class="card">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h3>📖 Bible Typing (ESV)</h3>
<button onclick="backToStudentDashboard()" class="btn-secondary" style="padding: 0.5rem 1rem;">
← Back to Dashboard
</button>
</div>
<!-- Verse Selection -->
<div style="margin-bottom: 2rem;">
<h4>Select a Bible Verse:</h4>
<select id="verseSelect" onchange="loadSelectedVerse()" style="width: 100%; max-width: 500px; margin-bottom: 1rem;">
<option value="">-- Choose a verse --</option>
</select>
<button onclick="getRandomVerse()" class="btn-secondary" style="margin-left: 1rem;">🎲 Random Verse</button>
</div>
<!-- Verse Display -->
<div id="bibleVerseDisplay" style="font-size: 1.2rem; line-height: 1.8; padding: 2rem; background: var(--bg-secondary); border-radius: var(--radius); margin-bottom: 2rem; min-height: 100px; display: flex; align-items: center; justify-content: center; text-align: center;">
Select a verse to begin typing practice
</div>
<!-- Typing Area -->
<div style="text-align: center; margin: 2rem 0;">
<textarea id="bibleInput" placeholder="Type the verse here..." style="width: 100%; max-width: 700px; min-height: 120px; font-size: 1.1rem; line-height: 1.6;"></textarea>
<div style="margin-top: 1rem;">
<button onclick="checkBibleVerse()" class="btn-primary">✓ Check Typing</button>
<button onclick="clearBibleInput()" class="btn-secondary">🗑️ Clear</button>
</div>
</div>
<!-- Feedback -->
<div id="bibleFeedback" style="text-align: center; margin-top: 2rem;"></div>
<!-- Progress -->
<div id="bibleProgress" style="margin-top: 2rem;">
<h4>📊 Typing Progress</h4>
<div id="bibleStats" style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; margin-top: 1rem;">
<div style="text-align: center; padding: 1rem; background: var(--bg-secondary); border-radius: var(--radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--primary);" id="accuracyPercent">0%</div>
<div>Accuracy</div>
</div>
<div style="text-align: center; padding: 1rem; background: var(--bg-secondary); border-radius: var(--radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--success);" id="correctWords">0</div>
<div>Correct Words</div>
</div>
<div style="text-align: center; padding: 1rem; background: var(--bg-secondary); border-radius: var(--radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--error);" id="incorrectWords">0</div>
<div>Errors</div>
</div>
</div>
</div>
</div>
</div>
<!-- Toast notification -->
<div id="toast" class="toast"></div>
</div>
<script>
// Initialize the application when DOM is loaded
window.addEventListener('DOMContentLoaded', () => {
const user = JSON.parse(localStorage.getItem('loggedInUser'));
if (user) {
if (user.role === 'admin') {
showAdmin();
} else {
showStudent();
}
}
});
</script>
<script src="js/admin.js"></script>
</body>
</html>