Skip to content

Commit a720748

Browse files
committed
2 parents 4443c8c + 6eee40a commit a720748

7 files changed

Lines changed: 458 additions & 75 deletions

File tree

feedback-loader.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*************************************************
2+
* Feedback Modal Loader (Search-style)
3+
*************************************************/
4+
5+
const FEEDBACK_ENDPOINT =
6+
"https://script.google.com/macros/s/AKfycbwH1QM0zc4DcYXcG0CJIVoien-vj8VmCi0wEUxeEdZX0EbROxx6rWvLgIi2vSHtd9TBIQ/exec";
7+
8+
/* Wire button safely */
9+
document.addEventListener("DOMContentLoaded", () => {
10+
const btn = document.querySelector(".feedback-btn");
11+
if (!btn) return;
12+
btn.addEventListener("click", openFeedback);
13+
});
14+
15+
/* Open feedback modal */
16+
window.openFeedback = function () {
17+
const overlay = document.getElementById("feedbackOverlay");
18+
const modal = document.getElementById("feedbackModal");
19+
20+
if (!overlay || !modal) return;
21+
22+
overlay.hidden = false;
23+
modal.hidden = false;
24+
document.body.style.overflow = "hidden";
25+
26+
modal.innerHTML = `
27+
<div class="feedback-wrapper search-wrapper" role="dialog" aria-modal="true">
28+
29+
<!-- Header -->
30+
<div class="sw-header">
31+
<svg
32+
class="sw-icon"
33+
viewBox="0 0 24 24"
34+
fill="none"
35+
stroke="currentColor"
36+
stroke-width="2"
37+
stroke-linecap="round"
38+
stroke-linejoin="round"
39+
aria-hidden="true"
40+
>
41+
<!-- Taller speech bubble -->
42+
<path d="M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H9l-5 5v-5H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" />
43+
44+
<!-- Dots (spread out more) -->
45+
<circle cx="8" cy="11.5" r="1" fill="currentColor" stroke-width="0.8" />
46+
<circle cx="12" cy="11.5" r="1" fill="currentColor" stroke-width="0.8"/>
47+
<circle cx="16" cy="11.5" r="1" fill="currentColor" stroke-width="0.8" />
48+
</svg>
49+
50+
51+
<h2 class="sw-title">Send Feedback</h2>
52+
<button class="sw-close" data-feedback-close aria-label="Close feedback">
53+
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="3">
54+
<line x1="18" y1="6" x2="6" y2="18"></line>
55+
<line x1="6" y1="6" x2="18" y2="18"></line>
56+
</svg>
57+
</button>
58+
</div>
59+
60+
<!-- Form -->
61+
<form id="feedbackForm" class="feedback-form">
62+
63+
<div class="field">
64+
<label>What is your role? *</label>
65+
<select name="role" required class="sw-input">
66+
<option value="">Select</option>
67+
<option>Author</option>
68+
<option>Instructor</option>
69+
<option>Student</option>
70+
</select>
71+
</div>
72+
73+
<div class="field">
74+
<label>Which part of the Tutorial Hub are you commenting on? *</label>
75+
<input name="section" required class="sw-input" />
76+
</div>
77+
78+
<div class="field">
79+
<label>If you notice an issue, please explain it.</label>
80+
<textarea name="issue" class="sw-input"></textarea>
81+
</div>
82+
83+
<div class="field">
84+
<label>Optional: Email or contact</label>
85+
<input name="contact" class="sw-input" />
86+
</div>
87+
88+
<div class="sw-actions">
89+
<button type="submit" class="sw-btn">
90+
Submit Feedback
91+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
92+
<path d="M9 18l6-6-6-6"></path>
93+
</svg>
94+
</button>
95+
</div>
96+
97+
</form>
98+
</div>
99+
`;
100+
101+
attachFeedbackHandlers();
102+
};
103+
104+
/* Submit + close logic */
105+
function attachFeedbackHandlers() {
106+
const overlay = document.getElementById("feedbackOverlay");
107+
const modal = document.getElementById("feedbackModal");
108+
const form = modal.querySelector("#feedbackForm");
109+
110+
if (!form) return;
111+
112+
form.addEventListener("submit", async (e) => {
113+
e.preventDefault();
114+
115+
const formData = new FormData(form);
116+
formData.append("timestamp_client", new Date().toISOString());
117+
formData.append(
118+
"timezone",
119+
Intl.DateTimeFormat().resolvedOptions().timeZone
120+
);
121+
formData.append("page", window.location.href);
122+
123+
await fetch(FEEDBACK_ENDPOINT, {
124+
method: "POST",
125+
body: new URLSearchParams(formData),
126+
});
127+
128+
form.innerHTML = `
129+
<div class="sw-results">
130+
<p><strong>Thank you!</strong></p>
131+
<p>Your feedback has been submitted.</p>
132+
</div>
133+
`;
134+
});
135+
136+
const close = () => {
137+
overlay.hidden = true;
138+
modal.hidden = true;
139+
modal.innerHTML = "";
140+
document.body.style.overflow = "";
141+
};
142+
143+
overlay.addEventListener("click", close, { once: true });
144+
modal
145+
.querySelectorAll("[data-feedback-close]")
146+
.forEach((btn) => btn.addEventListener("click", close));
147+
}

