Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2026-01-10 - Search Keyboard Shortcut & Accessibility
**Learning:** Users often rely on standard keyboard shortcuts like `/` or `Ctrl+K` for search, but visual cues are essential for discoverability. Adding a `.sr-only` label significantly improves accessibility for screen readers without altering the visual design.
**Action:** When implementing search features, always include a proper label (even if visually hidden) and consider adding standard keyboard shortcuts with visual hints for desktop users.
352 changes: 177 additions & 175 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,175 +1,177 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- Updated CSP to allow CDN resources and Google Fonts -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://usis-cdn.eniamza.com https://fonts.googleapis.com https://fonts.gstatic.com https://cdn.jsdelivr.net; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net;">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<!-- Social / Open Graph meta tags for rich link previews -->
<!-- NOTE: For best results, use absolute URLs when you deploy. Adjust the "og:url" and image URL to your production domain if different. -->
<meta property="og:title" content="Connect Dump Analyser" />
<meta property="og:description" content="Analyse USIS course dumps across semesters, predict TBA faculties, and explore historic scheduling patterns." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://connect-dumps.itzmrz.xyz/" />
<meta property="og:image" content="https://connect-dumps.itzmrz.xyz/img.png" />
<meta property="og:image:alt" content="Connect Dump Analyser preview" />
<meta property="og:image:type" content="image/png" />
<!-- Optional (safely ignored if dimensions differ) -->
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<!-- Twitter Card (also used by some clients as fallback) -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Connect Dump Analyser" />
<meta name="twitter:description" content="Analyse USIS course dumps across semesters with faculty predictions for TBA courses." />
<meta name="twitter:image" content="https://connect-dumps.itzmrz.xyz/img.png" />
<link rel="canonical" href="https://connect-dumps.itzmrz.xyz/" />
<title>Connect Dump Analyser V2.0</title>
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="styles.css">
<!-- Material Icons for better UX -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Bootstrap Icons for GitHub logo -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<!-- Header area -->
<header class="site-header">
<div class="header-top">
<label class="theme-switch" aria-label="Toggle dark mode">
<input type="checkbox" id="themeToggle">
<span class="slider">
<span class="sun material-icons">light_mode</span>
<span class="moon material-icons">dark_mode</span>
</span>
</label>
<div class="header-title">
<h1>Connect Dump Analyser <span class="version-number">v2.0</span></h1>
<div class="author-footer">
<a href="https://github.com/itzMRZ/" target="_blank" rel="noopener noreferrer">
by <i class="bi bi-github github-icon"></i> MRZ
</a>
</div>
</div>
<button class="help-button" id="helpButton" aria-label="Help">
<span class="material-icons">help_outline</span>
</button>
</div>
</header>

<!-- Hidden legacy status container for JS compatibility -->
<div class="status-container"></div>

<div class="button-container" id="semesterButtons">
<!-- Semester buttons will be dynamically generated -->
</div>
<div class="search-status-wrapper">
<div class="search-container">
<input type="text" id="searchInput" placeholder="Search by Course Code, Faculty, or Name...">
<span class="search-icon material-icons">search</span>
<button id="clearSearch" class="clear-search" aria-label="Clear search">×</button>
</div>
<div id="data-status" class="data-status"></div>
</div>

<!-- Mobile pagination with page numbers -->
<div class="mobile-pagination">
<div id="pageNumbers" class="page-numbers">
<!-- Page numbers will be generated dynamically -->
</div>
</div>

<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Course Code</th>
<th class="sortable" data-sort="section">SEC <span class="sort-icon"></span></th>
<th class="sortable" data-sort="facultyInitial">Faculty <span class="sort-icon"></span></th>
<th>Faculty Info</th>
<th class="sortable" data-sort="schedule">Schedule <span class="sort-icon"></span></th>
<th>Lab Schedule</th>
<th class="sortable" data-sort="available">Available <span class="sort-icon"></span></th>
<th class="sortable" data-sort="booked">Booked <span class="sort-icon"></span></th>
<th class="sortable" data-sort="capacity">Capacity <span class="sort-icon"></span></th>
<th>Exam Date</th>
<th>Room</th>
</tr>
</thead>
<tbody id="courseTableBody"></tbody>
</table>
</div>

<div class="pagination">
<button id="prevPageBottom" aria-label="Previous page"><span class="material-icons">arrow_back</span></button>
<span id="pageInfoBottom">Page 1 of 1</span>
<button id="nextPageBottom" aria-label="Next page"><span class="material-icons">arrow_forward</span></button>
</div>
</div>

<!-- Back to top button -->
<a href="#" class="back-to-top" id="backToTop" aria-label="Back to top">
<span class="material-icons">arrow_upward</span>
</a>

