@asd20/ui 3.2.989 → 3.2.991

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asd20/ui",
3
- "version": "3.2.988",
3
+ "version": "3.2.990",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -11665,6 +11665,11 @@
11665
11665
  "@babel/runtime": "^7.21.0"
11666
11666
  }
11667
11667
  },
11668
+ "date-fns-tz": {
11669
+ "version": "1.1.7",
11670
+ "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.1.7.tgz",
11671
+ "integrity": "sha512-xfL918kXO528DJ17Sao60H07rYv5L/X0Bp6zojDssuZAR/acYETDS9PaICKAnodcO9XVHL/0bpLRGKd7kNnvcQ=="
11672
+ },
11668
11673
  "dateformat": {
11669
11674
  "version": "3.0.3",
11670
11675
  "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
@@ -33509,8 +33514,7 @@
33509
33514
  "vue": {
33510
33515
  "version": "2.6.14",
33511
33516
  "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",
33512
- "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==",
33513
- "dev": true
33517
+ "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ=="
33514
33518
  },
33515
33519
  "vue-class-component": {
33516
33520
  "version": "7.2.6",
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "*.scss",
6
6
  "*.vue"
7
7
  ],
8
- "version": "3.2.989",
8
+ "version": "3.2.991",
9
9
  "private": false,
10
10
  "license": "MIT",
11
11
  "repository": {
@@ -31,6 +31,7 @@
31
31
  "basicscroll": "^3.0.2",
32
32
  "countup.js": "^2.0.0",
33
33
  "date-fns": "^2.30.0",
34
+ "date-fns-tz": "^1.1.7",
34
35
  "focus-trap": "^6.9.4",
35
36
  "focus-trap-vue": "^1.1.1",
36
37
  "js-cookie": "^2.2.1",
@@ -38,6 +39,7 @@
38
39
  "swiper": "^5.4.5",
39
40
  "uuid": "^3.3.2",
40
41
  "v-scroll-lock": "^1.3.1",
42
+ "vue": "^2.6.14",
41
43
  "vue-intersect": "^1.1.6",
42
44
  "vue-lazyload": "^1.2.6",
43
45
  "vue-mq": "^1.0.1",
@@ -90,7 +92,6 @@
90
92
  "stylelint-config-prettier": "^5.0.0",
91
93
  "stylelint-config-standard": "^18.2.0",
92
94
  "stylelint-scss": "^3.5.4",
93
- "vue": "2.6.14",
94
95
  "vue-class-component": "^7.0.2",
95
96
  "vue-docgen-api": "^3.26.0",
96
97
  "vue-loader": "^15.8.3",
@@ -52,25 +52,19 @@ export default {
52
52
  }
53
53
  },
54
54
  startTime() {
55
- return format(
56
- parse(this.event.start, "yyyy-MM-dd'T'HH:mm:ssX", new Date()),
57
- 'h:mm aa'
58
- )
55
+ const d = this.toDateSafe(this.event.start)
56
+ if (!d) return ''
57
+ return format(d, 'h:mm aa')
59
58
  },
60
59
  start() {
61
- return format(
62
- parse(this.event.start, "yyyy-MM-dd'T'HH:mm:ssX", new Date()),
63
- 'h:mm aa, MMMM dd yyyy'
64
- )
60
+ const d = this.toDateSafe(this.event.start)
61
+ if (!d) return ''
62
+ return format(d, 'h:mm aa, MMMM dd yyyy')
65
63
  },
66
64
  end() {
67
- return (
68
- ' to ' +
69
- format(
70
- parse(this.event.end, "yyyy-MM-dd'T'HH:mm:ssX", new Date()),
71
- 'h:mm aa, MMMM dd yyyy'
72
- )
73
- )
65
+ const d = this.toDateSafe(this.event.end)
66
+ if (!d) return ''
67
+ return ' to ' + format(d, 'h:mm aa, MMMM dd yyyy')
74
68
  },
75
69
  sanitizedSummary() {
76
70
  return this.sanitizeSummary(this.event.summary)
@@ -104,8 +98,15 @@ export default {
104
98
  return summary.replace(pattern, 'vs. Multiple Schools')
105
99
  },
106
100
  formatDate(date, opts = { month: 'short', day: 'numeric' }) {
107
- if (!date) return ''
108
- return new Date(date).toLocaleDateString(undefined, opts)
101
+ const d = this.toDateSafe(date)
102
+ if (!d) return ''
103
+ return d.toLocaleDateString(undefined, opts)
104
+ },
105
+ toDateSafe(value) {
106
+ if (!value) return null;
107
+ if (value instanceof Date) return isNaN(value) ? null : value;
108
+ const d = new Date(value);
109
+ return isNaN(d) ? null : d;
109
110
  },
110
111
  },
111
112
  }