feedback.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const form = document.getElementById("feedbackForm");
2+
3+
form.addEventListener("submit", e => {
4+
e.preventDefault();
5+
6+
fetch("https://script.google.com/macros/s/AKfycbwTdBpSEDirKJp2KDqHT56N6TNwEx9zkVvGsTRBLc1TL70lTJ_ERmjSWky3UG6gbwYQ6g/exec", {
7+
method: "POST",
8+
body: new URLSearchParams(new FormData(form)),
9+
mode: "no-cors"
10+
}).then(() => {
11+
alert("submitted");
12+
closeFeedback();
13+
});
14+
});

index.html

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<div class="header-left">
1515
<button id="menu-toggle" class="menu-toggle"></button>
1616

17-
<a href="/" class="brand" aria-label="OLI Torus Launchpad (home)">
17+
<a href="#" class="brand" aria-label="OLI Torus Launchpad (home)">
1818
<img src="assets/images/logo.png" alt="" class="brand-logo" aria-hidden="true" />
1919
<span class="brand-oli">OLI</span>
2020
<span class="brand-torus">Torus</span>
@@ -33,12 +33,13 @@
3333
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
3434
</svg>
3535
</a>
36-
<a href="https://forms.gle/3ta7TqVyWjRdgTmx9"
37-
target="_blank"
38-
class="feedback-btn"
39-
aria-label="Feedback">
36+
<button
37+
class="feedback-btn"
38+
aria-label="Feedback"
39+
onclick="openFeedback()">
4040
<img src="assets/images/feedback.png" alt="Feedback" class="feedback-icon" />
41-
</a>
41+
</button>
42+
4243

4344
<button class="home-btn" aria-label="Home" data-page="pages/introduction/logging-in.html">
4445
<img src="assets/images/home.png" alt="Home" class="home-icon" />
@@ -253,9 +254,15 @@
253254
</main>
254255
</div>
255256

256-
<script src="main.js"></script>
257-
<div id="searchOverlay" hidden></div>
258-
<div id="searchModal" hidden></div>
259-
<script src="search-wrapper-loader.js" defer></script>
257+
<script src="main.js"></script>
258+
<script src="feedback-loader.js" defer></script>
259+
260+
<div id="feedbackOverlay" hidden></div>
261+
<div id="feedbackModal" hidden></div>
262+
263+
<div id="searchOverlay" hidden></div>
264+
<div id="searchModal" hidden></div>
265+
<script src="search-wrapper-loader.js" defer></script>
266+
260267
</body>
261268
</html>

main.js

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,40 @@ console.log('main.js loaded');
44

55

