Skip to content

Commit df7546b

Browse files
authored
Merge pull request #36 from webflow/fix-empty-session-list
refactor: remove unused session-tabs and utils scripts; enhance templ…
2 parents 31b81d2 + 375280e commit df7546b

5 files changed

Lines changed: 86 additions & 22 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'scripts': patch
3+
---
4+
5+
Display an empty-state message on Pro session template pages when a selected time slot has no upcoming sessions.

packages/scripts/dist/pro/session-tabs.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/scripts/dist/pro/template-page.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/scripts/dist/pro/utils.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/scripts/src/pro/template-page.ts

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,50 @@ interface SessionData {
1717
sessionType: 'live-training' | 'workshop' | null;
1818
}
1919

20+
console.log('template-page.ts');
21+
2022
const NUM_OCCURRENCES_TO_SHOW = 3;
23+
const EMPTY_STATE_ID = 'pro-session-empty-state';
24+
const EMPTY_STATE_MESSAGE = 'No upcoming sessions are scheduled right now. Check back soon.';
25+
26+
function showNoUpcomingSessionsMessage(): void {
27+
const tabsContainer = document.querySelector('.cc_pro_session-tabs') as HTMLElement | null;
28+
if (!tabsContainer || document.getElementById(EMPTY_STATE_ID)) {
29+
return;
30+
}
31+
32+
const tabMenu = document.querySelector('.cc_pro_session-tab-menu') as HTMLElement | null;
33+
const tabButtons = document.querySelectorAll<HTMLElement>('.cc_pro_tabs_button');
34+
tabMenu?.style.setProperty('display', 'none');
35+
tabButtons.forEach((button) => {
36+
button.style.display = 'none';
37+
});
38+
39+
const emptyState = document.createElement('p');
40+
emptyState.id = EMPTY_STATE_ID;
41+
emptyState.className = 'cc_pro-session_empty-state';
42+
emptyState.textContent = EMPTY_STATE_MESSAGE;
43+
emptyState.setAttribute('role', 'status');
44+
emptyState.style.margin = '1.5rem 0 0';
45+
emptyState.style.color = 'rgba(255, 255, 255, 0.7)';
46+
emptyState.style.fontSize = '1rem';
47+
emptyState.style.lineHeight = '1.5';
48+
49+
tabsContainer.appendChild(emptyState);
50+
}
51+
52+
function renderEmptyRecurrenceMessage(listElement: Element): void {
53+
const emptyItem = document.createElement('li');
54+
emptyItem.className = 'cc_pro-session_empty-state';
55+
emptyItem.textContent = EMPTY_STATE_MESSAGE;
56+
emptyItem.setAttribute('role', 'status');
57+
emptyItem.style.listStyle = 'none';
58+
emptyItem.style.color = 'rgba(255, 255, 255, 0.7)';
59+
emptyItem.style.fontSize = '1rem';
60+
emptyItem.style.lineHeight = '1.5';
61+
62+
listElement.appendChild(emptyItem);
63+
}
2164

2265
/**
2366
* Parse session data from the #data-saver element
@@ -160,11 +203,11 @@ function updateRecurrenceUI(
160203
blackoutDates: DateTime[],
161204
registrationLink: string,
162205
sessionType: 'live-training' | 'workshop' | null
163-
): void {
206+
): boolean {
164207
const container = document.querySelector(`#datetimes-${index}`);
165208
if (!container) {
166209
console.error(`[updateRecurrenceUI] Container #datetimes-${index} not found`);
167-
return;
210+
return false;
168211
}
169212

170213
// Get next NUM_OCCURRENCES_TO_SHOW occurrences
@@ -176,12 +219,6 @@ function updateRecurrenceUI(
176219
recurrence.until
177220
);
178221

179-
if (occurrences.length === 0) {
180-
// Hide the container if no occurrences
181-
(container as HTMLElement).style.display = 'none';
182-
return;
183-
}
184-
185222
// Show the container
186223
(container as HTMLElement).style.display = '';
187224

@@ -214,12 +251,23 @@ function updateRecurrenceUI(
214251
const listElement = container.querySelector('ul.cc_pro-session_tab-list');
215252
if (!listElement) {
216253
console.error(`[updateRecurrenceUI] List element not found in container ${index}`);
217-
return;
254+
return false;
218255
}
219256

220257
// Clear existing items
221258
listElement.innerHTML = '';
222259

260+
if (occurrences.length === 0) {
261+
renderEmptyRecurrenceMessage(listElement);
262+
263+
const linkElement = container.querySelector('a.button');
264+
if (linkElement) {
265+
(linkElement as HTMLElement).style.display = 'none';
266+
}
267+
268+
return false;
269+
}
270+
223271
// Add new items with the new structure
224272
occurrences.forEach((occurrence) => {
225273
// Always convert to user's local timezone (dates are input in America/New_York)
@@ -269,44 +317,57 @@ function updateRecurrenceUI(
269317
} else if (linkElement) {
270318
(linkElement as HTMLElement).style.display = 'none';
271319
}
320+
321+
return true;
272322
}
273323

274324
/**
275325
* Initialize the template page
276326
* Times are always displayed in the user's local timezone
277327
*/
278-
function initTemplatePage(): void {
328+
function initTemplatePage(): boolean {
279329
const dataSaver = document.querySelector('#data-saver') as HTMLElement;
280330
if (!dataSaver) {
281331
console.error('[initTemplatePage] #data-saver element not found');
282-
return;
332+
return false;
283333
}
284334

285335
const sessionData = parseSessionData(dataSaver);
286336
if (!sessionData) {
287337
console.error('[initTemplatePage] Failed to parse session data');
288-
return;
338+
showNoUpcomingSessionsMessage();
339+
return false;
289340
}
290341

291342
// Update all recurrences (always show in user's local timezone)
343+
let hasUpcomingSessions = false;
292344
sessionData.recurrences.forEach((recurrence, index) => {
293-
updateRecurrenceUI(
345+
const recurrenceHasUpcomingSessions = updateRecurrenceUI(
294346
index + 1,
295347
recurrence,
296348
sessionData.blackoutDates,
297349
sessionData.registrationLinks[index],
298350
sessionData.sessionType
299351
);
352+
hasUpcomingSessions = hasUpcomingSessions || recurrenceHasUpcomingSessions;
300353
});
354+
355+
if (!hasUpcomingSessions) {
356+
showNoUpcomingSessionsMessage();
357+
}
358+
359+
return hasUpcomingSessions;
360+
}
361+
362+
function initTemplatePageWithTabs(): void {
363+
if (initTemplatePage()) {
364+
initTabMenuScrolling();
365+
}
301366
}
302367

303368
// Run when DOM is ready
304369
if (document.readyState === 'loading') {
305-
document.addEventListener('DOMContentLoaded', () => {
306-
initTemplatePage();
307-
initTabMenuScrolling();
308-
});
370+
document.addEventListener('DOMContentLoaded', initTemplatePageWithTabs);
309371
} else {
310-
initTemplatePage();
311-
initTabMenuScrolling();
372+
initTemplatePageWithTabs();
312373
}

0 commit comments

Comments
 (0)