@@ -3,7 +3,8 @@
3
3
  </template>
4
4
 
5
5
  <script>
6
- import format from 'date-fns/format'
6
+ import { format } from 'date-fns'
7
+
7
8
  export default {
8
9
  name: 'Asd20FormattedDate',
9
10
  props: {
@@ -14,7 +15,7 @@ export default {
14
15
  formattedDate() {
15
16
  // let apStyle = ['Jan.', 'Feb.', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.']
16
17
  // let shortMonths = /January|February|August|September|October|November|December /
17
- let formatted = format(new Date(this.dateTime), ' MMMM d, yyyy')
18
+ let formatted = format(new Date(this.dateTime), ' MMMM d, YYYY')
18
19
  // for (let month of apStyle) {
19
20
  // if (formatted.includes(month)) {
20
21
  // formatted = month
@@ -17,7 +17,7 @@
17
17
  </template>
18
18
 
19
19
  <script>
20
- import format from 'date-fns/format'
20
+ import { format } from 'date-fns'
21
21
 
22
22
  export default {
23
23
  name: '',
@@ -11,7 +11,11 @@
11
11
  :key="day.unix"
12
12
  :label="`${day.weekday}, ${day.month} ${day.shortDay}, ${day.year}`"
13
13
  />
14
- <asd20-list-item v-for="event in day.events" :key="event.uid" condensed>
14
+ <asd20-list-item
15
+ v-for="event in day.events"
16
+ :key="`${event.uid}-${new Date(event.start).getTime()}`"
17
+ condensed
18
+ >
15
19
  <asd20-calendar-event-button
16
20
  :event="event"
17
21
  large
@@ -1,41 +1,48 @@
1
- import format from 'date-fns/format'
2
- import addDays from 'date-fns/addDays'
3
- import isSameDay from 'date-fns/isSameDay'
1
+ import { format, addDays, isSameDay } from 'date-fns'
2
+ import { utcToZonedTime } from 'date-fns-tz'
3
+
4
+ const MOUNTAIN_TZ = 'America/Denver'
5
+
6
+ // Convert to Mountain Time
7
+ function toMountain(dateLike) {
8
+ // Accepts string/Date; handles undefined/null gracefully
9
+ if (!dateLike) return null
10
+ return utcToZonedTime(new Date(dateLike), MOUNTAIN_TZ)
11
+ }
4
12
 
5
13
  export default function expandEvents(events, includePastEvents = false) {
14
+ // Today in Mountain Time, at midnight
15
+ const now = new Date()
16
+ const today = toMountain(now)
17
+ today.setHours(0, 0, 0, 0)
18
+
6
19
  return events
7
20
  .reduce((acc, event) => {
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
-
12
- const today = new Date()
13
- today.setHours(0, 0, 0, 0)
21
+ // Always parse and convert to Mountain Time
22
+ const start = toMountain(event.start)
23
+ const end = event.end ? toMountain(event.end) : start
14
24
 
25
+ // Do all date math in Mountain Time
15
26
  const diffTime = end.getTime() - start.getTime()
16
27
  const diffHours = diffTime / (1000 * 60 * 60)
17
28
  let diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
18
-
19
29
  if (diffDays === 0) diffDays = 1
20
30
 
21
31
  const isAllDay = event.allDay || diffHours >= 23
22
32
 
23
- // Normalize for date-only comparisons
33
+ // Normalize for date-only comparisons (still in Mountain)
24
34
  const normalizedStart = new Date(start)
25
35
  normalizedStart.setHours(0, 0, 0, 0)
26
-
27
36
  const normalizedEnd = new Date(end)
28
37
  normalizedEnd.setHours(0, 0, 0, 0)
29
38
 
30
- const isMultiDay =
31
- diffDays > 1 || !isSameDay(normalizedStart, normalizedEnd)
39
+ const isMultiDay = diffDays > 1 || !isSameDay(normalizedStart, normalizedEnd)
32
40
 
33
41
  const expandedEvents = []
34
42
 
35
43
  if (isMultiDay) {
36
44
  for (let d = 0; d < diffDays; d++) {
37
45
  const currentDay = addDays(normalizedStart, d)
38
-
39
46
  if (includePastEvents || currentDay >= today) {
40
47
  expandedEvents.push({
41
48
  ...event,
@@ -56,7 +63,7 @@ export default function expandEvents(events, includePastEvents = false) {
56
63
  if (includePastEvents || normalizedStart >= today) {
57
64
  expandedEvents.push({
58
65
  ...event,
59
- start: start, // keep original start WITH time
66
+ start: start, // Mountain Time, with time for timed events
60
67
  end: end,
61
68
  originalStart: null,
62
69
  allDay: isAllDay,
@@ -1,4 +1,4 @@
1
- import format from 'date-fns/format'
1
+ import { format } from 'date-fns'
2
2
 
3
3
  function safeFormatDate(dateObj, fmt) {
4
4
  if (!dateObj || isNaN(dateObj)) return ''
@@ -1,5 +1,4 @@
1
- import format from 'date-fns/format'
2
- import parseISO from 'date-fns/parseISO'
1
+ import { format, parseISO } from 'date-fns'
3
2
  import formattedTime from './formatEventTime'
4
3
 
5
4
  // Function to sanitize the summary
@@ -1,10 +1,27 @@
1
- import format from 'date-fns/format'
2
- import addDays from 'date-fns/addDays'
3
- import isSameDay from 'date-fns/isSameDay'
4
- import getDaysInMonth from 'date-fns/getDaysInMonth'
1
+ import { format, addDays, getDaysInMonth } from 'date-fns'
2
+ import { utcToZonedTime } from 'date-fns-tz'
3
+
4
+ const MOUNTAIN_TZ = 'America/Denver'
5
+
6
+ // Converts any date-like input to a Mountain Time Date object.
7
+ function toMountain(dateLike) {
8
+ if (!dateLike) return null
9
+ return utcToZonedTime(new Date(dateLike), MOUNTAIN_TZ)
10
+ }
11
+
12
+ // Checks if two dates are the same day in Mountain Time.
13
+ function isSameDayMT(dateLeft, dateRight) {
14
+ const d1 = toMountain(dateLeft)
15
+ const d2 = toMountain(dateRight)
16
+ return (
17
+ d1.getFullYear() === d2.getFullYear() &&
18
+ d1.getMonth() === d2.getMonth() &&
19
+ d1.getDate() === d2.getDate()
20
+ )
21
+ }
5
22
 
6
23
  /**
7
- * Given an array of events, returns an array of days with events grouped by date.
24
+ * Given an array of events, returns an array of days with events grouped by date (in Mountain Time).
8
25
  */
9
26
  export default function mapEventsToDays(
10
27
  events,
@@ -12,28 +29,30 @@ export default function mapEventsToDays(
12
29
  month = 0,
13
30
  showAll = false
14
31
  ) {
15
- const today = new Date()
32
+ const today = toMountain(new Date())
16
33
  today.setHours(0, 0, 0, 0)
17
34
 
18
35
  let days = []
19
36
 
20
37
  if (showAll) {
21
- // Collect unique event dates
38
+ // Collect unique event dates (in Mountain Time)
22
39
  const uniqueDatesMap = new Map()
23
40
 
24
41
  events.forEach(event => {
25
- const eventDate = new Date(event.start)
26
- const dateKey = format(eventDate, 'yyyy-MM-dd')
42
+ const eventDate = toMountain(event.start)
43
+ const dateKey = format(eventDate, 'yyyy-MM-dd', { timeZone: MOUNTAIN_TZ })
27
44
  if (!uniqueDatesMap.has(dateKey)) {
28
45
  uniqueDatesMap.set(dateKey, eventDate)
29
46
  }
30
47
  })
31
48
 
32
- days = Array.from(uniqueDatesMap.values()).map(date => createDayObject(date, events, false, today))
49
+ days = Array.from(uniqueDatesMap.values()).map(date =>
50
+ createDayObject(date, events, false, today)
51
+ )
33
52
  } else {
34
- // Month view: create a full calendar grid
35
- const firstDayOfMonth = new Date(year, month, 1)
36
- const lastDayOfMonth = new Date(year, month + 1, 0)
53
+ // Month view: create a full calendar grid in Mountain Time
54
+ const firstDayOfMonth = toMountain(new Date(year, month, 1))
55
+ const lastDayOfMonth = toMountain(new Date(year, month + 1, 0))
37
56
  const daysInMonth = getDaysInMonth(firstDayOfMonth)
38
57
 
39
58
  const prevMonthDays = firstDayOfMonth.getDay()
@@ -47,28 +66,30 @@ export default function mapEventsToDays(
47
66
  }
48
67
  }
49
68
 
50
- // Sort by unix timestamp (probably unnecessary unless something weird happens)
69
+ // Sort by unix timestamp
51
70
  return days.sort((a, b) => a.unix - b.unix)
52
71
  }
53
72
 
54
73
  /**
55
- * Builds a day object with events attached.
74
+ * Builds a day object (in Mountain Time) with events attached.
56
75
  */
57
76
  function createDayObject(date, events, outsideOfCurrentMonth = false, today) {
58
- const normalizedDate = new Date(date)
77
+ const normalizedDate = toMountain(date)
59
78
  normalizedDate.setHours(0, 0, 0, 0)
60
79
 
61
80
  return {
62
81
  outsideOfCurrentMonth,
63
82
  date: normalizedDate,
64
83
  unix: normalizedDate.getTime(),
65
- today: isSameDay(normalizedDate, today),
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'),
71
- month: format(normalizedDate, 'MMMM'),
72
- year: format(normalizedDate, 'yyyy'),
84
+ today: isSameDayMT(normalizedDate, today),
85
+ events: events.filter(event =>
86
+ isSameDayMT(event.start, normalizedDate)
87
+ ),
88
+ weekday: format(normalizedDate, 'EEEE', { timeZone: MOUNTAIN_TZ }),
89
+ day: format(normalizedDate, 'dd', { timeZone: MOUNTAIN_TZ }),
90
+ shortDay: format(normalizedDate, 'd', { timeZone: MOUNTAIN_TZ }),
91
+ number: format(normalizedDate, 'd', { timeZone: MOUNTAIN_TZ }),
92
+ month: format(normalizedDate, 'MMMM', { timeZone: MOUNTAIN_TZ }),
93
+ year: format(normalizedDate, 'yyyy', { timeZone: MOUNTAIN_TZ }),
73
94
  }
74
95
  }
@@ -1,5 +1,4 @@
1
- import format from 'date-fns/format'
2
- import parseISO from 'date-fns/parseISO'
1
+ import { format, parseISO } from 'date-fns'
3
2
 
4
3
  export default function mapMessageToCard(
5
4
  message,