<!-- Info Modal with simplified content -->
<div class="modal-overlay" id="infoModal">
<div class="info-modal">
<h2 class="modal-title">About Connect Dump Analyser</h2>

<div class="modal-section">
<h3>Purpose</h3>
<p>This tool helps to explore courses across multiple semesters, with features for cross matching historic faculty placement data for TBA.</p>
</div>

<div class="modal-section">
<h3>Faculty Prediction for TBA Courses</h3>
<p>For courses with "TBA" faculty, the system predicts possible faculty assignments using:</p>
<ul>
<li><strong>Section History Match</strong> - Faculty who taught this section in previous semesters</li>
<li><strong>Time Match</strong> - Faculty who taught this course at similar times</li>
<li><strong>Room Match</strong> - Previously assigned rooms for this course [BETA]</li>
</ul>
</div>

<!-- Enhanced acknowledgements section -->
<div class="acknowledgements">
<summary>Acknowledgements</summary>
<div class="acknowledgements-content">
This site owes its existence to the invaluable support and resources of
<strong>Tashfeen Vaia</strong>, aka
<a href="https://github.com/Eniamza" target="_blank" rel="noopener noreferrer">
<i class="bi bi-github"></i> Eniamza
</a>
</div>
</div>

<button class="modal-close" id="closeModal">&times;</button>
</div>
</div>

<!-- Zoom controls for mobile -->
<div class="zoom-controls">
<button id="zoomOut" class="zoom-button" aria-label="Zoom out">
<span class="material-icons">remove</span>
</button>
<button id="zoomIn" class="zoom-button" aria-label="Zoom in">
<span class="material-icons">add</span>
</button>
</div>

<!-- Core scripts -->
<script src="js/config.js"></script>
<script src="js/utils.js"></script>
<script src="js/dataService.js"></script>
<script src="js/uiController.js"></script>
<script src="js/app.js"></script>

<!-- Vercel Web Analytics -->
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
</script>
<script defer src="/_vercel/insights/script.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- Updated CSP to allow CDN resources and Google Fonts -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://usis-cdn.eniamza.com https://fonts.googleapis.com https://fonts.gstatic.com https://cdn.jsdelivr.net; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net;">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<!-- Social / Open Graph meta tags for rich link previews -->
<!-- NOTE: For best results, use absolute URLs when you deploy. Adjust the "og:url" and image URL to your production domain if different. -->
<meta property="og:title" content="Connect Dump Analyser" />
<meta property="og:description" content="Analyse USIS course dumps across semesters, predict TBA faculties, and explore historic scheduling patterns." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://connect-dumps.itzmrz.xyz/" />
<meta property="og:image" content="https://connect-dumps.itzmrz.xyz/img.png" />
<meta property="og:image:alt" content="Connect Dump Analyser preview" />
<meta property="og:image:type" content="image/png" />
<!-- Optional (safely ignored if dimensions differ) -->
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<!-- Twitter Card (also used by some clients as fallback) -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Connect Dump Analyser" />
<meta name="twitter:description" content="Analyse USIS course dumps across semesters with faculty predictions for TBA courses." />
<meta name="twitter:image" content="https://connect-dumps.itzmrz.xyz/img.png" />
<link rel="canonical" href="https://connect-dumps.itzmrz.xyz/" />
<title>Connect Dump Analyser V2.0</title>
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="styles.css">
<!-- Material Icons for better UX -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Bootstrap Icons for GitHub logo -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<!-- Header area -->
<header class="site-header">
<div class="header-top">
<label class="theme-switch" aria-label="Toggle dark mode">
<input type="checkbox" id="themeToggle">
<span class="slider">
<span class="sun material-icons">light_mode</span>
<span class="moon material-icons">dark_mode</span>
</span>
</label>
<div class="header-title">
<h1>Connect Dump Analyser <span class="version-number">v2.0</span></h1>
<div class="author-footer">
<a href="https://github.com/itzMRZ/" target="_blank" rel="noopener noreferrer">
by <i class="bi bi-github github-icon"></i> MRZ
</a>
</div>
</div>
<button class="help-button" id="helpButton" aria-label="Help">
<span class="material-icons">help_outline</span>
</button>
</div>
</header>

<!-- Hidden legacy status container for JS compatibility -->
<div class="status-container"></div>

<div class="button-container" id="semesterButtons">
<!-- Semester buttons will be dynamically generated -->
</div>
<div class="search-status-wrapper">
<div class="search-container">
<label for="searchInput" class="sr-only">Search courses</label>
<input type="text" id="searchInput" placeholder="Search by Course Code, Faculty, or Name...">
<span class="search-icon material-icons">search</span>
<button id="clearSearch" class="clear-search" aria-label="Clear search">×</button>
<span class="shortcut-hint" aria-hidden="true" title="Press / to search">/</span>
</div>
<div id="data-status" class="data-status"></div>
</div>