66
(function () {
7-
// --- small DOM helpers ---
7+
// --- DOM helpers ---
88
const $all = (sel, root = document) => Array.from(root.querySelectorAll(sel));
99
const $ = (sel, root = document) => root.querySelector(sel);
1010

11-
// =============================================================
11+
1212
// Load welcome page by default on first visit
13-
// =============================================================
1413
window.addEventListener("DOMContentLoaded", () => {
1514
const content = document.querySelector(".content");
16-
if (content) {
17-
fetch("pages/introduction/welcome.html")
18-
.then(r => r.text())
19-
.then(html => {
20-
content.innerHTML = html;
21-
// Optionally highlight the matching menu item
22-
const li = document.querySelector('.submenu li[data-page="pages/welcome.html"]');
23-
if (li) {
24-
document.querySelectorAll(".submenu li.selected").forEach(el => el.classList.remove("selected"));
25-
li.classList.add("selected");
26-
}
27-
})
28-
.catch(err => console.error("Error loading welcome page:", err));
15+
if (!content) return;
16+
17+
const params = new URLSearchParams(window.location.search);
18+
const pageFromUrl = params.get("page");
19+
20+
if (pageFromUrl) {
21+
loadPage(pageFromUrl);
22+
23+
const li = document.querySelector(`.submenu li[data-page="${pageFromUrl}"]`);
24+
if (li) {
25+
document
26+
.querySelectorAll(".submenu li.selected")
27+
.forEach(el => el.classList.remove("selected"));
28+
li.classList.add("selected");
29+
}
30+
31+
return;
2932
}
33+
34+
// fallback only when no ?page=
35+
fetch("pages/introduction/welcome.html")
36+
.then(r => r.text())
37+
.then(html => {
38+
content.innerHTML = html;
39+
})
40+
.catch(err => console.error("Error loading welcome page:", err));
3041
});
3142

3243

@@ -49,14 +60,18 @@ window.addEventListener("DOMContentLoaded", () => {
4960
document.addEventListener('click', function (event) {
5061
const target = event.target.closest('[data-page]');
5162
if (!target) return;
63+
if (target.querySelector('a[href]')) return;
5264
setActiveMenuItem(target);
5365

5466
// Prevent full page reload
5567
event.preventDefault();
5668

5769
const page = target.getAttribute('data-page');
5870
if (!page) return;
59-
71+
72+
history.pushState({ page }, '', `?page=${encodeURIComponent(page)}`);
73+
74+
6075
// Load the HTML into the main content area
6176
fetch(page)
6277
.then(response => response.text())
@@ -191,6 +206,7 @@ document.addEventListener('click', function (event) {
191206
const homeBtn = document.querySelector('.home-btn');
192207
if (homeBtn) {
193208
homeBtn.addEventListener('click', () => {
209+
selectMenuItem(homeBtn);
194210
const li = document.querySelector(`.submenu li[data-page="${HOME_TARGET_PAGE}"]`);
195211
if (!li) return console.warn('Home target not found:', HOME_TARGET_PAGE);
196212

@@ -318,5 +334,4 @@ document.addEventListener('click', (e) => {
318334
setTimeout(() => li.classList.remove('spotlight'), 1100);
319335
});
320336

321-
322337
})();

pages/set-up-your-course/create-a-new-project.html

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,22 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
76
<link rel="stylesheet" href="./style.css" />
87
<link rel="icon" href="data:,">
9-
10-
<style>
11-
.enhanced-video {
12-
padding: 24px 0 32px;
13-
margin-bottom: 32px;
14-
border-radius: 12px;
15-
}
16-
17-
.title-bar {
18-
font-size: 1.3rem;
19-
font-weight: 600;
20-
padding: 12px 20px;
21-
margin-bottom: 16px;
22-
}
23-
</style>
248
</head>
25-
269
<body>
2710

28-
<div class="video-container enhanced-video">
29-
30-
<div class="title-bar">
31-
Create a New Project
32-
</div>
33-
11+
<div class="video-container">
3412
<video
3513
controls
3614
preload="metadata"
3715
playsinline
38-
style="
39-
width:100%;
40-
height:auto;
41-
display:block;
42-
background:#000;
43-
border-radius:12px;
44-
border:1px solid var(--border);
45-
box-shadow:var(--shadow);
46-
"
47-
>
16+
style="width:100%;height:auto;display:block;background:#000;border-radius:12px;border:1px solid var(--border);box-shadow:var(--shadow);"
17+
>
18+
<!-- UPDATE THIS: video file -->
4819
<source src="./assets/videos/set-up-your-course/create-a-new-project.mp4" type="video/mp4" />
4920

21+
<!-- UPDATE THIS: captions file -->
5022
<track
5123
src="./assets/captions/set-up-your-course/create-a-new-project.vtt"
5224
kind="subtitles"
@@ -58,6 +30,17 @@
5830
Your browser does not support the video tag.
5931
</video>
6032

33+
<!-- UPDATE THIS: video title -->
34+
<div class="title-bar">
35+
<span class="video-title">Create a New Project</span>
36+
37+
<span class="version-badge">
38+
(Placeholder)This video applies to Torus <strong>0.32.3</strong> and newer <!-- UPDATE THIS: version number -->
39+
</span>
40+
</div>
41+
42+
</div>
43+
6144
</div>
6245

6346
</body>

0 commit comments

Comments
 (0)