Spaces:
Running
Running
refactor: Externalize project list into projects.json
Browse files- .gitignore +3 -1
- index.html +1 -1
- main.js +30 -35
- projects.json +23 -0
.gitignore
CHANGED
|
@@ -4,4 +4,6 @@ server/
|
|
| 4 |
requirements.txt
|
| 5 |
start_server.sh
|
| 6 |
scripts_reminders.txt
|
| 7 |
-
GEMINI.md
|
|
|
|
|
|
|
|
|
| 4 |
requirements.txt
|
| 5 |
start_server.sh
|
| 6 |
scripts_reminders.txt
|
| 7 |
+
GEMINI.md
|
| 8 |
+
versions/
|
| 9 |
+
.gitignore
|
index.html
CHANGED
|
@@ -67,7 +67,7 @@
|
|
| 67 |
<iframe id="project-iframe" class="absolute inset-0 w-full h-full border-none" src="about:blank"></iframe>
|
| 68 |
|
| 69 |
<!-- Loading Spinner -->
|
| 70 |
-
<div id="loading-spinner" class="absolute inset-0 flex items-center justify-center
|
| 71 |
<div class="loader"></div>
|
| 72 |
</div>
|
| 73 |
|
|
|
|
| 67 |
<iframe id="project-iframe" class="absolute inset-0 w-full h-full border-none" src="about:blank"></iframe>
|
| 68 |
|
| 69 |
<!-- Loading Spinner -->
|
| 70 |
+
<div id="loading-spinner" class="absolute inset-0 flex items-center justify-center z-20 pointer-events-none">
|
| 71 |
<div class="loader"></div>
|
| 72 |
</div>
|
| 73 |
|
main.js
CHANGED
|
@@ -1,28 +1,4 @@
|
|
| 1 |
document.addEventListener('DOMContentLoaded', () => {
|
| 2 |
-
const projects = [
|
| 3 |
-
{ name: "Definitions of Probability", slug: "defining-probability.static" },
|
| 4 |
-
{ name: "Probability Rules Infographic", slug: "probability-rules.static" },
|
| 5 |
-
{ name: "Probability Trees", slug: "probability-trees.static" },
|
| 6 |
-
{ name: "Binomial Distribution", slug: "binomial-distribution-app" },
|
| 7 |
-
{ name: "Bayes' Rule Calculator", slug: "bayes-rule" },
|
| 8 |
-
{ name: "Random Variables", slug: "Random-Variables.static" },
|
| 9 |
-
{ name: "Expected Value", slug: "expected-value.static" },
|
| 10 |
-
{ name: "Standard Normal CDF", slug: "standard-normal-cdf" },
|
| 11 |
-
{ name: "Z-Tables", slug: "z-tables" },
|
| 12 |
-
{ name: "Intro to Inference", slug: "intro-inference-problems.static" },
|
| 13 |
-
{ name: "Inference for Means", slug: "Inference-Means" },
|
| 14 |
-
{ name: "Inference: One Proportion", slug: "inference-one-prop" },
|
| 15 |
-
{ name: "Sampling Dist: Two Props", slug: "sampl-dist-two-prop" },
|
| 16 |
-
{ name: "Inference: Two Proportions", slug: "inference-two-prop" },
|
| 17 |
-
{ name: "Hypothesis Testing", slug: "hypothesis-testing" },
|
| 18 |
-
{ name: "Hypothesis Testing FAQ", slug: "hypothesis-testing-faq.static" },
|
| 19 |
-
{ name: "Correlation Explorer", slug: "Correlation" },
|
| 20 |
-
{ name: "Probability Problem Set", slug: "Probability-Problem-Set.static" },
|
| 21 |
-
{ name: "Self-Study Guide", slug: "self-study-guide" },
|
| 22 |
-
{ name: "Week 5, Module 1", slug: "week-5-module-1.static" },
|
| 23 |
-
{ name: "Week 5, Module 2", slug: "week-5-module-2.static" }
|
| 24 |
-
];
|
| 25 |
-
|
| 26 |
const navList = document.querySelector('#project-nav ul');
|
| 27 |
const iframe = document.getElementById('project-iframe');
|
| 28 |
const welcomeScreen = document.getElementById('welcome-screen');
|
|
@@ -33,6 +9,34 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 33 |
let spinnerTimeout;
|
| 34 |
const loadedUrls = new Set();
|
| 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
// --- Unified Touch/Click logic for sidebar ---
|
| 37 |
sidebar.addEventListener('click', (e) => {
|
| 38 |
const link = e.target.closest('.nav-link');
|
|
@@ -90,17 +94,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 90 |
sidebar.classList.remove('is-open');
|
| 91 |
});
|
| 92 |
|
| 93 |
-
//
|
| 94 |
-
|
| 95 |
-
const li = document.createElement('li');
|
| 96 |
-
const a = document.createElement('a');
|
| 97 |
-
a.href = '#';
|
| 98 |
-
a.textContent = project.name;
|
| 99 |
-
a.dataset.slug = project.slug;
|
| 100 |
-
a.className = 'nav-link block w-full text-left px-4 py-2.5 rounded-md text-gray-300 hover:bg-gray-700/50 hover:text-white transition-colors duration-200';
|
| 101 |
-
li.appendChild(a);
|
| 102 |
-
navList.appendChild(li);
|
| 103 |
-
});
|
| 104 |
});
|
| 105 |
|
| 106 |
// This script is for the footer year, it's separate because it's not part of the main app logic
|
|
|
|
| 1 |
document.addEventListener('DOMContentLoaded', () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
const navList = document.querySelector('#project-nav ul');
|
| 3 |
const iframe = document.getElementById('project-iframe');
|
| 4 |
const welcomeScreen = document.getElementById('welcome-screen');
|
|
|
|
| 9 |
let spinnerTimeout;
|
| 10 |
const loadedUrls = new Set();
|
| 11 |
|
| 12 |
+
// --- Main App Initialization ---
|
| 13 |
+
async function initializeApp() {
|
| 14 |
+
try {
|
| 15 |
+
const response = await fetch('projects.json');
|
| 16 |
+
if (!response.ok) {
|
| 17 |
+
throw new Error(`HTTP error! status: ${response.status}`);
|
| 18 |
+
}
|
| 19 |
+
const projects = await response.json();
|
| 20 |
+
populateNav(projects);
|
| 21 |
+
} catch (error) {
|
| 22 |
+
console.error("Could not load projects:", error);
|
| 23 |
+
// Optionally, display an error message to the user in the UI
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
function populateNav(projects) {
|
| 28 |
+
projects.forEach(project => {
|
| 29 |
+
const li = document.createElement('li');
|
| 30 |
+
const a = document.createElement('a');
|
| 31 |
+
a.href = '#';
|
| 32 |
+
a.textContent = project.name;
|
| 33 |
+
a.dataset.slug = project.slug;
|
| 34 |
+
a.className = 'nav-link block w-full text-left px-4 py-2.5 rounded-md text-gray-300 hover:bg-gray-700/50 hover:text-white transition-colors duration-200';
|
| 35 |
+
li.appendChild(a);
|
| 36 |
+
navList.appendChild(li);
|
| 37 |
+
});
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
// --- Unified Touch/Click logic for sidebar ---
|
| 41 |
sidebar.addEventListener('click', (e) => {
|
| 42 |
const link = e.target.closest('.nav-link');
|
|
|
|
| 94 |
sidebar.classList.remove('is-open');
|
| 95 |
});
|
| 96 |
|
| 97 |
+
// Initialize the app
|
| 98 |
+
initializeApp();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
});
|
| 100 |
|
| 101 |
// This script is for the footer year, it's separate because it's not part of the main app logic
|
projects.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{ "name": "Definitions of Probability", "slug": "defining-probability.static" },
|
| 3 |
+
{ "name": "Probability Rules Infographic", "slug": "probability-rules.static" },
|
| 4 |
+
{ "name": "Probability Trees", "slug": "probability-trees.static" },
|
| 5 |
+
{ "name": "Binomial Distribution", "slug": "binomial-distribution-app" },
|
| 6 |
+
{ "name": "Bayes' Rule Calculator", "slug": "bayes-rule" },
|
| 7 |
+
{ "name": "Random Variables", "slug": "Random-Variables.static" },
|
| 8 |
+
{ "name": "Expected Value", "slug": "expected-value.static" },
|
| 9 |
+
{ "name": "Standard Normal CDF", "slug": "standard-normal-cdf" },
|
| 10 |
+
{ "name": "Z-Tables", "slug": "z-tables" },
|
| 11 |
+
{ "name": "Inference for Means", "slug": "Inference-Means" },
|
| 12 |
+
{ "name": "Inference: One Proportion", "slug": "inference-one-prop" },
|
| 13 |
+
{ "name": "Sampling Dist: Two Props", "slug": "sampl-dist-two-prop" },
|
| 14 |
+
{ "name": "Inference: Two Proportions", "slug": "inference-two-prop" },
|
| 15 |
+
{ "name": "Hypothesis Testing", "slug": "hypothesis-testing" },
|
| 16 |
+
{ "name": "Hypothesis Testing FAQ", "slug": "hypothesis-testing-faq.static" },
|
| 17 |
+
{ "name": "Correlation Explorer", "slug": "Correlation" },
|
| 18 |
+
{ "name": "Probability Problem Set", "slug": "Probability-Problem-Set.static" },
|
| 19 |
+
{ "name": "Self-Study Intro to Inference", "slug": "intro-inference-problems.static" },
|
| 20 |
+
{ "name": "Self-Study Guide", "slug": "self-study-guide" },
|
| 21 |
+
{ "name": "Week 5, Module 1", "slug": "week-5-module-1.static" },
|
| 22 |
+
{ "name": "Week 5, Module 2", "slug": "week-5-module-2.static" }
|
| 23 |
+
]
|