<!-- Mobile pagination with page numbers -->
<div class="mobile-pagination">
<div id="pageNumbers" class="page-numbers">
<!-- Page numbers will be generated dynamically -->
</div>
</div>

<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Course Code</th>
<th class="sortable" data-sort="section">SEC <span class="sort-icon"></span></th>
<th class="sortable" data-sort="facultyInitial">Faculty <span class="sort-icon"></span></th>
<th>Faculty Info</th>
<th class="sortable" data-sort="schedule">Schedule <span class="sort-icon"></span></th>
<th>Lab Schedule</th>
<th class="sortable" data-sort="available">Available <span class="sort-icon"></span></th>
<th class="sortable" data-sort="booked">Booked <span class="sort-icon"></span></th>
<th class="sortable" data-sort="capacity">Capacity <span class="sort-icon"></span></th>
<th>Exam Date</th>
<th>Room</th>
</tr>
</thead>
<tbody id="courseTableBody"></tbody>
</table>
</div>

<div class="pagination">
<button id="prevPageBottom" aria-label="Previous page"><span class="material-icons">arrow_back</span></button>
<span id="pageInfoBottom">Page 1 of 1</span>
<button id="nextPageBottom" aria-label="Next page"><span class="material-icons">arrow_forward</span></button>
</div>
</div>

<!-- Back to top button -->
<a href="#" class="back-to-top" id="backToTop" aria-label="Back to top">
<span class="material-icons">arrow_upward</span>
</a>

<!-- Info Modal with simplified content -->
<div class="modal-overlay" id="infoModal">
<div class="info-modal">
<h2 class="modal-title">About Connect Dump Analyser</h2>

<div class="modal-section">
<h3>Purpose</h3>
<p>This tool helps to explore courses across multiple semesters, with features for cross matching historic faculty placement data for TBA.</p>
</div>

<div class="modal-section">
<h3>Faculty Prediction for TBA Courses</h3>
<p>For courses with "TBA" faculty, the system predicts possible faculty assignments using:</p>
<ul>
<li><strong>Section History Match</strong> - Faculty who taught this section in previous semesters</li>
<li><strong>Time Match</strong> - Faculty who taught this course at similar times</li>
<li><strong>Room Match</strong> - Previously assigned rooms for this course [BETA]</li>
</ul>
</div>

<!-- Enhanced acknowledgements section -->
<div class="acknowledgements">
<summary>Acknowledgements</summary>
<div class="acknowledgements-content">
This site owes its existence to the invaluable support and resources of
<strong>Tashfeen Vaia</strong>, aka
<a href="https://github.com/Eniamza" target="_blank" rel="noopener noreferrer">
<i class="bi bi-github"></i> Eniamza
</a>
</div>
</div>

<button class="modal-close" id="closeModal">&times;</button>
</div>
</div>

<!-- Zoom controls for mobile -->
<div class="zoom-controls">
<button id="zoomOut" class="zoom-button" aria-label="Zoom out">
<span class="material-icons">remove</span>
</button>
<button id="zoomIn" class="zoom-button" aria-label="Zoom in">
<span class="material-icons">add</span>
</button>
</div>

<!-- Core scripts -->
<script src="js/config.js"></script>
<script src="js/utils.js"></script>
<script src="js/dataService.js"></script>
<script src="js/uiController.js"></script>
<script src="js/app.js"></script>

<!-- Vercel Web Analytics -->
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
</script>
<script defer src="/_vercel/insights/script.js"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions js/uiController.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,31 @@ const UIController = {
}
});
}

// Keyboard Shortcuts
document.addEventListener('keydown', (e) => {
// Guard clause if search input doesn't exist
if (!this.elements.searchInput) return;

// Focus search on '/' or Ctrl+K (Cmd+K)
if ((e.key === '/' || (e.key === 'k' && (e.metaKey || e.ctrlKey))) &&
document.activeElement !== this.elements.searchInput) {

// Don't trigger if user is typing in another input (if any existed)
if (document.activeElement.tagName === 'INPUT' ||
document.activeElement.tagName === 'TEXTAREA') {
return;
}

e.preventDefault();
this.elements.searchInput.focus();
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
}

// Remove focus from search on Escape
if (e.key === 'Escape' && document.activeElement === this.elements.searchInput) {
this.elements.searchInput.blur();
}
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},

/**
Expand Down
Loading