@asd20/ui 3.2.986 → 3.2.988
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package-lock.json +26 -7
- package/package.json +2 -2
- package/src/components/atoms/Asd20FormattedDate/index.vue +1 -1
- package/src/components/molecules/Asd20Card/index.vue +4 -2
- package/src/components/molecules/Asd20EventListItem.vue +6 -7
- package/src/components/templates/Asd20DetailAlternateTemplate/index.vue +1 -31
- package/src/components/templates/Asd20DetailImageFullTemplate/index.vue +1 -32
- package/src/components/templates/Asd20DetailImageTemplate/index.vue +1 -31
- package/src/components/templates/Asd20DetailTemplate/index.vue +1 -25
- package/src/data/events/district-events.json +4 -4
- package/src/helpers/expandEvents.js +13 -26
- package/src/helpers/formatEventTime.js +26 -34
- package/src/helpers/mapEventToCard.js +22 -7
- package/src/helpers/mapEventsToDays.js +13 -27
- package/src/helpers/mapMessageToCard.js +33 -3
- package/src/mixins/pageTemplateMixin.js +61 -18
package/package-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asd20/ui",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.987",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -1285,7 +1285,6 @@
|
|
|
1285
1285
|
"version": "7.27.0",
|
|
1286
1286
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
|
1287
1287
|
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
|
1288
|
-
"dev": true,
|
|
1289
1288
|
"requires": {
|
|
1290
1289
|
"regenerator-runtime": "^0.14.0"
|
|
1291
1290
|
}
|
|
@@ -1423,6 +1422,12 @@
|
|
|
1423
1422
|
"restore-cursor": "^1.0.1"
|
|
1424
1423
|
}
|
|
1425
1424
|
},
|
|
1425
|
+
"date-fns": {
|
|
1426
|
+
"version": "1.30.1",
|
|
1427
|
+
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
|
|
1428
|
+
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
|
|
1429
|
+
"dev": true
|
|
1430
|
+
},
|
|
1426
1431
|
"figures": {
|
|
1427
1432
|
"version": "1.7.0",
|
|
1428
1433
|
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
|
|
@@ -11548,9 +11553,12 @@
|
|
|
11548
11553
|
}
|
|
11549
11554
|
},
|
|
11550
11555
|
"date-fns": {
|
|
11551
|
-
"version": "
|
|
11552
|
-
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-
|
|
11553
|
-
"integrity": "sha512-
|
|
11556
|
+
"version": "2.30.0",
|
|
11557
|
+
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
|
|
11558
|
+
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
|
|
11559
|
+
"requires": {
|
|
11560
|
+
"@babel/runtime": "^7.21.0"
|
|
11561
|
+
}
|
|
11554
11562
|
},
|
|
11555
11563
|
"dateformat": {
|
|
11556
11564
|
"version": "3.0.3",
|
|
@@ -21394,6 +21402,12 @@
|
|
|
21394
21402
|
"figures": "^2.0.0"
|
|
21395
21403
|
},
|
|
21396
21404
|
"dependencies": {
|
|
21405
|
+
"date-fns": {
|
|
21406
|
+
"version": "1.30.1",
|
|
21407
|
+
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
|
|
21408
|
+
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
|
|
21409
|
+
"dev": true
|
|
21410
|
+
},
|
|
21397
21411
|
"figures": {
|
|
21398
21412
|
"version": "2.0.0",
|
|
21399
21413
|
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
|
@@ -21833,6 +21847,12 @@
|
|
|
21833
21847
|
"restore-cursor": "^1.0.1"
|
|
21834
21848
|
}
|
|
21835
21849
|
},
|
|
21850
|
+
"date-fns": {
|
|
21851
|
+
"version": "1.30.1",
|
|
21852
|
+
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
|
|
21853
|
+
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
|
|
21854
|
+
"dev": true
|
|
21855
|
+
},
|
|
21836
21856
|
"figures": {
|
|
21837
21857
|
"version": "1.7.0",
|
|
21838
21858
|
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
|
|
@@ -27520,8 +27540,7 @@
|
|
|
27520
27540
|
"regenerator-runtime": {
|
|
27521
27541
|
"version": "0.14.1",
|
|
27522
27542
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
|
27523
|
-
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
|
|
27524
|
-
"dev": true
|
|
27543
|
+
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
|
|
27525
27544
|
},
|
|
27526
27545
|
"regenerator-transform": {
|
|
27527
27546
|
"version": "0.15.2",
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"*.scss",
|
|
6
6
|
"*.vue"
|
|
7
7
|
],
|
|
8
|
-
"version": "3.2.
|
|
8
|
+
"version": "3.2.988",
|
|
9
9
|
"private": false,
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"axios": "^0.19.2",
|
|
31
31
|
"basicscroll": "^3.0.2",
|
|
32
32
|
"countup.js": "^2.0.0",
|
|
33
|
-
"date-fns": "^
|
|
33
|
+
"date-fns": "^2.30.0",
|
|
34
34
|
"focus-trap": "^6.9.4",
|
|
35
35
|
"focus-trap-vue": "^1.1.1",
|
|
36
36
|
"js-cookie": "^2.2.1",
|
|
@@ -14,7 +14,7 @@ export default {
|
|
|
14
14
|
formattedDate() {
|
|
15
15
|
// let apStyle = ['Jan.', 'Feb.', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.']
|
|
16
16
|
// let shortMonths = /January|February|August|September|October|November|December /
|
|
17
|
-
let formatted = format(new Date(this.dateTime), ' MMMM
|
|
17
|
+
let formatted = format(new Date(this.dateTime), ' MMMM d, yyyy')
|
|
18
18
|
// for (let month of apStyle) {
|
|
19
19
|
// if (formatted.includes(month)) {
|
|
20
20
|
// formatted = month
|
|
@@ -343,8 +343,9 @@ export default {
|
|
|
343
343
|
font-family: var(--website-typography__font-family-headlines);
|
|
344
344
|
display: flex;
|
|
345
345
|
align-items: flex-start;
|
|
346
|
-
margin-top: space(0.
|
|
347
|
-
margin-bottom: space(0.
|
|
346
|
+
margin-top: space(0.25);
|
|
347
|
+
margin-bottom: space(0.25);
|
|
348
|
+
align-items: center;
|
|
348
349
|
.asd20-icon {
|
|
349
350
|
--line-color: var(--website-icon__line-color);
|
|
350
351
|
margin-left: -0.125em;
|
|
@@ -356,6 +357,7 @@ export default {
|
|
|
356
357
|
}
|
|
357
358
|
&__time + &__location {
|
|
358
359
|
margin-top: space(0);
|
|
360
|
+
margin-bottom: space(0.25);
|
|
359
361
|
}
|
|
360
362
|
// &__date {
|
|
361
363
|
// margin-right: space(0.5);
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
</template>
|
|
18
18
|
|
|
19
19
|
<script>
|
|
20
|
-
import parse from 'date-fns/parse'
|
|
21
20
|
import format from 'date-fns/format'
|
|
22
21
|
|
|
23
22
|
export default {
|
|
@@ -28,27 +27,27 @@ export default {
|
|
|
28
27
|
computed: {
|
|
29
28
|
startDay() {
|
|
30
29
|
if (!this.event) return ''
|
|
31
|
-
return format(
|
|
30
|
+
return format(new Date(this.event.start.dateTime), 'dd')
|
|
32
31
|
},
|
|
33
32
|
startMonthName() {
|
|
34
33
|
if (!this.event) return ''
|
|
35
|
-
return format(
|
|
34
|
+
return format(new Date(this.event.start.dateTime), 'MMM')
|
|
36
35
|
},
|
|
37
36
|
startDate() {
|
|
38
37
|
if (!this.event) return ''
|
|
39
|
-
return format(
|
|
38
|
+
return format(new Date(this.event.start.dateTime), 'EEEE MMM d, yyyy')
|
|
40
39
|
},
|
|
41
40
|
endDate() {
|
|
42
41
|
if (!this.event) return ''
|
|
43
|
-
return format(
|
|
42
|
+
return format(new Date(this.event.end.dateTime), 'EEEE MMM d, yyyy')
|
|
44
43
|
},
|
|
45
44
|
startTime() {
|
|
46
45
|
if (!this.event) return ''
|
|
47
|
-
return format(
|
|
46
|
+
return format(new Date(this.event.start.dateTime), 'h:mm aa')
|
|
48
47
|
},
|
|
49
48
|
endTime() {
|
|
50
49
|
if (!this.event) return ''
|
|
51
|
-
return format(
|
|
50
|
+
return format(new Date(this.event.end.dateTime), 'h:mm aa')
|
|
52
51
|
},
|
|
53
52
|
},
|
|
54
53
|
}
|
|
@@ -254,25 +254,8 @@ export default {
|
|
|
254
254
|
.asd20-notification-group--floating {
|
|
255
255
|
position: absolute;
|
|
256
256
|
top: space(2.0375);
|
|
257
|
-
// .bell {
|
|
258
|
-
// box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.125) !important;
|
|
259
|
-
// svg {
|
|
260
|
-
// fill: var(--color__accent) !important;
|
|
261
|
-
// }
|
|
262
|
-
// span {
|
|
263
|
-
// background: var(--color__accent) !important;
|
|
264
|
-
// top: inherit !important;
|
|
265
|
-
// right: inherit !important;
|
|
266
|
-
// width: 1.2rem !important;
|
|
267
|
-
// height: 1.2rem !important;
|
|
268
|
-
// font-size: 0.75rem !important;
|
|
269
|
-
// }
|
|
270
|
-
// }
|
|
271
257
|
}
|
|
272
258
|
|
|
273
|
-
// .notification-group--inline {
|
|
274
|
-
// margin-bottom: space(3);
|
|
275
|
-
// }
|
|
276
259
|
.asd20-feeds-section--top {
|
|
277
260
|
// margin-top: space(1);
|
|
278
261
|
.asd20-swiper-feed:first-child {
|
|
@@ -290,9 +273,6 @@ export default {
|
|
|
290
273
|
}
|
|
291
274
|
}
|
|
292
275
|
}
|
|
293
|
-
// .asd20-page-content h2 {
|
|
294
|
-
// font-size: 20.8px !important;
|
|
295
|
-
// }
|
|
296
276
|
}
|
|
297
277
|
|
|
298
278
|
@media (min-width: 1024px) {
|
|
@@ -303,13 +283,6 @@ export default {
|
|
|
303
283
|
.asd20-notification-group--floating {
|
|
304
284
|
position: absolute;
|
|
305
285
|
top: space(1);
|
|
306
|
-
// .bell {
|
|
307
|
-
// span {
|
|
308
|
-
// background: var(--color__accent);
|
|
309
|
-
// top: -0.6em !important;
|
|
310
|
-
// right: -0.6em !important;
|
|
311
|
-
// }
|
|
312
|
-
// }
|
|
313
286
|
}
|
|
314
287
|
.notification-group--inline {
|
|
315
288
|
flex-basis: 100%;
|
|
@@ -320,10 +293,6 @@ export default {
|
|
|
320
293
|
}
|
|
321
294
|
}
|
|
322
295
|
|
|
323
|
-
// .asd20-feeds-section--top {
|
|
324
|
-
// margin-top: space(0);
|
|
325
|
-
// }
|
|
326
|
-
|
|
327
296
|
.asd20-page-content {
|
|
328
297
|
// margin-top: space(1);
|
|
329
298
|
display: flex;
|
|
@@ -343,6 +312,7 @@ export default {
|
|
|
343
312
|
max-width: 50vw;
|
|
344
313
|
flex: 1 1 0;
|
|
345
314
|
min-width: 0;
|
|
315
|
+
flex-direction: column;
|
|
346
316
|
}
|
|
347
317
|
}
|
|
348
318
|
}
|
|
@@ -246,24 +246,7 @@ export default {
|
|
|
246
246
|
.asd20-notification-group--floating {
|
|
247
247
|
position: absolute;
|
|
248
248
|
top: space(2);
|
|
249
|
-
// .bell {
|
|
250
|
-
// box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.125) !important;
|
|
251
|
-
// svg {
|
|
252
|
-
// fill: var(--color__accent) !important;
|
|
253
|
-
// }
|
|
254
|
-
// span {
|
|
255
|
-
// background: var(--color__accent) !important;
|
|
256
|
-
// top: inherit !important;
|
|
257
|
-
// right: inherit !important;
|
|
258
|
-
// width: 1.2rem !important;
|
|
259
|
-
// height: 1.2rem !important;
|
|
260
|
-
// font-size: 0.75rem !important;
|
|
261
|
-
// }
|
|
262
|
-
// }
|
|
263
249
|
}
|
|
264
|
-
// .asd20-page-content h2 {
|
|
265
|
-
// font-size: 20.8px !important;
|
|
266
|
-
// }
|
|
267
250
|
}
|
|
268
251
|
|
|
269
252
|
@media (min-width: 768px) {
|
|
@@ -271,20 +254,6 @@ export default {
|
|
|
271
254
|
.asd20-notification-group--floating {
|
|
272
255
|
position: absolute;
|
|
273
256
|
top: space(0.5);
|
|
274
|
-
// .bell {
|
|
275
|
-
// box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.125) !important;
|
|
276
|
-
// svg {
|
|
277
|
-
// fill: var(--color__accent) !important;
|
|
278
|
-
// }
|
|
279
|
-
// span {
|
|
280
|
-
// background: var(--color__accent) !important;
|
|
281
|
-
// top: inherit !important;
|
|
282
|
-
// right: inherit !important;
|
|
283
|
-
// width: 1.2rem !important;
|
|
284
|
-
// height: 1.2rem !important;
|
|
285
|
-
// font-size: 0.75rem !important;
|
|
286
|
-
// }
|
|
287
|
-
// }
|
|
288
257
|
}
|
|
289
258
|
}
|
|
290
259
|
}
|
|
@@ -320,7 +289,7 @@ export default {
|
|
|
320
289
|
padding: space(2) !important;
|
|
321
290
|
flex: 1 1 0;
|
|
322
291
|
min-width: 0;
|
|
323
|
-
|
|
292
|
+
flex-direction: column;
|
|
324
293
|
}
|
|
325
294
|
}
|
|
326
295
|
}
|
|
@@ -239,24 +239,7 @@ export default {
|
|
|
239
239
|
.asd20-notification-group--floating {
|
|
240
240
|
position: absolute;
|
|
241
241
|
top: space(2);
|
|
242
|
-
// .bell {
|
|
243
|
-
// box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.125) !important;
|
|
244
|
-
// svg {
|
|
245
|
-
// fill: var(--color__accent) !important;
|
|
246
|
-
// }
|
|
247
|
-
// span {
|
|
248
|
-
// background: var(--color__accent) !important;
|
|
249
|
-
// top: inherit !important;
|
|
250
|
-
// right: inherit !important;
|
|
251
|
-
// width: 1.2rem !important;
|
|
252
|
-
// height: 1.2rem !important;
|
|
253
|
-
// font-size: 0.75rem !important;
|
|
254
|
-
// }
|
|
255
|
-
// }
|
|
256
242
|
}
|
|
257
|
-
// .asd20-page-content h2 {
|
|
258
|
-
// font-size: 20.8px !important;
|
|
259
|
-
// }
|
|
260
243
|
}
|
|
261
244
|
|
|
262
245
|
@media (min-width: 768px) {
|
|
@@ -264,20 +247,6 @@ export default {
|
|
|
264
247
|
.asd20-notification-group--floating {
|
|
265
248
|
position: absolute;
|
|
266
249
|
top: space(0.5);
|
|
267
|
-
// .bell {
|
|
268
|
-
// box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.125) !important;
|
|
269
|
-
// svg {
|
|
270
|
-
// fill: var(--color__accent) !important;
|
|
271
|
-
// }
|
|
272
|
-
// span {
|
|
273
|
-
// background: var(--color__accent) !important;
|
|
274
|
-
// top: inherit !important;
|
|
275
|
-
// right: inherit !important;
|
|
276
|
-
// width: 1.2rem !important;
|
|
277
|
-
// height: 1.2rem !important;
|
|
278
|
-
// font-size: 0.75rem !important;
|
|
279
|
-
// }
|
|
280
|
-
// }
|
|
281
250
|
}
|
|
282
251
|
}
|
|
283
252
|
}
|
|
@@ -316,6 +285,7 @@ export default {
|
|
|
316
285
|
max-width: 50vw;
|
|
317
286
|
flex: 1 1 0;
|
|
318
287
|
min-width: 0;
|
|
288
|
+
flex-direction: column;
|
|
319
289
|
}
|
|
320
290
|
}
|
|
321
291
|
|
|
@@ -242,24 +242,7 @@ export default {
|
|
|
242
242
|
.asd20-notification-group--floating {
|
|
243
243
|
position: absolute;
|
|
244
244
|
top: space(2.0375);
|
|
245
|
-
// .bell {
|
|
246
|
-
// box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.125) !important;
|
|
247
|
-
// svg {
|
|
248
|
-
// fill: var(--color__accent) !important;
|
|
249
|
-
// }
|
|
250
|
-
// span {
|
|
251
|
-
// background: var(--color__accent) !important;
|
|
252
|
-
// top: inherit !important;
|
|
253
|
-
// right: inherit !important;
|
|
254
|
-
// width: 1.2rem !important;
|
|
255
|
-
// height: 1.2rem !important;
|
|
256
|
-
// font-size: 0.75rem !important;
|
|
257
|
-
// }
|
|
258
|
-
// }
|
|
259
245
|
}
|
|
260
|
-
// .asd20-page-content h2 {
|
|
261
|
-
// font-size: 20.8px !important;
|
|
262
|
-
// }
|
|
263
246
|
}
|
|
264
247
|
|
|
265
248
|
@media (min-width: 1024px) {
|
|
@@ -270,13 +253,6 @@ export default {
|
|
|
270
253
|
.asd20-notification-group--floating {
|
|
271
254
|
position: absolute;
|
|
272
255
|
top: space(1);
|
|
273
|
-
// .bell {
|
|
274
|
-
// span {
|
|
275
|
-
// background: var(--color__accent);
|
|
276
|
-
// top: -0.6em !important;
|
|
277
|
-
// right: -0.6em !important;
|
|
278
|
-
// }
|
|
279
|
-
// }
|
|
280
256
|
}
|
|
281
257
|
.notification-group--inline {
|
|
282
258
|
margin: space(2) space(3) space(1) space(3);
|
|
@@ -304,7 +280,7 @@ export default {
|
|
|
304
280
|
flex: 1;
|
|
305
281
|
flex: 1 1 0;
|
|
306
282
|
min-width: 0;
|
|
307
|
-
|
|
283
|
+
flex-direction: column;
|
|
308
284
|
}
|
|
309
285
|
}
|
|
310
286
|
}
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"summary": "Winter Break - No School",
|
|
30
30
|
"description": "No School",
|
|
31
31
|
"location": "AAHS",
|
|
32
|
-
"start": "2025-12-
|
|
33
|
-
"end": "2026-
|
|
32
|
+
"start": "2025-12-20T07:00:00Z",
|
|
33
|
+
"end": "2026-12-25T07:00:00Z",
|
|
34
34
|
"dtstamp": "2024-12-19T07:00:00Z",
|
|
35
35
|
"class": "",
|
|
36
36
|
"priority": "",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"summary": "Register for Summer School",
|
|
57
57
|
"description": "Ok. We're actually registeriing for Summer School really, really, really early.",
|
|
58
58
|
"location": "EAC",
|
|
59
|
-
"start": "2025-12-
|
|
60
|
-
"end": "2025-12-
|
|
59
|
+
"start": "2025-12-24T16:01:00Z",
|
|
60
|
+
"end": "2025-12-24T16:01:00Z",
|
|
61
61
|
"dtstamp": "2024-12-23T17:00:00Z",
|
|
62
62
|
"class": "",
|
|
63
63
|
"priority": "",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import parse from 'date-fns/parse'
|
|
2
1
|
import format from 'date-fns/format'
|
|
3
|
-
import addDays from 'date-fns/
|
|
4
|
-
import isSameDay from 'date-fns/
|
|
2
|
+
import addDays from 'date-fns/addDays'
|
|
3
|
+
import isSameDay from 'date-fns/isSameDay'
|
|
5
4
|
|
|
6
5
|
export default function expandEvents(events, includePastEvents = false) {
|
|
7
6
|
return events
|
|
8
7
|
.reduce((acc, event) => {
|
|
9
|
-
|
|
10
|
-
const
|
|
8
|
+
// Use new Date() for ISO date strings
|
|
9
|
+
const start = new Date(event.start)
|
|
10
|
+
const end = event.end ? new Date(event.end) : start
|
|
11
11
|
|
|
12
12
|
const today = new Date()
|
|
13
13
|
today.setHours(0, 0, 0, 0)
|
|
@@ -16,7 +16,6 @@ export default function expandEvents(events, includePastEvents = false) {
|
|
|
16
16
|
const diffHours = diffTime / (1000 * 60 * 60)
|
|
17
17
|
let diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
|
|
18
18
|
|
|
19
|
-
// Safety net for zero-day events
|
|
20
19
|
if (diffDays === 0) diffDays = 1
|
|
21
20
|
|
|
22
21
|
const isAllDay = event.allDay || diffHours >= 23
|
|
@@ -28,22 +27,12 @@ export default function expandEvents(events, includePastEvents = false) {
|
|
|
28
27
|
const normalizedEnd = new Date(end)
|
|
29
28
|
normalizedEnd.setHours(0, 0, 0, 0)
|
|
30
29
|
|
|
31
|
-
// let isMultiDay
|
|
32
|
-
|
|
33
|
-
// if (isAllDay && diffDays === 1) {
|
|
34
|
-
// // All-day event lasting exactly one day → NOT multi-day
|
|
35
|
-
// isMultiDay = false
|
|
36
|
-
// } else {
|
|
37
|
-
// isMultiDay = !isSameDay(normalizedStart, normalizedEnd)
|
|
38
|
-
// }
|
|
39
|
-
|
|
40
30
|
const isMultiDay =
|
|
41
31
|
diffDays > 1 || !isSameDay(normalizedStart, normalizedEnd)
|
|
42
32
|
|
|
43
33
|
const expandedEvents = []
|
|
44
34
|
|
|
45
35
|
if (isMultiDay) {
|
|
46
|
-
// Multi-day event expansion
|
|
47
36
|
for (let d = 0; d < diffDays; d++) {
|
|
48
37
|
const currentDay = addDays(normalizedStart, d)
|
|
49
38
|
|
|
@@ -55,16 +44,15 @@ export default function expandEvents(events, includePastEvents = false) {
|
|
|
55
44
|
originalStart: start,
|
|
56
45
|
allDay: true,
|
|
57
46
|
multiDay: true,
|
|
58
|
-
weekday: format(currentDay, '
|
|
59
|
-
day: format(currentDay, '
|
|
60
|
-
number: format(currentDay, '
|
|
47
|
+
weekday: format(currentDay, 'EEEE'),
|
|
48
|
+
day: format(currentDay, 'dd'),
|
|
49
|
+
number: format(currentDay, 'd'),
|
|
61
50
|
month: format(currentDay, 'MMMM'),
|
|
62
|
-
year: format(currentDay, '
|
|
51
|
+
year: format(currentDay, 'yyyy'),
|
|
63
52
|
})
|
|
64
53
|
}
|
|
65
54
|
}
|
|
66
55
|
} else {
|
|
67
|
-
// Single-day event
|
|
68
56
|
if (includePastEvents || normalizedStart >= today) {
|
|
69
57
|
expandedEvents.push({
|
|
70
58
|
...event,
|
|
@@ -73,11 +61,11 @@ export default function expandEvents(events, includePastEvents = false) {
|
|
|
73
61
|
originalStart: null,
|
|
74
62
|
allDay: isAllDay,
|
|
75
63
|
multiDay: false,
|
|
76
|
-
weekday: format(normalizedStart, '
|
|
77
|
-
day: format(normalizedStart, '
|
|
78
|
-
number: format(normalizedStart, '
|
|
64
|
+
weekday: format(normalizedStart, 'EEEE'),
|
|
65
|
+
day: format(normalizedStart, 'dd'),
|
|
66
|
+
number: format(normalizedStart, 'd'),
|
|
79
67
|
month: format(normalizedStart, 'MMMM'),
|
|
80
|
-
year: format(normalizedStart, '
|
|
68
|
+
year: format(normalizedStart, 'yyyy'),
|
|
81
69
|
})
|
|
82
70
|
}
|
|
83
71
|
}
|
|
@@ -110,7 +98,6 @@ export default function expandEvents(events, includePastEvents = false) {
|
|
|
110
98
|
if (isAHighPriority && !isBHighPriority) return -1
|
|
111
99
|
if (!isAHighPriority && isBHighPriority) return 1
|
|
112
100
|
|
|
113
|
-
// Fall back to alphabetical order if both have same priority
|
|
114
101
|
return aSummary.localeCompare(bSummary)
|
|
115
102
|
})
|
|
116
103
|
}
|
|
@@ -1,47 +1,39 @@
|
|
|
1
1
|
import format from 'date-fns/format'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
function safeFormatDate(dateObj, fmt) {
|
|
4
|
+
if (!dateObj || isNaN(dateObj)) return ''
|
|
5
|
+
try {
|
|
6
|
+
return format(dateObj, fmt)
|
|
7
|
+
} catch {
|
|
8
|
+
return ''
|
|
9
|
+
}
|
|
10
|
+
}
|
|
3
11
|
|
|
4
12
|
export default function formattedTime(event) {
|
|
5
|
-
if (!event) return
|
|
13
|
+
if (!event) return ''
|
|
6
14
|
|
|
7
15
|
if (event.allDay) return 'All Day'
|
|
8
16
|
|
|
9
17
|
if (event.multiDay) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.replace(/:00/g, '')}`
|
|
18
|
+
const startStr = safeFormatDate(event.originalStart, 'h:mm aa, EEE, MMM dd, yyyy')
|
|
19
|
+
const endStr = safeFormatDate(event.end, 'h:mm aa, EEE, MM dd, yyyy')
|
|
20
|
+
if (startStr && endStr) {
|
|
21
|
+
return `<b>MultiDay Event:</b><br/>Starts: ${startStr}<br>Ends: ${endStr}`
|
|
22
|
+
} else if (startStr) {
|
|
23
|
+
return `<b>MultiDay Event:</b><br/>Starts: ${startStr}`
|
|
24
|
+
} else if (endStr) {
|
|
25
|
+
return `<b>MultiDay Event:</b><br/>Ends: ${endStr}`
|
|
26
|
+
}
|
|
27
|
+
return 'MultiDay Event'
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
// const startHour = startTime.getHours()
|
|
26
|
-
|
|
27
|
-
// if (
|
|
28
|
-
// startTime.getTime() === endTime.getTime() &&
|
|
29
|
-
// (startHour >= 23 || startHour < 3)
|
|
30
|
-
// ) {
|
|
31
|
-
// return 'TBD'
|
|
32
|
-
// }
|
|
33
|
-
|
|
34
|
-
let time = `${format(startTime, '<b>h:mm aa</b>').replace(/:00/g, '')}`
|
|
30
|
+
const start = safeFormatDate(event.start, 'h:mm aa')
|
|
31
|
+
const end = safeFormatDate(event.end, 'h:mm aa')
|
|
35
32
|
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
} else if (event.endTimeUndetermined) {
|
|
39
|
-
time += `${format(endTime).replace(/:00/g, '')}`
|
|
40
|
-
} else {
|
|
41
|
-
time += ` - ${format(endTime, '<b>h:mm aa</b>')
|
|
42
|
-
.replace(/#/g, ' ')
|
|
43
|
-
.replace(/:00/g, '')}`
|
|
33
|
+
if (start && end && event.start.getTime() !== event.end.getTime()) {
|
|
34
|
+
return `${start} - ${end}`
|
|
44
35
|
}
|
|
36
|
+
if (start) return start
|
|
45
37
|
|
|
46
|
-
return
|
|
38
|
+
return ''
|
|
47
39
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import format from 'date-fns/format'
|
|
2
|
-
import
|
|
2
|
+
import parseISO from 'date-fns/parseISO'
|
|
3
3
|
import formattedTime from './formatEventTime'
|
|
4
4
|
|
|
5
5
|
// Function to sanitize the summary
|
|
6
6
|
const sanitizeSummary = summary => {
|
|
7
7
|
if (!summary) return summary
|
|
8
|
-
|
|
9
8
|
const pattern = /vs\.[^>]*>Multiple Schools/
|
|
10
9
|
return summary.replace(pattern, 'vs. Multiple Schools')
|
|
11
10
|
}
|
|
@@ -16,15 +15,12 @@ const sanitizeDescription = description => {
|
|
|
16
15
|
|
|
17
16
|
// Check if the description contains ">Multiple Schools"
|
|
18
17
|
if (description.includes('>Multiple Schools')) {
|
|
19
|
-
// Remove text between the ">" backwards to the first "." or ":" and replace '>Multiple Schools' with '.'
|
|
20
18
|
description = description.replace(
|
|
21
19
|
/([.:][^>]*?)>([^>]*Multiple Schools)/,
|
|
22
20
|
'$1.'
|
|
23
21
|
)
|
|
24
|
-
|
|
25
22
|
// Separate capital letters preceded by lowercase letters with ', '
|
|
26
23
|
description = description.replace(/([a-z])([A-Z])/g, '$1, $2')
|
|
27
|
-
|
|
28
24
|
// Remove unmatched quotes between "." or ":" and ">"
|
|
29
25
|
const quotePattern = /[.:][^>]*['"][^'"]*$|[^'"]*['"][^>]*['"]>Multiple Schools/g
|
|
30
26
|
description = description.replace(quotePattern, match => {
|
|
@@ -32,7 +28,6 @@ const sanitizeDescription = description => {
|
|
|
32
28
|
return quotes.length % 2 !== 0 ? match.replace(/['"]/g, '') : match
|
|
33
29
|
})
|
|
34
30
|
}
|
|
35
|
-
|
|
36
31
|
return description
|
|
37
32
|
}
|
|
38
33
|
|
|
@@ -40,11 +35,31 @@ export default function mapEventToCard(event) {
|
|
|
40
35
|
const sanitizedSummary = sanitizeSummary(event.summary)
|
|
41
36
|
const sanitizedDescription = sanitizeDescription(event.description)
|
|
42
37
|
|
|
38
|
+
let dateObj = null
|
|
39
|
+
if (event.start) {
|
|
40
|
+
try {
|
|
41
|
+
dateObj = parseISO(event.start)
|
|
42
|
+
if (isNaN(dateObj)) {
|
|
43
|
+
// fallback
|
|
44
|
+
const { parse } = require('date-fns')
|
|
45
|
+
dateObj = parse(event.start, "yyyy-MM-dd'T'HH:mm:ssX", new Date())
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
dateObj = null
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Always calculate these fields, not just rely on input
|
|
53
|
+
// const weekday = dateObj && !isNaN(dateObj) ? format(dateObj, 'EEEE') : ''
|
|
54
|
+
// const day = dateObj && !isNaN(dateObj) ? format(dateObj, 'dd') : ''
|
|
55
|
+
// const month = dateObj && !isNaN(dateObj) ? format(dateObj, 'MMMM') : ''
|
|
56
|
+
// const year = dateObj && !isNaN(dateObj) ? format(dateObj, 'yyyy') : ''
|
|
57
|
+
|
|
43
58
|
return {
|
|
44
59
|
title: sanitizedSummary,
|
|
45
60
|
description: sanitizedDescription,
|
|
46
61
|
categories: event.calendarCategories.concat([event.calendarName]),
|
|
47
|
-
date: format(
|
|
62
|
+
date: dateObj && !isNaN(dateObj) ? format(dateObj, 'MMMM d, yyyy') : '',
|
|
48
63
|
time: formattedTime(event),
|
|
49
64
|
weekday: event.weekday,
|
|
50
65
|
day: event.day,
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
import parse from 'date-fns/parse'
|
|
2
1
|
import format from 'date-fns/format'
|
|
3
|
-
import addDays from 'date-fns/
|
|
4
|
-
import isSameDay from 'date-fns/
|
|
5
|
-
import getDaysInMonth from 'date-fns/
|
|
2
|
+
import addDays from 'date-fns/addDays'
|
|
3
|
+
import isSameDay from 'date-fns/isSameDay'
|
|
4
|
+
import getDaysInMonth from 'date-fns/getDaysInMonth'
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Given an array of events, returns an array of days with events grouped by date.
|
|
9
|
-
*
|
|
10
|
-
* @export
|
|
11
|
-
* @param {Array} events - Array of events (should already be expanded if needed)
|
|
12
|
-
* @param {number} year - Target year (used when showAll is false)
|
|
13
|
-
* @param {number} month - Target month (zero-indexed, used when showAll is false)
|
|
14
|
-
* @param {boolean} showAll - If true, returns only days with events (useful for agenda views)
|
|
15
|
-
* @returns {Array} Array of day objects { date, events, ... }
|
|
16
8
|
*/
|
|
17
9
|
export default function mapEventsToDays(
|
|
18
10
|
events,
|
|
@@ -30,8 +22,8 @@ export default function mapEventsToDays(
|
|
|
30
22
|
const uniqueDatesMap = new Map()
|
|
31
23
|
|
|
32
24
|
events.forEach(event => {
|
|
33
|
-
const eventDate =
|
|
34
|
-
const dateKey = format(eventDate, '
|
|
25
|
+
const eventDate = new Date(event.start)
|
|
26
|
+
const dateKey = format(eventDate, 'yyyy-MM-dd')
|
|
35
27
|
if (!uniqueDatesMap.has(dateKey)) {
|
|
36
28
|
uniqueDatesMap.set(dateKey, eventDate)
|
|
37
29
|
}
|
|
@@ -44,8 +36,8 @@ export default function mapEventsToDays(
|
|
|
44
36
|
const lastDayOfMonth = new Date(year, month + 1, 0)
|
|
45
37
|
const daysInMonth = getDaysInMonth(firstDayOfMonth)
|
|
46
38
|
|
|
47
|
-
const prevMonthDays = firstDayOfMonth.getDay()
|
|
48
|
-
const nextMonthDays = 6 - lastDayOfMonth.getDay()
|
|
39
|
+
const prevMonthDays = firstDayOfMonth.getDay()
|
|
40
|
+
const nextMonthDays = 6 - lastDayOfMonth.getDay()
|
|
49
41
|
const totalDays = daysInMonth + prevMonthDays + nextMonthDays
|
|
50
42
|
|
|
51
43
|
for (let i = -prevMonthDays; i < totalDays - prevMonthDays; i++) {
|
|
@@ -61,12 +53,6 @@ export default function mapEventsToDays(
|
|
|
61
53
|
|
|
62
54
|
/**
|
|
63
55
|
* Builds a day object with events attached.
|
|
64
|
-
*
|
|
65
|
-
* @param {Date} date - The date this day represents.
|
|
66
|
-
* @param {Array} events - The full events list.
|
|
67
|
-
* @param {boolean} outsideOfCurrentMonth - Whether this date is outside the target month.
|
|
68
|
-
* @param {Date} today - Today's date (normalized to 00:00).
|
|
69
|
-
* @returns {Object} The day object.
|
|
70
56
|
*/
|
|
71
57
|
function createDayObject(date, events, outsideOfCurrentMonth = false, today) {
|
|
72
58
|
const normalizedDate = new Date(date)
|
|
@@ -77,12 +63,12 @@ function createDayObject(date, events, outsideOfCurrentMonth = false, today) {
|
|
|
77
63
|
date: normalizedDate,
|
|
78
64
|
unix: normalizedDate.getTime(),
|
|
79
65
|
today: isSameDay(normalizedDate, today),
|
|
80
|
-
events: events.filter(event => isSameDay(
|
|
81
|
-
weekday: format(normalizedDate, '
|
|
82
|
-
day: format(normalizedDate, '
|
|
83
|
-
shortDay: format(normalizedDate, '
|
|
84
|
-
number: format(normalizedDate, '
|
|
66
|
+
events: events.filter(event => isSameDay(new Date(event.start), normalizedDate)),
|
|
67
|
+
weekday: format(normalizedDate, 'EEEE'),
|
|
68
|
+
day: format(normalizedDate, 'dd'),
|
|
69
|
+
shortDay: format(normalizedDate, 'd'),
|
|
70
|
+
number: format(normalizedDate, 'd'),
|
|
85
71
|
month: format(normalizedDate, 'MMMM'),
|
|
86
|
-
year: format(normalizedDate, '
|
|
72
|
+
year: format(normalizedDate, 'yyyy'),
|
|
87
73
|
}
|
|
88
74
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import format from 'date-fns/format'
|
|
2
|
+
import parseISO from 'date-fns/parseISO'
|
|
2
3
|
|
|
3
4
|
export default function mapMessageToCard(
|
|
4
5
|
message,
|
|
@@ -48,14 +49,43 @@ export default function mapMessageToCard(
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
// Safely format dates (handle missing/null)
|
|
53
|
+
let date = ''
|
|
54
|
+
let modifiedDate = ''
|
|
55
|
+
let time = ''
|
|
56
|
+
|
|
57
|
+
if (message.publishDateTime) {
|
|
58
|
+
try {
|
|
59
|
+
const parsed = parseISO(message.publishDateTime)
|
|
60
|
+
if (!isNaN(parsed)) {
|
|
61
|
+
date = format(parsed, 'MMM. d, yyyy')
|
|
62
|
+
time = format(parsed, 'h:mm aa')
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
date = ''
|
|
66
|
+
time = ''
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (message.modifiedDateTime) {
|
|
71
|
+
try {
|
|
72
|
+
const parsed = parseISO(message.modifiedDateTime)
|
|
73
|
+
if (!isNaN(parsed)) {
|
|
74
|
+
modifiedDate = format(parsed, 'MMM. d, yyyy')
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
modifiedDate = ''
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
51
81
|
return Object.assign(
|
|
52
82
|
{
|
|
53
83
|
title: message.title,
|
|
54
84
|
description: message.description || message.summary,
|
|
55
85
|
categories: message.categories,
|
|
56
|
-
date
|
|
57
|
-
modifiedDate
|
|
58
|
-
time
|
|
86
|
+
date,
|
|
87
|
+
modifiedDate,
|
|
88
|
+
time,
|
|
59
89
|
pinned: message.isFeatured || message.isDistrictFeatured,
|
|
60
90
|
image: bannerImageOrDefault ? bannerImageOrDefault.url : '',
|
|
61
91
|
alt: bannerImageOrDefault ? coverImageAlt : '',
|
|
@@ -134,25 +134,66 @@ export default {
|
|
|
134
134
|
}
|
|
135
135
|
},
|
|
136
136
|
|
|
137
|
-
primaryDetailMessages() {
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
// primaryDetailMessages() {
|
|
138
|
+
// // If there are more than 2 or more messages on a detail page
|
|
139
|
+
// // -- Detail Pages
|
|
140
|
+
|
|
141
|
+
// let originalMessages = JSON.parse(JSON.stringify(this.messages))
|
|
142
|
+
|
|
143
|
+
// let firstMessage = originalMessages[0]
|
|
144
|
+
// delete firstMessage.title
|
|
145
|
+
// delete firstMessage.heading
|
|
146
|
+
// delete firstMessage.summary
|
|
147
|
+
// delete firstMessage.shortDescription
|
|
148
|
+
|
|
149
|
+
// let messagesArray = originalMessages.slice(1)
|
|
150
|
+
// messagesArray.unshift(firstMessage)
|
|
151
|
+
// messagesArray.slice(
|
|
152
|
+
// 1,
|
|
153
|
+
// Math.min(originalMessages.length, this.primaryMessageLimit + 1)
|
|
154
|
+
// )
|
|
155
|
+
// return messagesArray
|
|
156
|
+
// },
|
|
140
157
|
|
|
141
|
-
|
|
158
|
+
primaryDetailMessages() {
|
|
159
|
+
const originalMessages = JSON.parse(JSON.stringify(this.messages))
|
|
160
|
+
|
|
161
|
+
return originalMessages.map((message, index) => {
|
|
162
|
+
// Clone the message
|
|
163
|
+
const newMessage = { ...message }
|
|
164
|
+
|
|
165
|
+
if (index === 0) {
|
|
166
|
+
// Strip fields already used in pageHeader
|
|
167
|
+
delete newMessage.title
|
|
168
|
+
delete newMessage.heading
|
|
169
|
+
delete newMessage.summary
|
|
170
|
+
delete newMessage.shortDescription
|
|
171
|
+
return newMessage
|
|
172
|
+
}
|
|
142
173
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
174
|
+
// Construct title + summary markup if available
|
|
175
|
+
const titleMarkup = newMessage.title
|
|
176
|
+
? `<h2>${newMessage.title}</h2>`
|
|
177
|
+
: ''
|
|
178
|
+
|
|
179
|
+
const summaryMarkup = newMessage.shortDescription
|
|
180
|
+
? `<p>${newMessage.shortDescription}</p>`
|
|
181
|
+
: ''
|
|
182
|
+
|
|
183
|
+
// Merge into bodyContent (inserted before existing body)
|
|
184
|
+
const originalBody = newMessage.bodyContent || ''
|
|
185
|
+
newMessage.bodyContent = `${titleMarkup}${summaryMarkup}${originalBody}`
|
|
186
|
+
|
|
187
|
+
// Remove title/summary fields to prevent accidental rendering
|
|
188
|
+
delete newMessage.title
|
|
189
|
+
delete newMessage.heading
|
|
190
|
+
delete newMessage.summary
|
|
191
|
+
delete newMessage.shortDescription
|
|
192
|
+
delete newMessage.detailLink
|
|
193
|
+
delete newMessage.detailLinkLabel
|
|
194
|
+
|
|
195
|
+
return newMessage
|
|
196
|
+
})
|
|
156
197
|
},
|
|
157
198
|
|
|
158
199
|
secondaryMessages() {
|
|
@@ -215,7 +256,9 @@ export default {
|
|
|
215
256
|
coverImageFull.filename.includes('headerimage')
|
|
216
257
|
) {
|
|
217
258
|
imageUrl = null
|
|
218
|
-
headerImageUrl = coverImageFull
|
|
259
|
+
headerImageUrl = coverImageFull
|
|
260
|
+
? coverImageFull.url
|
|
261
|
+
: coverImage.url || ''
|
|
219
262
|
} else {
|
|
220
263
|
imageUrl = coverImageFull ? coverImageFull.url : coverImage.url || ''
|
|
221
264
|
imageCaption = coverImage.metadata
|