PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / week-schedule / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/week-schedule/frontend.js

185 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 var DAY_NAMES = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
5
6 function fmt(h, m, format) {
7 m = m || 0;
8 if (format === '24h') {
9 return ('0' + h).slice(-2) + ':' + ('0' + m).slice(-2);
10 }
11 var ampm = h >= 12 ? 'PM' : 'AM';
12 var h12 = h % 12 || 12;
13 return h12 + (m ? ':' + ('0' + m).slice(-2) : '') + ' ' + ampm;
14 }
15
16 function applyCSS(el, styles) {
17 Object.keys(styles).forEach(function (k) { el.style[k] = styles[k]; });
18 }
19
20 function makeEl(tag, className, styles) {
21 var el = document.createElement(tag);
22 if (className) el.className = className;
23 if (styles) applyCSS(el, styles);
24 return el;
25 }
26
27 function init() {
28 document.querySelectorAll('.bkbg-wscd-app').forEach(function (appEl) {
29 if (appEl.dataset.rendered) return;
30 appEl.dataset.rendered = '1';
31
32 var opts;
33 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
34 var o = Object.assign({
35 events: [],
36 dayLabels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
37 startHour: 8,
38 endHour: 20,
39 cellHeight: 60,
40 showTime: true,
41 showInstructor: true,
42 showLocation: false,
43 showWeekend: true,
44 timeFormat: '12h',
45 title: 'Class Schedule',
46 showTitle: true,
47 bgColor: '#ffffff',
48 headerBg: '#f8fafc',
49 headerColor: '#1e293b',
50 gridColor: '#f1f5f9',
51 borderColor: '#e2e8f0',
52 timeBg: '#f8fafc',
53 timeColor: '#64748b',
54 borderRadius: 8,
55 eventRadius: 6,
56 fontSize: 12
57 }, opts);
58
59 var numDays = o.showWeekend ? 7 : 5;
60 var totalHours = o.endHour - o.startHour;
61 var gridHeight = totalHours * o.cellHeight;
62
63 // Outer wrap
64 var wrap = makeEl('div', 'bkbg-wscd-wrap');
65 wrap.style.setProperty('--bkbg-wscd-border', o.borderColor);
66 wrap.style.setProperty('--bkbg-wscd-radius', o.borderRadius + 'px');
67 wrap.style.setProperty('--bkbg-wscd-cell-h', o.cellHeight + 'px');
68 wrap.style.setProperty('--bkbg-wscd-grid', o.gridColor);
69 wrap.style.background = o.bgColor;
70
71 // Title
72 if (o.showTitle && o.title) {
73 var titleEl = makeEl('div', 'bkbg-wscd-title');
74 titleEl.textContent = o.title;
75 titleEl.style.color = o.headerColor;
76 wrap.appendChild(titleEl);
77 }
78
79 // Grid container
80 var grid = makeEl('div', 'bkbg-wscd-grid');
81
82 // Header row
83 var headerRow = makeEl('div', 'bkbg-wscd-header-row');
84
85 var corner = makeEl('div', 'bkbg-wscd-time-corner');
86 applyCSS(corner, { background: o.headerBg, borderRight: '1px solid ' + o.borderColor, borderBottom: '1px solid ' + o.borderColor });
87 headerRow.appendChild(corner);
88
89 for (var d = 0; d < numDays; d++) {
90 var dayHeader = makeEl('div', 'bkbg-wscd-day-header');
91 dayHeader.textContent = o.dayLabels[d] || DAY_NAMES[d];
92 applyCSS(dayHeader, { background: o.headerBg, color: o.headerColor, borderRight: '1px solid ' + o.borderColor, borderBottom: '1px solid ' + o.borderColor });
93 headerRow.appendChild(dayHeader);
94 }
95 grid.appendChild(headerRow);
96
97 // Body row
98 var bodyRow = makeEl('div', 'bkbg-wscd-body-row');
99
100 // Time column
101 var timeCol = makeEl('div', 'bkbg-wscd-time-col');
102 applyCSS(timeCol, { background: o.timeBg, borderRight: '1px solid ' + o.borderColor, height: gridHeight + 'px' });
103
104 for (var h = o.startHour; h <= o.endHour; h++) {
105 if (o.showTime) {
106 var topPos = (h - o.startHour) * o.cellHeight;
107 var label = makeEl('div', 'bkbg-wscd-time-label');
108 label.textContent = fmt(h, 0, o.timeFormat);
109 label.style.top = topPos + 'px';
110 label.style.color = o.timeColor;
111 timeCol.appendChild(label);
112 }
113 }
114 bodyRow.appendChild(timeCol);
115
116 // Days area
117 var daysArea = makeEl('div', 'bkbg-wscd-days-area');
118 daysArea.style.height = gridHeight + 'px';
119
120 for (var day = 0; day < numDays; day++) {
121 var dayCol = makeEl('div', 'bkbg-wscd-day-col');
122 applyCSS(dayCol, {
123 background: o.bgColor,
124 borderRight: day < numDays - 1 ? '1px solid ' + o.borderColor : 'none',
125 height: gridHeight + 'px'
126 });
127
128 // Hour lines
129 for (var hl = 0; hl < totalHours; hl++) {
130 var line = makeEl('div', 'bkbg-wscd-hour-line');
131 line.style.top = (hl * o.cellHeight) + 'px';
132 line.style.borderTopColor = o.gridColor;
133 dayCol.appendChild(line);
134 }
135
136 // Events for this day
137 var dayEvents = (o.events || []).filter(function (ev) { return ev.day === day; });
138 dayEvents.forEach(function (ev) {
139 var startFrac = (ev.startHour || 0) + ((ev.startMinute || 0) / 60);
140 var top = (startFrac - o.startHour) * o.cellHeight;
141 var height = (ev.duration || 1) * o.cellHeight - 4;
142 if (top < 0 || top >= gridHeight) return;
143
144 var evEl = makeEl('div', 'bkbg-wscd-event');
145 applyCSS(evEl, {
146 top: top + 'px',
147 height: height + 'px',
148 background: ev.color || '#6366f1',
149 borderRadius: o.eventRadius + 'px'
150 });
151
152 var titleDiv = makeEl('div', 'bkbg-wscd-event-title');
153 titleDiv.textContent = ev.title || '';
154 evEl.appendChild(titleDiv);
155
156 if (o.showInstructor && ev.instructor) {
157 var instDiv = makeEl('div', 'bkbg-wscd-event-sub');
158 instDiv.textContent = ev.instructor;
159 evEl.appendChild(instDiv);
160 }
161 if (o.showLocation && ev.location) {
162 var locDiv = makeEl('div', 'bkbg-wscd-event-sub');
163 locDiv.textContent = '📍 ' + ev.location;
164 evEl.appendChild(locDiv);
165 }
166
167 dayCol.appendChild(evEl);
168 });
169
170 daysArea.appendChild(dayCol);
171 }
172
173 bodyRow.appendChild(daysArea);
174 grid.appendChild(bodyRow);
175 wrap.appendChild(grid);
176
177 appEl.parentNode.insertBefore(wrap, appEl);
178 appEl.style.display = 'none';
179 });
180 }
181
182 if (document.readyState !== 'loading') { init(); }
183 else { document.addEventListener('DOMContentLoaded', init); }
184 })();
185