@ieeesa-npm/dashboard 0.0.0-stage → 0.0.1

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.
Files changed (63) hide show
  1. package/README.md +75 -3
  2. package/esm2022/ieeesa-npm-dashboard.mjs +5 -0
  3. package/esm2022/lib/assets/constants.json +141 -0
  4. package/esm2022/lib/assets/dashboard-mock.mjs +217 -0
  5. package/esm2022/lib/assets/dashboard-route-paths.mock.mjs +12 -0
  6. package/esm2022/lib/assets/dashboard-user-permissions.mock.mjs +23 -0
  7. package/esm2022/lib/assets/date-formats.mjs +28 -0
  8. package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +277 -0
  9. package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +181 -0
  10. package/esm2022/lib/components/member-level-badge/member-level-badge.component.mjs +79 -0
  11. package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +163 -0
  12. package/esm2022/lib/components/welcome-header/dashboard-welcome-header.component.mjs +151 -0
  13. package/esm2022/lib/components/your-groups/your-groups.component.mjs +206 -0
  14. package/esm2022/lib/dashboard.component.mjs +377 -0
  15. package/esm2022/lib/dashboard.module.mjs +16 -0
  16. package/esm2022/lib/dashboard.routes.mjs +7 -0
  17. package/esm2022/lib/models/attendance-action-permissions.model.mjs +2 -0
  18. package/esm2022/lib/models/attendance-state.model.mjs +7 -0
  19. package/esm2022/lib/models/dashboard-list-response.model.mjs +2 -0
  20. package/esm2022/lib/models/dashboard-route-config.model.mjs +2 -0
  21. package/esm2022/lib/models/dashboard-section-state.model.mjs +9 -0
  22. package/esm2022/lib/models/dashboard-user-info.model.mjs +2 -0
  23. package/esm2022/lib/models/group-row.model.mjs +2 -0
  24. package/esm2022/lib/models/meeting-row.model.mjs +2 -0
  25. package/esm2022/lib/models/page-change.model.mjs +2 -0
  26. package/esm2022/lib/models/upcoming-event.model.mjs +2 -0
  27. package/esm2022/lib/services/attendance-reducers.mjs +54 -0
  28. package/esm2022/lib/services/dashboard.service.mjs +208 -0
  29. package/esm2022/lib/services/user-permissions.service.mjs +50 -0
  30. package/esm2022/lib/utils/attendance-action.util.mjs +53 -0
  31. package/esm2022/public-api.mjs +34 -0
  32. package/fesm2022/ieeesa-npm-dashboard.mjs +2234 -0
  33. package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -0
  34. package/index.d.ts +5 -0
  35. package/lib/assets/dashboard-mock.d.ts +31 -0
  36. package/lib/assets/dashboard-route-paths.mock.d.ts +2 -0
  37. package/lib/assets/dashboard-user-permissions.mock.d.ts +2 -0
  38. package/lib/assets/date-formats.d.ts +27 -0
  39. package/lib/components/event-group-card/event-group-card.component.d.ts +300 -0
  40. package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +239 -0
  41. package/lib/components/member-level-badge/member-level-badge.component.d.ts +161 -0
  42. package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +238 -0
  43. package/lib/components/welcome-header/dashboard-welcome-header.component.d.ts +98 -0
  44. package/lib/components/your-groups/your-groups.component.d.ts +110 -0
  45. package/lib/dashboard.component.d.ts +376 -0
  46. package/lib/dashboard.module.d.ts +7 -0
  47. package/lib/dashboard.routes.d.ts +2 -0
  48. package/lib/models/attendance-action-permissions.model.d.ts +4 -0
  49. package/lib/models/attendance-state.model.d.ts +4 -0
  50. package/lib/models/dashboard-list-response.model.d.ts +5 -0
  51. package/lib/models/dashboard-route-config.model.d.ts +7 -0
  52. package/lib/models/dashboard-section-state.model.d.ts +6 -0
  53. package/lib/models/dashboard-user-info.model.d.ts +5 -0
  54. package/lib/models/group-row.model.d.ts +8 -0
  55. package/lib/models/meeting-row.model.d.ts +12 -0
  56. package/lib/models/page-change.model.d.ts +4 -0
  57. package/lib/models/upcoming-event.model.d.ts +13 -0
  58. package/lib/services/attendance-reducers.d.ts +43 -0
  59. package/lib/services/dashboard.service.d.ts +119 -0
  60. package/lib/services/user-permissions.service.d.ts +31 -0
  61. package/lib/utils/attendance-action.util.d.ts +38 -0
  62. package/package.json +30 -3
  63. package/public-api.d.ts +24 -0
@@ -0,0 +1,2234 @@
1
+ import * as i1 from '@angular/common';
2
+ import { CommonModule } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { EventEmitter, Component, ViewEncapsulation, Input, Output, Injectable, NgModule } from '@angular/core';
5
+ import { BehaviorSubject, of, map, catchError, Subject, takeUntil } from 'rxjs';
6
+ import { AlertType } from '@ieeesa-npm/models';
7
+ import * as i1$1 from '@ieeesa-npm/utility';
8
+ import { AlertsService } from '@ieeesa-npm/utility';
9
+ import * as i3 from '@ieeesa-npm/presentation';
10
+ import { LoaderComponent, TableColumnType, DataTableComponent, LegendComponent } from '@ieeesa-npm/presentation';
11
+ import * as i2 from '@angular/material/paginator';
12
+ import { MatPaginatorModule } from '@angular/material/paginator';
13
+ import { DateTime } from 'luxon';
14
+
15
+ /* eslint-disable no-unused-vars */
16
+ var DashboardSectionState;
17
+ (function (DashboardSectionState) {
18
+ DashboardSectionState["LOADING"] = "LOADING";
19
+ DashboardSectionState["LOADED"] = "LOADED";
20
+ DashboardSectionState["EMPTY"] = "EMPTY";
21
+ DashboardSectionState["ERROR"] = "ERROR";
22
+ })(DashboardSectionState || (DashboardSectionState = {}));
23
+
24
+ /* eslint-disable no-unused-vars */
25
+ var AttendanceState;
26
+ (function (AttendanceState) {
27
+ AttendanceState["CURRENTLY_ATTENDING"] = "CURRENTLY_ATTENDING";
28
+ AttendanceState["NOT_ATTENDING"] = "NOT_ATTENDING";
29
+ })(AttendanceState || (AttendanceState = {}));
30
+
31
+ /**
32
+ * Luxon format tokens used across the dashboard library for rendering
33
+ * event/meeting dates, times, and timezones.
34
+ *
35
+ * These tokens follow the luxon `DateTime.toFormat()` convention
36
+ * (NOT moment). New code in this library must use luxon exclusively.
37
+ *
38
+ * @see https://moment.github.io/luxon/#/formatting?id=table-of-tokens
39
+ */
40
+ const DateFormats = {
41
+ /** ISO date used for request payloads, e.g. 2025-03-14. */
42
+ requestPayloadFormat: 'yyyy-MM-dd',
43
+ /** ISO date-time used for request payloads, e.g. 2025-03-14T09:30:00. */
44
+ requestPayloadDateTimeFormat: "yyyy-MM-dd'T'HH:mm:ss",
45
+ /** Human-readable date for display, e.g. 14 Mar 2025. */
46
+ displayFormat: 'dd MMM yyyy',
47
+ /** Human-readable long date for display, e.g. 14 March 2025. */
48
+ displayLongFormat: 'dd MMMM yyyy',
49
+ /** 24-hour time for display, e.g. 09:30. */
50
+ timeFormat: 'HH:mm',
51
+ /** 12-hour time with meridiem for display, e.g. 9:30 AM. */
52
+ timeMeridiemFormat: 'h:mm a',
53
+ /** Short timezone abbreviation for display, e.g. EST. */
54
+ timezoneFormat: 'ZZZZ',
55
+ /** Long timezone name for display, e.g. Eastern Standard Time. */
56
+ timezoneLongFormat: 'ZZZZZ',
57
+ };
58
+
59
+ /**
60
+ * Pure helpers for the per-meeting attendance action state machine. No Angular /
61
+ * service dependencies so they are trivially testable (property-tested as
62
+ * Property 1) and reusable by `MeetingAttendanceRowComponent`.
63
+ *
64
+ * The handler is the single source of truth for what a meeting row's action
65
+ * button should emit when activated. The displayed `AttendanceState` only
66
+ * advances on a successful resolution (handled by the service reducers), so this
67
+ * function is a pure mapping from the current inputs to the action to emit.
68
+ */
69
+ /* eslint-disable no-unused-vars */
70
+ /**
71
+ * The action a meeting row's action button should emit when activated.
72
+ * `NONE` means the activation is non-actionable (empty id or in-flight) and the
73
+ * row must emit no `logAttendance` / `leaveMeeting` / navigation event.
74
+ */
75
+ var AttendanceAction;
76
+ (function (AttendanceAction) {
77
+ AttendanceAction["LOG_ATTENDANCE"] = "LOG_ATTENDANCE";
78
+ AttendanceAction["LEAVE_MEETING"] = "LEAVE_MEETING";
79
+ AttendanceAction["NONE"] = "NONE";
80
+ })(AttendanceAction || (AttendanceAction = {}));
81
+ /* eslint-enable no-unused-vars */
82
+ /**
83
+ * Resolves the attendance action to emit for a meeting row, following the
84
+ * attendance action state machine (see design: Attendance Action State Machine).
85
+ *
86
+ * Behavior:
87
+ * - Returns `NONE` when `meetingId` is empty or undefined (non-actionable row).
88
+ * - Returns `NONE` while the row is in-flight (re-entrancy guard — no further
89
+ * event is emitted until the current action resolves).
90
+ * - Returns `LEAVE_MEETING` when the state is `CURRENTLY_ATTENDING`.
91
+ * - Returns `LOG_ATTENDANCE` when the state is `NOT_ATTENDING` or undefined.
92
+ *
93
+ * @param {AttendanceState | undefined} attendanceState The row's current attendance state.
94
+ * @param {boolean} isInFlight Whether an attendance action for this row is awaiting resolution.
95
+ * @param {string | undefined} meetingId The row's meeting identifier.
96
+ * @return {AttendanceAction} The action to emit, or `NONE` when non-actionable.
97
+ */
98
+ function resolveAttendanceAction(attendanceState, isInFlight, meetingId) {
99
+ if (!meetingId) {
100
+ return AttendanceAction.NONE;
101
+ }
102
+ if (isInFlight) {
103
+ return AttendanceAction.NONE;
104
+ }
105
+ if (attendanceState === AttendanceState.CURRENTLY_ATTENDING) {
106
+ return AttendanceAction.LEAVE_MEETING;
107
+ }
108
+ return AttendanceAction.LOG_ATTENDANCE;
109
+ }
110
+
111
+ var welcomeHeader = {
112
+ greeting: "Welcome back, ",
113
+ fallbackGreeting: "Welcome back",
114
+ helperText: "Here's what's happening inside the portal",
115
+ jumpToLabel: "JUMP TO",
116
+ shortcuts: {
117
+ meetings: {
118
+ label: "Upcoming Meetings & Events",
119
+ iconUrl: "/assets/images/icons/attendance-flag.svg",
120
+ ariaLabel: "Jump to upcoming meetings and events"
121
+ },
122
+ groups: {
123
+ label: "Your Groups",
124
+ iconUrl: "/assets/images/icons/icon-committees.svg",
125
+ ariaLabel: "Jump to your groups"
126
+ }
127
+ }
128
+ };
129
+ var upcomingSection = {
130
+ title: "Upcoming Meetings & Events",
131
+ viewAllLabel: "View All",
132
+ expandLabel: "Expand",
133
+ collapseLabel: "Collapse",
134
+ ariaLabel: {
135
+ viewAll: "View all upcoming meetings and events",
136
+ toggle: "Collapse or expand upcoming meetings and events"
137
+ },
138
+ emptyMessage: "You have no upcoming meetings or events.",
139
+ errorMessage: "Unable to load upcoming meetings and events. Please try again."
140
+ };
141
+ var eventGroupCard = {
142
+ viewEventLabel: "View Event",
143
+ meetingListToggle: {
144
+ showLabelPrefix: "Show Meetings (",
145
+ showLabelSuffix: " open for attendance)",
146
+ hideLabel: "Hide Meetings"
147
+ },
148
+ ariaLabel: {
149
+ viewEvent: "View event details",
150
+ meetingListToggle: "Show or hide the meeting list for this event"
151
+ },
152
+ paginator: {
153
+ rangeTemplate: "Showing {start}-{end} of {total}",
154
+ totalTemplate: "{total} meetings"
155
+ }
156
+ };
157
+ var meetingRow = {
158
+ emptyFieldPlaceholder: "—",
159
+ currentlyAttendingIndicator: "Currently Attending",
160
+ logAttendanceLabel: "Log Attendance",
161
+ leaveMeetingLabel: "Leave Meeting",
162
+ ariaLabel: {
163
+ meetingNameLink: "View meeting details",
164
+ logAttendance: "Log attendance for this meeting",
165
+ leaveMeeting: "Leave this meeting"
166
+ }
167
+ };
168
+ var groupsSection = {
169
+ title: "Your Groups",
170
+ viewAllLabel: "View All",
171
+ expandLabel: "Expand",
172
+ collapseLabel: "Collapse",
173
+ countSuffix: "Groups",
174
+ emptyValue: "-",
175
+ ariaLabel: {
176
+ viewAll: "View all your groups",
177
+ toggle: "Collapse or expand your groups",
178
+ groupLink: "View group details"
179
+ },
180
+ columns: {
181
+ group: "Group",
182
+ type: "Type",
183
+ officerRole: "Officer Role",
184
+ affiliation: "Affiliation",
185
+ memberLevel: "Member Level"
186
+ },
187
+ paginator: {
188
+ rangeTemplate: "Showing {start}-{end} of {total}",
189
+ totalTemplate: "{total} groups"
190
+ },
191
+ memberLevelBadge: {
192
+ votingMember: "ieeesa-your-groups__badge--success",
193
+ "default": "ieeesa-your-groups__badge--warning"
194
+ },
195
+ emptyMessage: "You are not a member of any groups.",
196
+ errorMessage: "Unable to load your groups. Please try again."
197
+ };
198
+ var memberLevel = {
199
+ colorMap: {
200
+ "Voting Member": "$ieeesa-color-success",
201
+ Observer: "$ieeesa-color-info",
202
+ "Associate Member": "$ieeesa-color-warning",
203
+ Member: "$ieeesa-color-primary",
204
+ "default": "$ieeesa-color-neutral"
205
+ }
206
+ };
207
+ var attendance = {
208
+ errorMessage: "Unable to update your attendance. Please try again."
209
+ };
210
+ var footer = {
211
+ links: [
212
+ {
213
+ label: "Dashboard",
214
+ target: "/dashboard"
215
+ },
216
+ {
217
+ label: "Contact & Support",
218
+ target: "https://supportcenter.ieee.org/app/home"
219
+ },
220
+ {
221
+ label: "Accessibility",
222
+ target: "https://www.ieee.org/accessibility-statement.html"
223
+ },
224
+ {
225
+ label: "Nondiscrimination Policy",
226
+ target: "https://www.ieee.org/about/corporate/governance/p9-26.html"
227
+ },
228
+ {
229
+ label: "IEEE Ethics Reporting",
230
+ target: "https://www.ieee.org/about/ethics/index.html"
231
+ },
232
+ {
233
+ label: "IEEE Privacy Policy",
234
+ target: "https://www.ieee.org/security-privacy.html"
235
+ },
236
+ {
237
+ label: "IEEE SA Copyright Policy",
238
+ target: "https://standards.ieee.org/about/policies/"
239
+ }
240
+ ],
241
+ copyright: "© Copyright 2024 IEEE - All rights reserved. Use of this website signifies your agreement to the IEEE Terms and Conditions."
242
+ };
243
+ var defaultRouteConfig = {
244
+ eventDetail: "/events",
245
+ meetingDetail: "/meetings",
246
+ groupDetail: "/groups",
247
+ viewAllEvents: "/events-and-meetings/view-events-meetings-list",
248
+ viewAllGroups: "/groups"
249
+ };
250
+ var constants = {
251
+ welcomeHeader: welcomeHeader,
252
+ upcomingSection: upcomingSection,
253
+ eventGroupCard: eventGroupCard,
254
+ meetingRow: meetingRow,
255
+ groupsSection: groupsSection,
256
+ memberLevel: memberLevel,
257
+ attendance: attendance,
258
+ footer: footer,
259
+ defaultRouteConfig: defaultRouteConfig
260
+ };
261
+
262
+ var constants$1 = /*#__PURE__*/Object.freeze({
263
+ __proto__: null,
264
+ attendance: attendance,
265
+ default: constants,
266
+ defaultRouteConfig: defaultRouteConfig,
267
+ eventGroupCard: eventGroupCard,
268
+ footer: footer,
269
+ groupsSection: groupsSection,
270
+ meetingRow: meetingRow,
271
+ memberLevel: memberLevel,
272
+ upcomingSection: upcomingSection,
273
+ welcomeHeader: welcomeHeader
274
+ });
275
+
276
+ /**
277
+ * Meeting_Attendance_Row renders a single meeting within an event-group card:
278
+ * the meeting-name link, group/committee, room/location, date, and
279
+ * time+timezone (all luxon-formatted), together with the attendance action
280
+ * button that drives the per-meeting attendance state machine.
281
+ *
282
+ * The component is purely presentational — it emits navigation and attendance
283
+ * intents via `@Output()` and never performs navigation or HTTP itself. The
284
+ * action button delegates to the pure `resolveAttendanceAction` handler so the
285
+ * emit/guard logic is shared with the property-tested core (Property 1), and the
286
+ * displayed state only advances when the host updates `attendanceState`.
287
+ * @export
288
+ * @class MeetingAttendanceRowComponent
289
+ */
290
+ class MeetingAttendanceRowComponent {
291
+ constructor() {
292
+ this.constants = constants$1;
293
+ /** The current attendance state controlling label/indicator and action. */
294
+ this.attendanceState = AttendanceState.NOT_ATTENDING;
295
+ /** Whether an attendance action for this meeting is awaiting resolution. */
296
+ this.isInFlight = false;
297
+ /** Host permissions gating the log-attendance / leave-meeting buttons. */
298
+ this.permissions = {
299
+ canLogAttendance: false,
300
+ canLeaveMeeting: false,
301
+ };
302
+ /** Emits the meeting id when the meeting-name link is activated (Req 7.4). */
303
+ this.openMeeting = new EventEmitter();
304
+ /** Emits the meeting id to request logging attendance (Req 7.7). */
305
+ this.logAttendance = new EventEmitter();
306
+ /** Emits the meeting id to request leaving the meeting (Req 7.8). */
307
+ this.leaveMeeting = new EventEmitter();
308
+ /** Expose the enum to the template for state comparisons. */
309
+ this.AttendanceState = AttendanceState;
310
+ }
311
+ /**
312
+ * Whether this row is actionable — a non-empty `meetingId` is required for the
313
+ * meeting-name link and action button to emit anything (Req 7.10).
314
+ * @return {boolean} True when the row has a usable meeting id.
315
+ * @memberof MeetingAttendanceRowComponent
316
+ */
317
+ get isActionable() {
318
+ return !!this.meeting?.meetingId;
319
+ }
320
+ /**
321
+ * Whether the row is in the currently-attending state, which shows the
322
+ * currently-attending indicator and the leave-meeting action (Req 7.5).
323
+ * @return {boolean} True when the attendance state is `CURRENTLY_ATTENDING`.
324
+ * @memberof MeetingAttendanceRowComponent
325
+ */
326
+ get isCurrentlyAttending() {
327
+ return this.attendanceState === AttendanceState.CURRENTLY_ATTENDING;
328
+ }
329
+ /**
330
+ * Whether the log-attendance button should be shown: only when the row is in
331
+ * the log state (not currently attending) and the host grants
332
+ * `canLogAttendance` (Req 7.6, 12.1).
333
+ * @return {boolean} True when the log-attendance button is visible.
334
+ * @memberof MeetingAttendanceRowComponent
335
+ */
336
+ get showLogAttendanceButton() {
337
+ return !this.isCurrentlyAttending && !!this.permissions?.canLogAttendance;
338
+ }
339
+ /**
340
+ * Whether the leave-meeting button should be shown: only when the row is in
341
+ * the currently-attending state and the host grants `canLeaveMeeting`
342
+ * (Req 7.5, 12.2).
343
+ * @return {boolean} True when the leave-meeting button is visible.
344
+ * @memberof MeetingAttendanceRowComponent
345
+ */
346
+ get showLeaveMeetingButton() {
347
+ return this.isCurrentlyAttending && !!this.permissions?.canLeaveMeeting;
348
+ }
349
+ /**
350
+ * Resolves a group-or-committee / room-or-location field value, substituting
351
+ * the empty-field placeholder from `constants.json` when the value is empty or
352
+ * undefined (Req 7.2).
353
+ * @param {string | undefined} value - The raw field value from the meeting.
354
+ * @return {string} The value to display, or the empty-field placeholder.
355
+ * @memberof MeetingAttendanceRowComponent
356
+ */
357
+ resolveFieldValue(value) {
358
+ const placeholder = this.constants?.meetingRow?.emptyFieldPlaceholder ?? '—';
359
+ return value && value.trim().length > 0 ? value : placeholder;
360
+ }
361
+ /**
362
+ * Formats the meeting date for display using the shared luxon display format
363
+ * (Req 7.3). Falls back to the raw value when it cannot be parsed.
364
+ * @return {string} The formatted meeting date.
365
+ * @memberof MeetingAttendanceRowComponent
366
+ */
367
+ get formattedDate() {
368
+ return this.formatIso(this.meeting?.meetingDate, DateFormats.displayFormat);
369
+ }
370
+ /**
371
+ * Formats the meeting time + timezone for display using luxon (Req 7.3).
372
+ * The timezone abbreviation from the meeting model is appended to the parsed
373
+ * time. Falls back to the raw value when it cannot be parsed.
374
+ * @return {string} The formatted meeting time with timezone.
375
+ * @memberof MeetingAttendanceRowComponent
376
+ */
377
+ get formattedTime() {
378
+ const time = this.formatIso(this.meeting?.meetingTime, DateFormats.timeMeridiemFormat);
379
+ const timezone = this.meeting?.timezone ?? '';
380
+ return timezone ? `${time} ${timezone}` : time;
381
+ }
382
+ /**
383
+ * Handles activation of the attendance action button. Delegates to the pure
384
+ * `resolveAttendanceAction` handler and emits exactly one event based on the
385
+ * resolved action: `logAttendance` for `LOG_ATTENDANCE`, `leaveMeeting` for
386
+ * `LEAVE_MEETING`, and nothing for `NONE` (empty id or in-flight)
387
+ * (Req 7.7, 7.8, 7.9, 7.10, 13.6).
388
+ * @memberof MeetingAttendanceRowComponent
389
+ */
390
+ onAttendanceAction() {
391
+ const action = resolveAttendanceAction(this.attendanceState, this.isInFlight, this.meeting?.meetingId);
392
+ if (action === AttendanceAction.LOG_ATTENDANCE) {
393
+ this.logAttendance.emit(this.meeting.meetingId);
394
+ return;
395
+ }
396
+ if (action === AttendanceAction.LEAVE_MEETING) {
397
+ this.leaveMeeting.emit(this.meeting.meetingId);
398
+ }
399
+ }
400
+ /**
401
+ * Handles activation of the meeting-name link. Emits the meeting id only when
402
+ * the row is actionable (non-empty meeting id) (Req 7.4, 7.10).
403
+ * @memberof MeetingAttendanceRowComponent
404
+ */
405
+ onOpenMeeting() {
406
+ if (!this.isActionable) {
407
+ return;
408
+ }
409
+ this.openMeeting.emit(this.meeting.meetingId);
410
+ }
411
+ /**
412
+ * Parses an ISO string with luxon and formats it with the supplied token,
413
+ * returning the raw value unchanged when it is missing or unparseable.
414
+ * @param {string | undefined} isoValue - The ISO date/time string.
415
+ * @param {string} format - The luxon format token.
416
+ * @return {string} The formatted value or the raw/empty fallback.
417
+ * @memberof MeetingAttendanceRowComponent
418
+ */
419
+ formatIso(isoValue, format) {
420
+ if (!isoValue) {
421
+ return '';
422
+ }
423
+ const parsed = DateTime.fromISO(isoValue, { setZone: true });
424
+ return parsed.isValid ? parsed.toFormat(format) : isoValue;
425
+ }
426
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MeetingAttendanceRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
427
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MeetingAttendanceRowComponent, isStandalone: true, selector: "ieeesa-meeting-attendance-row", inputs: { meeting: "meeting", attendanceState: "attendanceState", isInFlight: "isInFlight", permissions: "permissions" }, outputs: { openMeeting: "openMeeting", logAttendance: "logAttendance", leaveMeeting: "leaveMeeting" }, ngImport: i0, template: "<div class=\"ieeesa-meeting-attendance-row\">\r\n <div class=\"ieeesa-meeting-attendance-row__details\">\r\n <!-- Meeting-name link (emits openMeeting; non-actionable when id missing). -->\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-meeting-attendance-row__name-link\"\r\n [disabled]=\"!isActionable\"\r\n [attr.aria-label]=\"constants?.meetingRow?.ariaLabel?.meetingNameLink ?? 'View meeting details'\"\r\n (click)=\"onOpenMeeting()\"\r\n >\r\n {{ meeting?.meetingName }}\r\n </button>\r\n\r\n <dl class=\"ieeesa-meeting-attendance-row__meta\">\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">\r\n {{ constants?.groupsSection?.columns?.group ?? 'Group' }}\r\n </dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ resolveFieldValue(meeting?.groupOrCommittee) }}\r\n </dd>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">\r\n {{ constants?.groupsSection?.columns?.affiliation ?? 'Location' }}\r\n </dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ resolveFieldValue(meeting?.roomOrLocation) }}\r\n </dd>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">Date</dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ formattedDate }}\r\n </dd>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">Time</dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ formattedTime }}\r\n </dd>\r\n </div>\r\n </dl>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__actions\">\r\n <!-- Currently-attending indicator shown only in the attending state. -->\r\n <span\r\n *ngIf=\"isCurrentlyAttending\"\r\n class=\"ieeesa-meeting-attendance-row__attending-indicator\"\r\n >\r\n {{ constants?.meetingRow?.currentlyAttendingIndicator ?? 'Currently Attending' }}\r\n </span>\r\n\r\n <!-- Log-attendance button: shown in the log state with the permission. -->\r\n <button\r\n *ngIf=\"showLogAttendanceButton\"\r\n type=\"button\"\r\n class=\"ieeesa-meeting-attendance-row__action-button ieeesa-meeting-attendance-row__action-button--log\"\r\n [disabled]=\"isInFlight || !isActionable\"\r\n [attr.aria-label]=\"constants?.meetingRow?.ariaLabel?.logAttendance ?? 'Log attendance for this meeting'\"\r\n (click)=\"onAttendanceAction()\"\r\n >\r\n {{ constants?.meetingRow?.logAttendanceLabel ?? 'Log Attendance' }}\r\n </button>\r\n\r\n <!-- Leave-meeting button: shown in the attending state with the permission. -->\r\n <button\r\n *ngIf=\"showLeaveMeetingButton\"\r\n type=\"button\"\r\n class=\"ieeesa-meeting-attendance-row__action-button ieeesa-meeting-attendance-row__action-button--leave\"\r\n [disabled]=\"isInFlight || !isActionable\"\r\n [attr.aria-label]=\"constants?.meetingRow?.ariaLabel?.leaveMeeting ?? 'Leave this meeting'\"\r\n (click)=\"onAttendanceAction()\"\r\n >\r\n {{ constants?.meetingRow?.leaveMeetingLabel ?? 'Leave Meeting' }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-meeting-attendance-row{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid #d7d6d6}.ieeesa-meeting-attendance-row__details{display:flex;flex-direction:column;gap:8px;min-width:0}.ieeesa-meeting-attendance-row__name-link{padding:0;border:0;background:none;text-align:left;text-decoration:underline;color:#00629b;cursor:pointer}.ieeesa-meeting-attendance-row__name-link:disabled{color:#939094;text-decoration:none;cursor:default}.ieeesa-meeting-attendance-row__meta{display:flex;flex-wrap:wrap;gap:4px 24px;margin:0}.ieeesa-meeting-attendance-row__meta-item{display:flex;flex-direction:column;gap:4px}.ieeesa-meeting-attendance-row__meta-term{margin:0;font-size:.75rem;color:#939094}.ieeesa-meeting-attendance-row__meta-value{margin:0;font-size:.875rem;color:#000}.ieeesa-meeting-attendance-row__actions{display:flex;align-items:center;gap:12px;flex-shrink:0}.ieeesa-meeting-attendance-row__attending-indicator{display:inline-flex;align-items:center;padding:4px 12px;border-radius:16px;font-size:.8125rem;color:#00629b;background-color:#f0f5f9}.ieeesa-meeting-attendance-row__action-button{padding:8px 16px;border-radius:4px;font-size:.875rem;cursor:pointer}.ieeesa-meeting-attendance-row__action-button--log{border:1px solid #00629b;background-color:#00629b;color:#fff}.ieeesa-meeting-attendance-row__action-button--leave{border:1px solid #00629b;background-color:#fff;color:#00629b}.ieeesa-meeting-attendance-row__action-button:disabled{border-color:#939094;background-color:#939094;color:#fff;cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None }); }
428
+ }
429
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MeetingAttendanceRowComponent, decorators: [{
430
+ type: Component,
431
+ args: [{ selector: 'ieeesa-meeting-attendance-row', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"ieeesa-meeting-attendance-row\">\r\n <div class=\"ieeesa-meeting-attendance-row__details\">\r\n <!-- Meeting-name link (emits openMeeting; non-actionable when id missing). -->\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-meeting-attendance-row__name-link\"\r\n [disabled]=\"!isActionable\"\r\n [attr.aria-label]=\"constants?.meetingRow?.ariaLabel?.meetingNameLink ?? 'View meeting details'\"\r\n (click)=\"onOpenMeeting()\"\r\n >\r\n {{ meeting?.meetingName }}\r\n </button>\r\n\r\n <dl class=\"ieeesa-meeting-attendance-row__meta\">\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">\r\n {{ constants?.groupsSection?.columns?.group ?? 'Group' }}\r\n </dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ resolveFieldValue(meeting?.groupOrCommittee) }}\r\n </dd>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">\r\n {{ constants?.groupsSection?.columns?.affiliation ?? 'Location' }}\r\n </dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ resolveFieldValue(meeting?.roomOrLocation) }}\r\n </dd>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">Date</dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ formattedDate }}\r\n </dd>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__meta-item\">\r\n <dt class=\"ieeesa-meeting-attendance-row__meta-term\">Time</dt>\r\n <dd class=\"ieeesa-meeting-attendance-row__meta-value\">\r\n {{ formattedTime }}\r\n </dd>\r\n </div>\r\n </dl>\r\n </div>\r\n\r\n <div class=\"ieeesa-meeting-attendance-row__actions\">\r\n <!-- Currently-attending indicator shown only in the attending state. -->\r\n <span\r\n *ngIf=\"isCurrentlyAttending\"\r\n class=\"ieeesa-meeting-attendance-row__attending-indicator\"\r\n >\r\n {{ constants?.meetingRow?.currentlyAttendingIndicator ?? 'Currently Attending' }}\r\n </span>\r\n\r\n <!-- Log-attendance button: shown in the log state with the permission. -->\r\n <button\r\n *ngIf=\"showLogAttendanceButton\"\r\n type=\"button\"\r\n class=\"ieeesa-meeting-attendance-row__action-button ieeesa-meeting-attendance-row__action-button--log\"\r\n [disabled]=\"isInFlight || !isActionable\"\r\n [attr.aria-label]=\"constants?.meetingRow?.ariaLabel?.logAttendance ?? 'Log attendance for this meeting'\"\r\n (click)=\"onAttendanceAction()\"\r\n >\r\n {{ constants?.meetingRow?.logAttendanceLabel ?? 'Log Attendance' }}\r\n </button>\r\n\r\n <!-- Leave-meeting button: shown in the attending state with the permission. -->\r\n <button\r\n *ngIf=\"showLeaveMeetingButton\"\r\n type=\"button\"\r\n class=\"ieeesa-meeting-attendance-row__action-button ieeesa-meeting-attendance-row__action-button--leave\"\r\n [disabled]=\"isInFlight || !isActionable\"\r\n [attr.aria-label]=\"constants?.meetingRow?.ariaLabel?.leaveMeeting ?? 'Leave this meeting'\"\r\n (click)=\"onAttendanceAction()\"\r\n >\r\n {{ constants?.meetingRow?.leaveMeetingLabel ?? 'Leave Meeting' }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-meeting-attendance-row{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid #d7d6d6}.ieeesa-meeting-attendance-row__details{display:flex;flex-direction:column;gap:8px;min-width:0}.ieeesa-meeting-attendance-row__name-link{padding:0;border:0;background:none;text-align:left;text-decoration:underline;color:#00629b;cursor:pointer}.ieeesa-meeting-attendance-row__name-link:disabled{color:#939094;text-decoration:none;cursor:default}.ieeesa-meeting-attendance-row__meta{display:flex;flex-wrap:wrap;gap:4px 24px;margin:0}.ieeesa-meeting-attendance-row__meta-item{display:flex;flex-direction:column;gap:4px}.ieeesa-meeting-attendance-row__meta-term{margin:0;font-size:.75rem;color:#939094}.ieeesa-meeting-attendance-row__meta-value{margin:0;font-size:.875rem;color:#000}.ieeesa-meeting-attendance-row__actions{display:flex;align-items:center;gap:12px;flex-shrink:0}.ieeesa-meeting-attendance-row__attending-indicator{display:inline-flex;align-items:center;padding:4px 12px;border-radius:16px;font-size:.8125rem;color:#00629b;background-color:#f0f5f9}.ieeesa-meeting-attendance-row__action-button{padding:8px 16px;border-radius:4px;font-size:.875rem;cursor:pointer}.ieeesa-meeting-attendance-row__action-button--log{border:1px solid #00629b;background-color:#00629b;color:#fff}.ieeesa-meeting-attendance-row__action-button--leave{border:1px solid #00629b;background-color:#fff;color:#00629b}.ieeesa-meeting-attendance-row__action-button:disabled{border-color:#939094;background-color:#939094;color:#fff;cursor:default}\n"] }]
432
+ }], propDecorators: { meeting: [{
433
+ type: Input
434
+ }], attendanceState: [{
435
+ type: Input
436
+ }], isInFlight: [{
437
+ type: Input
438
+ }], permissions: [{
439
+ type: Input
440
+ }], openMeeting: [{
441
+ type: Output
442
+ }], logAttendance: [{
443
+ type: Output
444
+ }], leaveMeeting: [{
445
+ type: Output
446
+ }] } });
447
+
448
+ /**
449
+ * Event_Group_Card renders a single upcoming event as a card: the status badge,
450
+ * title, day indicator, meeting-count summary sub-line, start/end date, and
451
+ * timezone (all luxon-formatted). It exposes a "View Event" action, a
452
+ * show/hide toggle for the meeting list labeled with the open-for-attendance
453
+ * count, the per-event meeting rows (one {@link MeetingAttendanceRowComponent}
454
+ * per meeting on the current page), and a per-card paginator.
455
+ *
456
+ * The component is purely presentational — it emits navigation, attendance, and
457
+ * pagination intents via `@Output()` and never performs navigation or HTTP
458
+ * itself. Meeting-row outputs (`openMeeting`/`logAttendance`/`leaveMeeting`) are
459
+ * bubbled upward unchanged so the container can delegate to the service.
460
+ * @export
461
+ * @class EventGroupCardComponent
462
+ */
463
+ class EventGroupCardComponent {
464
+ constructor() {
465
+ /** User-facing strings sourced from `constants.json`. */
466
+ this.constants = constants$1;
467
+ /** Host permissions gating the per-row log-attendance / leave-meeting buttons. */
468
+ this.permissions = {
469
+ canLogAttendance: false,
470
+ canLeaveMeeting: false,
471
+ };
472
+ /** Map of meeting id to current attendance state, passed down to each row. */
473
+ this.attendanceStates = {};
474
+ /** Set of meeting ids with an attendance action awaiting resolution. */
475
+ this.inFlightMeetingIds = new Set();
476
+ /** Whether the host has determined the viewport is at/below the mobile breakpoint. */
477
+ this.isMobileView = false;
478
+ /** Emits the event id when the "View Event" button is activated (Req 6.4). */
479
+ this.viewEvent = new EventEmitter();
480
+ /** Bubbles the meeting id when a row's meeting-name link is activated (Req 6.7, 7.4). */
481
+ this.openMeeting = new EventEmitter();
482
+ /** Bubbles the meeting id when a row requests logging attendance (Req 6.7, 7.7). */
483
+ this.logAttendance = new EventEmitter();
484
+ /** Bubbles the meeting id when a row requests leaving the meeting (Req 6.7, 7.8). */
485
+ this.leaveMeeting = new EventEmitter();
486
+ /** Emits the requested page when the per-card paginator changes (Req 6.9, 3.3). */
487
+ this.pageChange = new EventEmitter();
488
+ /** The default page size for the per-card meeting paginator. */
489
+ this.defaultPageSize = 5;
490
+ /** The current zero-based page index of the meeting list. */
491
+ this.pageIndex = 0;
492
+ /** The current page size of the meeting list. */
493
+ this.pageSize = this.defaultPageSize;
494
+ /** Whether the meeting list is currently shown (toggled open). */
495
+ this.isMeetingListOpen = false;
496
+ }
497
+ /**
498
+ * The full list of meetings for the event, defaulting to an empty list when
499
+ * the event has none.
500
+ * @return {MeetingRow[]} The event's meetings.
501
+ * @memberof EventGroupCardComponent
502
+ */
503
+ get meetings() {
504
+ return this.event?.meetings ?? [];
505
+ }
506
+ /** The total number of meetings for the event (paginator length). */
507
+ get totalMeetings() {
508
+ return this.meetings.length;
509
+ }
510
+ /**
511
+ * The slice of meetings for the current page, used by the row `*ngFor`.
512
+ * @return {MeetingRow[]} The meetings on the current page.
513
+ * @memberof EventGroupCardComponent
514
+ */
515
+ get pagedMeetings() {
516
+ const start = this.pageIndex * this.pageSize;
517
+ return this.meetings.slice(start, start + this.pageSize);
518
+ }
519
+ /**
520
+ * The one-based index of the first meeting shown on the current page, or 0
521
+ * when there are no meetings.
522
+ * @return {number} The start index for the range template.
523
+ * @memberof EventGroupCardComponent
524
+ */
525
+ get rangeStart() {
526
+ return this.totalMeetings === 0 ? 0 : this.pageIndex * this.pageSize + 1;
527
+ }
528
+ /**
529
+ * The one-based index of the last meeting shown on the current page, clamped
530
+ * to the total meeting count.
531
+ * @return {number} The end index for the range template.
532
+ * @memberof EventGroupCardComponent
533
+ */
534
+ get rangeEnd() {
535
+ return Math.min((this.pageIndex + 1) * this.pageSize, this.totalMeetings);
536
+ }
537
+ /**
538
+ * The paginator range label (e.g. "Showing 1-5 of 12") built from the
539
+ * `constants.json` range template with the current start/end/total values.
540
+ * @return {string} The formatted range label.
541
+ * @memberof EventGroupCardComponent
542
+ */
543
+ get rangeLabel() {
544
+ const template = this.constants?.eventGroupCard?.paginator?.rangeTemplate ??
545
+ 'Showing {start}-{end} of {total}';
546
+ return template
547
+ .replace('{start}', `${this.rangeStart}`)
548
+ .replace('{end}', `${this.rangeEnd}`)
549
+ .replace('{total}', `${this.totalMeetings}`);
550
+ }
551
+ /**
552
+ * The meeting-count summary sub-line (e.g. "12 meetings") built from the
553
+ * `constants.json` total template with the event's meeting count.
554
+ * @return {string} The formatted meeting-count summary.
555
+ * @memberof EventGroupCardComponent
556
+ */
557
+ get meetingCountSummary() {
558
+ const template = this.constants?.eventGroupCard?.paginator?.totalTemplate ??
559
+ '{total} meetings';
560
+ return template.replace('{total}', `${this.event?.meetingCount ?? 0}`);
561
+ }
562
+ /**
563
+ * The meeting-list show/hide toggle label. When the list is hidden the label
564
+ * reads "Show Meetings ({count} open for attendance)" built from the
565
+ * `constants.json` templates and the event's open-for-attendance count; when
566
+ * the list is shown the label reads the configured hide label (Req 6.5).
567
+ * @return {string} The toggle button label.
568
+ * @memberof EventGroupCardComponent
569
+ */
570
+ get meetingListToggleLabel() {
571
+ const toggle = this.constants?.eventGroupCard?.meetingListToggle;
572
+ if (this.isMeetingListOpen) {
573
+ return toggle?.hideLabel ?? 'Hide Meetings';
574
+ }
575
+ const prefix = toggle?.showLabelPrefix ?? 'Show Meetings (';
576
+ const suffix = toggle?.showLabelSuffix ?? ' open for attendance)';
577
+ return `${prefix}${this.event?.openForAttendanceCount ?? 0}${suffix}`;
578
+ }
579
+ /** The luxon-formatted start date of the event (Req 6.2). */
580
+ get formattedStartDate() {
581
+ return this.formatIso(this.event?.startDate, DateFormats.displayFormat);
582
+ }
583
+ /** The luxon-formatted end date of the event (Req 6.2). */
584
+ get formattedEndDate() {
585
+ return this.formatIso(this.event?.endDate, DateFormats.displayFormat);
586
+ }
587
+ /**
588
+ * `trackBy` for the meeting-row `*ngFor`, keyed by the stable meeting id so
589
+ * Angular reuses row components across pagination/state changes (Req 6.7, 14.4).
590
+ * @param {number} _index - The iteration index (unused).
591
+ * @param {MeetingRow} meeting - The meeting for this row.
592
+ * @return {string} The stable track key (meeting id).
593
+ * @memberof EventGroupCardComponent
594
+ */
595
+ trackByMeetingId(_index, meeting) {
596
+ return meeting?.meetingId ?? `${_index}`;
597
+ }
598
+ /**
599
+ * Resolves the attendance state for a meeting from the `attendanceStates` map,
600
+ * defaulting to `NOT_ATTENDING` when the map has no entry for it.
601
+ * @param {MeetingRow} meeting - The meeting to resolve state for.
602
+ * @return {AttendanceState} The attendance state passed to the row.
603
+ * @memberof EventGroupCardComponent
604
+ */
605
+ resolveAttendanceState(meeting) {
606
+ return (this.attendanceStates?.[meeting?.meetingId] ??
607
+ AttendanceState.NOT_ATTENDING);
608
+ }
609
+ /**
610
+ * Resolves whether a meeting has an attendance action in flight from the
611
+ * `inFlightMeetingIds` set.
612
+ * @param {MeetingRow} meeting - The meeting to check.
613
+ * @return {boolean} True when the meeting's action is awaiting resolution.
614
+ * @memberof EventGroupCardComponent
615
+ */
616
+ resolveIsInFlight(meeting) {
617
+ return this.inFlightMeetingIds?.has(meeting?.meetingId) ?? false;
618
+ }
619
+ /**
620
+ * Toggles the meeting-list visibility (Req 6.6).
621
+ * @memberof EventGroupCardComponent
622
+ */
623
+ onToggleMeetingList() {
624
+ this.isMeetingListOpen = !this.isMeetingListOpen;
625
+ }
626
+ /**
627
+ * Handles the "View Event" button, emitting the event id to the host (Req 6.4).
628
+ * @memberof EventGroupCardComponent
629
+ */
630
+ onViewEvent() {
631
+ this.viewEvent.emit(this.event?.eventId);
632
+ }
633
+ /**
634
+ * Bubbles a row's meeting-name link activation upward (Req 6.7, 7.4).
635
+ * @param {string} meetingId - The id emitted by the row.
636
+ * @memberof EventGroupCardComponent
637
+ */
638
+ onOpenMeeting(meetingId) {
639
+ this.openMeeting.emit(meetingId);
640
+ }
641
+ /**
642
+ * Bubbles a row's log-attendance request upward (Req 6.7, 7.7).
643
+ * @param {string} meetingId - The id emitted by the row.
644
+ * @memberof EventGroupCardComponent
645
+ */
646
+ onLogAttendance(meetingId) {
647
+ this.logAttendance.emit(meetingId);
648
+ }
649
+ /**
650
+ * Bubbles a row's leave-meeting request upward (Req 6.7, 7.8).
651
+ * @param {string} meetingId - The id emitted by the row.
652
+ * @memberof EventGroupCardComponent
653
+ */
654
+ onLeaveMeeting(meetingId) {
655
+ this.leaveMeeting.emit(meetingId);
656
+ }
657
+ /**
658
+ * Handles the per-card paginator change, updating the local page state and
659
+ * emitting the requested page as a {@link PageChange} (Req 6.9, 3.3).
660
+ * @param {PageEvent} event - The Material paginator page event.
661
+ * @memberof EventGroupCardComponent
662
+ */
663
+ onPageChange(event) {
664
+ this.pageIndex = event.pageIndex;
665
+ this.pageSize = event.pageSize;
666
+ this.pageChange.emit({
667
+ pageIndex: event.pageIndex,
668
+ pageSize: event.pageSize,
669
+ });
670
+ }
671
+ /**
672
+ * Parses an ISO string with luxon and formats it with the supplied token,
673
+ * returning the raw value unchanged when it is missing or unparseable.
674
+ * @param {string | undefined} isoValue - The ISO date/time string.
675
+ * @param {string} format - The luxon format token.
676
+ * @return {string} The formatted value or the raw/empty fallback.
677
+ * @memberof EventGroupCardComponent
678
+ */
679
+ formatIso(isoValue, format) {
680
+ if (!isoValue) {
681
+ return '';
682
+ }
683
+ const parsed = DateTime.fromISO(isoValue, { setZone: true });
684
+ return parsed.isValid ? parsed.toFormat(format) : isoValue;
685
+ }
686
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EventGroupCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
687
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EventGroupCardComponent, isStandalone: true, selector: "ieeesa-event-group-card", inputs: { event: "event", permissions: "permissions", attendanceStates: "attendanceStates", inFlightMeetingIds: "inFlightMeetingIds", isMobileView: "isMobileView" }, outputs: { viewEvent: "viewEvent", openMeeting: "openMeeting", logAttendance: "logAttendance", leaveMeeting: "leaveMeeting", pageChange: "pageChange" }, ngImport: i0, template: "<article\r\n class=\"ieeesa-event-group-card\"\r\n [class.ieeesa-event-group-card--mobile]=\"isMobileView\"\r\n>\r\n <header class=\"ieeesa-event-group-card__header\">\r\n <div class=\"ieeesa-event-group-card__heading\">\r\n <!-- Status badge (Req 6.1). -->\r\n <span\r\n *ngIf=\"event?.status\"\r\n class=\"ieeesa-event-group-card__status\"\r\n >\r\n {{ event?.status }}\r\n </span>\r\n\r\n <!-- Event title (Req 6.1). -->\r\n <h3 class=\"ieeesa-event-group-card__title\">{{ event?.title }}</h3>\r\n\r\n <!-- Day indicator (Req 6.1). -->\r\n <span\r\n *ngIf=\"event?.dayIndicator\"\r\n class=\"ieeesa-event-group-card__day-indicator\"\r\n >\r\n {{ event?.dayIndicator }}\r\n </span>\r\n </div>\r\n\r\n <!-- View Event action (Req 6.3, 6.4). -->\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-event-group-card__view-event\"\r\n [attr.aria-label]=\"constants?.eventGroupCard?.ariaLabel?.viewEvent ?? 'View event details'\"\r\n (click)=\"onViewEvent()\"\r\n >\r\n {{ constants?.eventGroupCard?.viewEventLabel ?? 'View Event' }}\r\n </button>\r\n </header>\r\n\r\n <dl class=\"ieeesa-event-group-card__meta\">\r\n <!-- Meeting-count summary sub-line (Req 6.1). -->\r\n <div class=\"ieeesa-event-group-card__meta-item\">\r\n <dd class=\"ieeesa-event-group-card__meeting-count\">\r\n {{ meetingCountSummary }}\r\n </dd>\r\n </div>\r\n\r\n <!-- Start / end date (Req 6.2). -->\r\n <div class=\"ieeesa-event-group-card__meta-item\">\r\n <dd class=\"ieeesa-event-group-card__dates\">\r\n {{ formattedStartDate }}<ng-container *ngIf=\"formattedEndDate\">\r\n &ndash; {{ formattedEndDate }}</ng-container>\r\n </dd>\r\n </div>\r\n\r\n <!-- Timezone (Req 6.2). -->\r\n <div class=\"ieeesa-event-group-card__meta-item\" *ngIf=\"event?.timezone\">\r\n <dd class=\"ieeesa-event-group-card__timezone\">{{ event?.timezone }}</dd>\r\n </div>\r\n </dl>\r\n\r\n <!-- Meeting-list show/hide toggle labeled with open-for-attendance count (Req 6.5, 6.6). -->\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-event-group-card__meeting-toggle\"\r\n [attr.aria-expanded]=\"isMeetingListOpen\"\r\n [attr.aria-label]=\"constants?.eventGroupCard?.ariaLabel?.meetingListToggle ?? 'Show or hide the meeting list for this event'\"\r\n (click)=\"onToggleMeetingList()\"\r\n >\r\n {{ meetingListToggleLabel }}\r\n </button>\r\n\r\n <!-- Meeting list + per-card paginator, shown only when the toggle is open (Req 6.7, 6.8). -->\r\n <div *ngIf=\"isMeetingListOpen\" class=\"ieeesa-event-group-card__meetings\">\r\n <ieeesa-meeting-attendance-row\r\n *ngFor=\"let meeting of pagedMeetings; trackBy: trackByMeetingId\"\r\n [meeting]=\"meeting\"\r\n [attendanceState]=\"resolveAttendanceState(meeting)\"\r\n [isInFlight]=\"resolveIsInFlight(meeting)\"\r\n [permissions]=\"permissions\"\r\n (openMeeting)=\"onOpenMeeting($event)\"\r\n (logAttendance)=\"onLogAttendance($event)\"\r\n (leaveMeeting)=\"onLeaveMeeting($event)\"\r\n ></ieeesa-meeting-attendance-row>\r\n\r\n <div\r\n class=\"ieeesa-event-group-card__paginator\"\r\n [attr.aria-label]=\"constants?.eventGroupCard?.ariaLabel?.meetingListToggle ?? 'Meeting list pagination'\"\r\n >\r\n <!-- Range + total count label from constants.json (Req 6.8). -->\r\n <span class=\"ieeesa-event-group-card__paginator-range\">\r\n {{ rangeLabel }}\r\n </span>\r\n\r\n <!-- Presentation paginator emitting pageChange({ pageIndex, pageSize }) (Req 6.9, 3.3). -->\r\n <mat-paginator\r\n class=\"ieeesa-event-group-card__paginator-control\"\r\n [pageIndex]=\"pageIndex\"\r\n [pageSize]=\"pageSize\"\r\n [length]=\"totalMeetings\"\r\n [hidePageSize]=\"true\"\r\n (page)=\"onPageChange($event)\"\r\n ></mat-paginator>\r\n </div>\r\n </div>\r\n</article>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-event-group-card{display:flex;flex-direction:column;gap:12px;padding:16px;border:1px solid #d7d6d6;border-radius:8px;background-color:#fff}.ieeesa-event-group-card__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.ieeesa-event-group-card__heading{display:flex;flex-direction:column;gap:4px;min-width:0}.ieeesa-event-group-card__status{display:inline-flex;align-items:center;align-self:flex-start;padding:4px 12px;border-radius:16px;font-size:.75rem;color:#00629b;background-color:#f0f5f9}.ieeesa-event-group-card__title{margin:0;font-size:1.125rem;color:#000}.ieeesa-event-group-card__day-indicator{font-size:.8125rem;color:#939094}.ieeesa-event-group-card__view-event{flex-shrink:0;padding:8px 16px;border:1px solid #00629b;border-radius:4px;background-color:#fff;font-size:.875rem;color:#00629b;cursor:pointer}.ieeesa-event-group-card__meta{display:flex;flex-wrap:wrap;gap:4px 24px;margin:0}.ieeesa-event-group-card__meta-item{display:flex;flex-direction:column;gap:4px}.ieeesa-event-group-card__meeting-count,.ieeesa-event-group-card__dates,.ieeesa-event-group-card__timezone{margin:0;font-size:.875rem;color:#000}.ieeesa-event-group-card__timezone{color:#939094}.ieeesa-event-group-card__meeting-toggle{align-self:flex-start;padding:8px 0;border:0;background:none;text-align:left;text-decoration:underline;font-size:.875rem;color:#00629b;cursor:pointer}.ieeesa-event-group-card__meetings{display:flex;flex-direction:column;border-top:1px solid #d7d6d6}.ieeesa-event-group-card__paginator{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding-top:8px}.ieeesa-event-group-card__paginator-range{font-size:.8125rem;color:#939094}.ieeesa-event-group-card--mobile .ieeesa-event-group-card__header{flex-direction:column;align-items:stretch}.ieeesa-event-group-card--mobile .ieeesa-event-group-card__view-event{align-self:stretch}.ieeesa-event-group-card--mobile .ieeesa-event-group-card__paginator{flex-direction:column;align-items:stretch}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i2.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: MeetingAttendanceRowComponent, selector: "ieeesa-meeting-attendance-row", inputs: ["meeting", "attendanceState", "isInFlight", "permissions"], outputs: ["openMeeting", "logAttendance", "leaveMeeting"] }], encapsulation: i0.ViewEncapsulation.None }); }
688
+ }
689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EventGroupCardComponent, decorators: [{
690
+ type: Component,
691
+ args: [{ selector: 'ieeesa-event-group-card', standalone: true, imports: [CommonModule, MatPaginatorModule, MeetingAttendanceRowComponent], encapsulation: ViewEncapsulation.None, template: "<article\r\n class=\"ieeesa-event-group-card\"\r\n [class.ieeesa-event-group-card--mobile]=\"isMobileView\"\r\n>\r\n <header class=\"ieeesa-event-group-card__header\">\r\n <div class=\"ieeesa-event-group-card__heading\">\r\n <!-- Status badge (Req 6.1). -->\r\n <span\r\n *ngIf=\"event?.status\"\r\n class=\"ieeesa-event-group-card__status\"\r\n >\r\n {{ event?.status }}\r\n </span>\r\n\r\n <!-- Event title (Req 6.1). -->\r\n <h3 class=\"ieeesa-event-group-card__title\">{{ event?.title }}</h3>\r\n\r\n <!-- Day indicator (Req 6.1). -->\r\n <span\r\n *ngIf=\"event?.dayIndicator\"\r\n class=\"ieeesa-event-group-card__day-indicator\"\r\n >\r\n {{ event?.dayIndicator }}\r\n </span>\r\n </div>\r\n\r\n <!-- View Event action (Req 6.3, 6.4). -->\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-event-group-card__view-event\"\r\n [attr.aria-label]=\"constants?.eventGroupCard?.ariaLabel?.viewEvent ?? 'View event details'\"\r\n (click)=\"onViewEvent()\"\r\n >\r\n {{ constants?.eventGroupCard?.viewEventLabel ?? 'View Event' }}\r\n </button>\r\n </header>\r\n\r\n <dl class=\"ieeesa-event-group-card__meta\">\r\n <!-- Meeting-count summary sub-line (Req 6.1). -->\r\n <div class=\"ieeesa-event-group-card__meta-item\">\r\n <dd class=\"ieeesa-event-group-card__meeting-count\">\r\n {{ meetingCountSummary }}\r\n </dd>\r\n </div>\r\n\r\n <!-- Start / end date (Req 6.2). -->\r\n <div class=\"ieeesa-event-group-card__meta-item\">\r\n <dd class=\"ieeesa-event-group-card__dates\">\r\n {{ formattedStartDate }}<ng-container *ngIf=\"formattedEndDate\">\r\n &ndash; {{ formattedEndDate }}</ng-container>\r\n </dd>\r\n </div>\r\n\r\n <!-- Timezone (Req 6.2). -->\r\n <div class=\"ieeesa-event-group-card__meta-item\" *ngIf=\"event?.timezone\">\r\n <dd class=\"ieeesa-event-group-card__timezone\">{{ event?.timezone }}</dd>\r\n </div>\r\n </dl>\r\n\r\n <!-- Meeting-list show/hide toggle labeled with open-for-attendance count (Req 6.5, 6.6). -->\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-event-group-card__meeting-toggle\"\r\n [attr.aria-expanded]=\"isMeetingListOpen\"\r\n [attr.aria-label]=\"constants?.eventGroupCard?.ariaLabel?.meetingListToggle ?? 'Show or hide the meeting list for this event'\"\r\n (click)=\"onToggleMeetingList()\"\r\n >\r\n {{ meetingListToggleLabel }}\r\n </button>\r\n\r\n <!-- Meeting list + per-card paginator, shown only when the toggle is open (Req 6.7, 6.8). -->\r\n <div *ngIf=\"isMeetingListOpen\" class=\"ieeesa-event-group-card__meetings\">\r\n <ieeesa-meeting-attendance-row\r\n *ngFor=\"let meeting of pagedMeetings; trackBy: trackByMeetingId\"\r\n [meeting]=\"meeting\"\r\n [attendanceState]=\"resolveAttendanceState(meeting)\"\r\n [isInFlight]=\"resolveIsInFlight(meeting)\"\r\n [permissions]=\"permissions\"\r\n (openMeeting)=\"onOpenMeeting($event)\"\r\n (logAttendance)=\"onLogAttendance($event)\"\r\n (leaveMeeting)=\"onLeaveMeeting($event)\"\r\n ></ieeesa-meeting-attendance-row>\r\n\r\n <div\r\n class=\"ieeesa-event-group-card__paginator\"\r\n [attr.aria-label]=\"constants?.eventGroupCard?.ariaLabel?.meetingListToggle ?? 'Meeting list pagination'\"\r\n >\r\n <!-- Range + total count label from constants.json (Req 6.8). -->\r\n <span class=\"ieeesa-event-group-card__paginator-range\">\r\n {{ rangeLabel }}\r\n </span>\r\n\r\n <!-- Presentation paginator emitting pageChange({ pageIndex, pageSize }) (Req 6.9, 3.3). -->\r\n <mat-paginator\r\n class=\"ieeesa-event-group-card__paginator-control\"\r\n [pageIndex]=\"pageIndex\"\r\n [pageSize]=\"pageSize\"\r\n [length]=\"totalMeetings\"\r\n [hidePageSize]=\"true\"\r\n (page)=\"onPageChange($event)\"\r\n ></mat-paginator>\r\n </div>\r\n </div>\r\n</article>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-event-group-card{display:flex;flex-direction:column;gap:12px;padding:16px;border:1px solid #d7d6d6;border-radius:8px;background-color:#fff}.ieeesa-event-group-card__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.ieeesa-event-group-card__heading{display:flex;flex-direction:column;gap:4px;min-width:0}.ieeesa-event-group-card__status{display:inline-flex;align-items:center;align-self:flex-start;padding:4px 12px;border-radius:16px;font-size:.75rem;color:#00629b;background-color:#f0f5f9}.ieeesa-event-group-card__title{margin:0;font-size:1.125rem;color:#000}.ieeesa-event-group-card__day-indicator{font-size:.8125rem;color:#939094}.ieeesa-event-group-card__view-event{flex-shrink:0;padding:8px 16px;border:1px solid #00629b;border-radius:4px;background-color:#fff;font-size:.875rem;color:#00629b;cursor:pointer}.ieeesa-event-group-card__meta{display:flex;flex-wrap:wrap;gap:4px 24px;margin:0}.ieeesa-event-group-card__meta-item{display:flex;flex-direction:column;gap:4px}.ieeesa-event-group-card__meeting-count,.ieeesa-event-group-card__dates,.ieeesa-event-group-card__timezone{margin:0;font-size:.875rem;color:#000}.ieeesa-event-group-card__timezone{color:#939094}.ieeesa-event-group-card__meeting-toggle{align-self:flex-start;padding:8px 0;border:0;background:none;text-align:left;text-decoration:underline;font-size:.875rem;color:#00629b;cursor:pointer}.ieeesa-event-group-card__meetings{display:flex;flex-direction:column;border-top:1px solid #d7d6d6}.ieeesa-event-group-card__paginator{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding-top:8px}.ieeesa-event-group-card__paginator-range{font-size:.8125rem;color:#939094}.ieeesa-event-group-card--mobile .ieeesa-event-group-card__header{flex-direction:column;align-items:stretch}.ieeesa-event-group-card--mobile .ieeesa-event-group-card__view-event{align-self:stretch}.ieeesa-event-group-card--mobile .ieeesa-event-group-card__paginator{flex-direction:column;align-items:stretch}\n"] }]
692
+ }], propDecorators: { event: [{
693
+ type: Input
694
+ }], permissions: [{
695
+ type: Input
696
+ }], attendanceStates: [{
697
+ type: Input
698
+ }], inFlightMeetingIds: [{
699
+ type: Input
700
+ }], isMobileView: [{
701
+ type: Input
702
+ }], viewEvent: [{
703
+ type: Output
704
+ }], openMeeting: [{
705
+ type: Output
706
+ }], logAttendance: [{
707
+ type: Output
708
+ }], leaveMeeting: [{
709
+ type: Output
710
+ }], pageChange: [{
711
+ type: Output
712
+ }] } });
713
+
714
+ /**
715
+ * Upcoming_Meetings_Events renders the "Upcoming Meetings & Events" dashboard
716
+ * section: a section title and "View All" link, a collapse/expand toggle that
717
+ * starts expanded, and one {@link EventGroupCardComponent} per upcoming event.
718
+ *
719
+ * The section is driven by its `sectionState` input: it shows the Loader while
720
+ * `LOADING`, the event-group cards while `LOADED`, the empty-state message while
721
+ * `EMPTY`, and the error message while `ERROR` — the four regions are mutually
722
+ * exclusive (Req 13.1, 13.2, 13.3, 13.5). The component is purely
723
+ * presentational: "View All" emits `viewAll` (Req 5.1, 5.2), the collapse toggle
724
+ * flips `isExpanded` and the card-list visibility while exposing
725
+ * `[attr.aria-expanded]` (Req 5.3, 5.4, 14.3), and each card is rendered via
726
+ * `*ngFor` with {@link trackByEventId} to preserve input order (Req 5.5, 5.6,
727
+ * 14.4). Card outputs (`viewEvent`/`openMeeting`/`logAttendance`/`leaveMeeting`)
728
+ * are bubbled upward unchanged, and each card's `pageChange` is mapped to
729
+ * `meetingPageChange` tagged with the originating event id (Req 6.9).
730
+ * @export
731
+ * @class UpcomingMeetingsEventsComponent
732
+ */
733
+ class UpcomingMeetingsEventsComponent {
734
+ constructor() {
735
+ /** User-facing strings sourced from `constants.json`. */
736
+ this.constants = constants$1;
737
+ /** Enum reference for template comparisons against `sectionState`. */
738
+ this.sectionStates = DashboardSectionState;
739
+ /** The upcoming events rendered as event-group cards (Req 5.5, 5.6). */
740
+ this.events = [];
741
+ /** The load/empty/error status driving the section's mutually exclusive regions. */
742
+ this.sectionState = DashboardSectionState.LOADING;
743
+ /** Host permissions gating the per-row log-attendance / leave-meeting buttons. */
744
+ this.permissions = {
745
+ canLogAttendance: false,
746
+ canLeaveMeeting: false,
747
+ };
748
+ /** Map of meeting id to current attendance state, passed down to each card. */
749
+ this.attendanceStates = {};
750
+ /** Set of meeting ids with an attendance action awaiting resolution. */
751
+ this.inFlightMeetingIds = new Set();
752
+ /** Whether the host has determined the viewport is at/below the mobile breakpoint. */
753
+ this.isMobileView = false;
754
+ /** Emits when the "View All" link is activated (Req 5.2). */
755
+ this.viewAll = new EventEmitter();
756
+ /** Bubbles the event id when a card's "View Event" button is activated (Req 6.4). */
757
+ this.viewEvent = new EventEmitter();
758
+ /** Bubbles the meeting id when a card's meeting-name link is activated (Req 7.4). */
759
+ this.openMeeting = new EventEmitter();
760
+ /** Bubbles the meeting id when a card requests logging attendance (Req 7.7). */
761
+ this.logAttendance = new EventEmitter();
762
+ /** Bubbles the meeting id when a card requests leaving the meeting (Req 7.8). */
763
+ this.leaveMeeting = new EventEmitter();
764
+ /** Emits the requested page tagged with its event id when a card paginates (Req 6.9). */
765
+ this.meetingPageChange = new EventEmitter();
766
+ /** Whether the section's card list is currently expanded; starts collapsed. */
767
+ this.isExpanded = false;
768
+ }
769
+ /**
770
+ * `trackBy` for the event-group-card `*ngFor`, keyed by the stable event id so
771
+ * Angular renders exactly one card per event in input order (Req 5.5, 5.6, 14.4).
772
+ * @param {number} index - The iteration index (fallback key).
773
+ * @param {UpcomingEvent} event - The event for this card.
774
+ * @return {string} The stable track key (event id).
775
+ * @memberof UpcomingMeetingsEventsComponent
776
+ */
777
+ trackByEventId(index, event) {
778
+ return event?.eventId ?? `${index}`;
779
+ }
780
+ /**
781
+ * Toggles the section's expanded/collapsed state, inverting the card-list
782
+ * visibility and the exposed `aria-expanded` value (Req 5.4, 14.3).
783
+ * @memberof UpcomingMeetingsEventsComponent
784
+ */
785
+ onToggleExpanded() {
786
+ this.isExpanded = !this.isExpanded;
787
+ }
788
+ /**
789
+ * Handles the "View All" link, emitting the `viewAll` intent to the host (Req 5.2).
790
+ * @memberof UpcomingMeetingsEventsComponent
791
+ */
792
+ onViewAll() {
793
+ this.viewAll.emit();
794
+ }
795
+ /**
796
+ * Bubbles a card's "View Event" activation upward (Req 6.4).
797
+ * @param {string} eventId - The event id emitted by the card.
798
+ * @memberof UpcomingMeetingsEventsComponent
799
+ */
800
+ onViewEvent(eventId) {
801
+ this.viewEvent.emit(eventId);
802
+ }
803
+ /**
804
+ * Bubbles a card's meeting-name link activation upward (Req 7.4).
805
+ * @param {string} meetingId - The meeting id emitted by the card.
806
+ * @memberof UpcomingMeetingsEventsComponent
807
+ */
808
+ onOpenMeeting(meetingId) {
809
+ this.openMeeting.emit(meetingId);
810
+ }
811
+ /**
812
+ * Bubbles a card's log-attendance request upward (Req 7.7).
813
+ * @param {string} meetingId - The meeting id emitted by the card.
814
+ * @memberof UpcomingMeetingsEventsComponent
815
+ */
816
+ onLogAttendance(meetingId) {
817
+ this.logAttendance.emit(meetingId);
818
+ }
819
+ /**
820
+ * Bubbles a card's leave-meeting request upward (Req 7.8).
821
+ * @param {string} meetingId - The meeting id emitted by the card.
822
+ * @memberof UpcomingMeetingsEventsComponent
823
+ */
824
+ onLeaveMeeting(meetingId) {
825
+ this.leaveMeeting.emit(meetingId);
826
+ }
827
+ /**
828
+ * Maps a card's `pageChange` into a `meetingPageChange` tagged with the
829
+ * originating event id so the host can page the correct event (Req 6.9).
830
+ * @param {string} eventId - The id of the event whose card paginated.
831
+ * @param {PageChange} page - The requested page from the card paginator.
832
+ * @memberof UpcomingMeetingsEventsComponent
833
+ */
834
+ onMeetingPageChange(eventId, page) {
835
+ this.meetingPageChange.emit({ eventId, ...page });
836
+ }
837
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UpcomingMeetingsEventsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
838
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: UpcomingMeetingsEventsComponent, isStandalone: true, selector: "ieeesa-upcoming-meetings-events", inputs: { events: "events", sectionState: "sectionState", permissions: "permissions", attendanceStates: "attendanceStates", inFlightMeetingIds: "inFlightMeetingIds", isMobileView: "isMobileView" }, outputs: { viewAll: "viewAll", viewEvent: "viewEvent", openMeeting: "openMeeting", logAttendance: "logAttendance", leaveMeeting: "leaveMeeting", meetingPageChange: "meetingPageChange" }, ngImport: i0, template: "<section\r\n class=\"ieeesa-upcoming-meetings-events\"\r\n [class.ieeesa-upcoming-meetings-events--mobile]=\"isMobileView\"\r\n>\r\n <header class=\"ieeesa-upcoming-meetings-events__header\">\r\n <!-- Section title (Req 5.1). -->\r\n <div class=\"ieeesa-upcoming-meetings-events__heading\">\r\n <h2 class=\"ieeesa-upcoming-meetings-events__title\">\r\n {{ constants?.upcomingSection?.title ?? 'Upcoming Meetings & Events' }}\r\n </h2>\r\n </div>\r\n\r\n <!-- View All link + Expand/Collapse toggle, matching the Your Groups card\r\n header (Req 5.1, 5.2, 5.3, 5.4, 14.3). -->\r\n <div class=\"ieeesa-upcoming-meetings-events__actions\">\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-upcoming-meetings-events__view-all\"\r\n [attr.aria-label]=\"constants?.upcomingSection?.ariaLabel?.viewAll ?? 'View all upcoming meetings and events'\"\r\n (click)=\"onViewAll()\"\r\n >\r\n {{ constants?.upcomingSection?.viewAllLabel ?? 'View All' }}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-upcoming-meetings-events__toggle\"\r\n [attr.aria-expanded]=\"isExpanded\"\r\n [attr.aria-label]=\"constants?.upcomingSection?.ariaLabel?.toggle ?? 'Collapse or expand upcoming meetings and events'\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <span>{{ isExpanded ? (constants?.upcomingSection?.collapseLabel ?? 'Collapse') : (constants?.upcomingSection?.expandLabel ?? 'Expand') }}</span>\r\n <i\r\n class=\"fa-solid\"\r\n [ngClass]=\"isExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <!-- Card list, shown only while expanded (Req 5.4). -->\r\n <div\r\n *ngIf=\"isExpanded\"\r\n class=\"ieeesa-upcoming-meetings-events__body\"\r\n >\r\n <!-- Loader region (Req 13.1). -->\r\n <div\r\n *ngIf=\"sectionState === sectionStates.LOADING\"\r\n class=\"ieeesa-upcoming-meetings-events__loader\"\r\n >\r\n <ieeesa-loader></ieeesa-loader>\r\n </div>\r\n\r\n <!-- Content region: one card per event preserving input order (Req 5.5, 5.6, 13.2). -->\r\n <div\r\n *ngIf=\"sectionState === sectionStates.LOADED\"\r\n class=\"ieeesa-upcoming-meetings-events__cards\"\r\n >\r\n <ieeesa-event-group-card\r\n *ngFor=\"let event of events; trackBy: trackByEventId\"\r\n [event]=\"event\"\r\n [permissions]=\"permissions\"\r\n [attendanceStates]=\"attendanceStates\"\r\n [inFlightMeetingIds]=\"inFlightMeetingIds\"\r\n [isMobileView]=\"isMobileView\"\r\n (viewEvent)=\"onViewEvent($event)\"\r\n (openMeeting)=\"onOpenMeeting($event)\"\r\n (logAttendance)=\"onLogAttendance($event)\"\r\n (leaveMeeting)=\"onLeaveMeeting($event)\"\r\n (pageChange)=\"onMeetingPageChange(event.eventId, $event)\"\r\n ></ieeesa-event-group-card>\r\n </div>\r\n\r\n <!-- Empty-state region (Req 13.3). -->\r\n <p\r\n *ngIf=\"sectionState === sectionStates.EMPTY\"\r\n class=\"ieeesa-upcoming-meetings-events__empty\"\r\n >\r\n {{ constants?.upcomingSection?.emptyMessage ?? 'You have no upcoming meetings or events.' }}\r\n </p>\r\n\r\n <!-- Error region (Req 13.5). -->\r\n <p\r\n *ngIf=\"sectionState === sectionStates.ERROR\"\r\n class=\"ieeesa-upcoming-meetings-events__error\"\r\n role=\"alert\"\r\n >\r\n {{ constants?.upcomingSection?.errorMessage ?? 'Unable to load upcoming meetings and events. Please try again.' }}\r\n </p>\r\n </div>\r\n</section>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-upcoming-meetings-events{display:flex;flex-direction:column;gap:16px;background-color:#fff;border-radius:12px;box-shadow:0 1px 2px #0003;border:1px solid #e2e8f0;padding:20px 24px}.ieeesa-upcoming-meetings-events__header{display:flex;align-items:center;justify-content:space-between;gap:16px}.ieeesa-upcoming-meetings-events__heading{display:flex;min-width:0}.ieeesa-upcoming-meetings-events__title{margin:0;font-family:Calibri Bold;font-weight:700;font-size:1.125rem;color:#333436}.ieeesa-upcoming-meetings-events__actions{display:flex;align-items:center;gap:16px}.ieeesa-upcoming-meetings-events__view-all{flex-shrink:0;background:none;border:none;padding:0;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-upcoming-meetings-events__view-all:hover{text-decoration:underline}.ieeesa-upcoming-meetings-events__toggle{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border:1px solid #dbe2eb;border-radius:8px;background-color:#fff;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-upcoming-meetings-events__toggle:hover{border-color:#00629b}.ieeesa-upcoming-meetings-events__toggle i{font-size:.75rem}.ieeesa-upcoming-meetings-events__body{display:flex;flex-direction:column}.ieeesa-upcoming-meetings-events__loader{display:flex;align-items:center;justify-content:center;padding:24px}.ieeesa-upcoming-meetings-events__cards{display:flex;flex-direction:column;gap:16px}.ieeesa-upcoming-meetings-events__empty,.ieeesa-upcoming-meetings-events__error{margin:0;padding:16px;font-size:.875rem;color:#939094}.ieeesa-upcoming-meetings-events__error{color:#ba0c2f}.ieeesa-upcoming-meetings-events--mobile .ieeesa-upcoming-meetings-events__header{flex-wrap:wrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoaderComponent, selector: "ieeesa-loader", inputs: ["diameter"] }, { kind: "component", type: EventGroupCardComponent, selector: "ieeesa-event-group-card", inputs: ["event", "permissions", "attendanceStates", "inFlightMeetingIds", "isMobileView"], outputs: ["viewEvent", "openMeeting", "logAttendance", "leaveMeeting", "pageChange"] }], encapsulation: i0.ViewEncapsulation.None }); }
839
+ }
840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UpcomingMeetingsEventsComponent, decorators: [{
841
+ type: Component,
842
+ args: [{ selector: 'ieeesa-upcoming-meetings-events', standalone: true, imports: [CommonModule, LoaderComponent, EventGroupCardComponent], encapsulation: ViewEncapsulation.None, template: "<section\r\n class=\"ieeesa-upcoming-meetings-events\"\r\n [class.ieeesa-upcoming-meetings-events--mobile]=\"isMobileView\"\r\n>\r\n <header class=\"ieeesa-upcoming-meetings-events__header\">\r\n <!-- Section title (Req 5.1). -->\r\n <div class=\"ieeesa-upcoming-meetings-events__heading\">\r\n <h2 class=\"ieeesa-upcoming-meetings-events__title\">\r\n {{ constants?.upcomingSection?.title ?? 'Upcoming Meetings & Events' }}\r\n </h2>\r\n </div>\r\n\r\n <!-- View All link + Expand/Collapse toggle, matching the Your Groups card\r\n header (Req 5.1, 5.2, 5.3, 5.4, 14.3). -->\r\n <div class=\"ieeesa-upcoming-meetings-events__actions\">\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-upcoming-meetings-events__view-all\"\r\n [attr.aria-label]=\"constants?.upcomingSection?.ariaLabel?.viewAll ?? 'View all upcoming meetings and events'\"\r\n (click)=\"onViewAll()\"\r\n >\r\n {{ constants?.upcomingSection?.viewAllLabel ?? 'View All' }}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-upcoming-meetings-events__toggle\"\r\n [attr.aria-expanded]=\"isExpanded\"\r\n [attr.aria-label]=\"constants?.upcomingSection?.ariaLabel?.toggle ?? 'Collapse or expand upcoming meetings and events'\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <span>{{ isExpanded ? (constants?.upcomingSection?.collapseLabel ?? 'Collapse') : (constants?.upcomingSection?.expandLabel ?? 'Expand') }}</span>\r\n <i\r\n class=\"fa-solid\"\r\n [ngClass]=\"isExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <!-- Card list, shown only while expanded (Req 5.4). -->\r\n <div\r\n *ngIf=\"isExpanded\"\r\n class=\"ieeesa-upcoming-meetings-events__body\"\r\n >\r\n <!-- Loader region (Req 13.1). -->\r\n <div\r\n *ngIf=\"sectionState === sectionStates.LOADING\"\r\n class=\"ieeesa-upcoming-meetings-events__loader\"\r\n >\r\n <ieeesa-loader></ieeesa-loader>\r\n </div>\r\n\r\n <!-- Content region: one card per event preserving input order (Req 5.5, 5.6, 13.2). -->\r\n <div\r\n *ngIf=\"sectionState === sectionStates.LOADED\"\r\n class=\"ieeesa-upcoming-meetings-events__cards\"\r\n >\r\n <ieeesa-event-group-card\r\n *ngFor=\"let event of events; trackBy: trackByEventId\"\r\n [event]=\"event\"\r\n [permissions]=\"permissions\"\r\n [attendanceStates]=\"attendanceStates\"\r\n [inFlightMeetingIds]=\"inFlightMeetingIds\"\r\n [isMobileView]=\"isMobileView\"\r\n (viewEvent)=\"onViewEvent($event)\"\r\n (openMeeting)=\"onOpenMeeting($event)\"\r\n (logAttendance)=\"onLogAttendance($event)\"\r\n (leaveMeeting)=\"onLeaveMeeting($event)\"\r\n (pageChange)=\"onMeetingPageChange(event.eventId, $event)\"\r\n ></ieeesa-event-group-card>\r\n </div>\r\n\r\n <!-- Empty-state region (Req 13.3). -->\r\n <p\r\n *ngIf=\"sectionState === sectionStates.EMPTY\"\r\n class=\"ieeesa-upcoming-meetings-events__empty\"\r\n >\r\n {{ constants?.upcomingSection?.emptyMessage ?? 'You have no upcoming meetings or events.' }}\r\n </p>\r\n\r\n <!-- Error region (Req 13.5). -->\r\n <p\r\n *ngIf=\"sectionState === sectionStates.ERROR\"\r\n class=\"ieeesa-upcoming-meetings-events__error\"\r\n role=\"alert\"\r\n >\r\n {{ constants?.upcomingSection?.errorMessage ?? 'Unable to load upcoming meetings and events. Please try again.' }}\r\n </p>\r\n </div>\r\n</section>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-upcoming-meetings-events{display:flex;flex-direction:column;gap:16px;background-color:#fff;border-radius:12px;box-shadow:0 1px 2px #0003;border:1px solid #e2e8f0;padding:20px 24px}.ieeesa-upcoming-meetings-events__header{display:flex;align-items:center;justify-content:space-between;gap:16px}.ieeesa-upcoming-meetings-events__heading{display:flex;min-width:0}.ieeesa-upcoming-meetings-events__title{margin:0;font-family:Calibri Bold;font-weight:700;font-size:1.125rem;color:#333436}.ieeesa-upcoming-meetings-events__actions{display:flex;align-items:center;gap:16px}.ieeesa-upcoming-meetings-events__view-all{flex-shrink:0;background:none;border:none;padding:0;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-upcoming-meetings-events__view-all:hover{text-decoration:underline}.ieeesa-upcoming-meetings-events__toggle{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border:1px solid #dbe2eb;border-radius:8px;background-color:#fff;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-upcoming-meetings-events__toggle:hover{border-color:#00629b}.ieeesa-upcoming-meetings-events__toggle i{font-size:.75rem}.ieeesa-upcoming-meetings-events__body{display:flex;flex-direction:column}.ieeesa-upcoming-meetings-events__loader{display:flex;align-items:center;justify-content:center;padding:24px}.ieeesa-upcoming-meetings-events__cards{display:flex;flex-direction:column;gap:16px}.ieeesa-upcoming-meetings-events__empty,.ieeesa-upcoming-meetings-events__error{margin:0;padding:16px;font-size:.875rem;color:#939094}.ieeesa-upcoming-meetings-events__error{color:#ba0c2f}.ieeesa-upcoming-meetings-events--mobile .ieeesa-upcoming-meetings-events__header{flex-wrap:wrap}\n"] }]
843
+ }], propDecorators: { events: [{
844
+ type: Input
845
+ }], sectionState: [{
846
+ type: Input
847
+ }], permissions: [{
848
+ type: Input
849
+ }], attendanceStates: [{
850
+ type: Input
851
+ }], inFlightMeetingIds: [{
852
+ type: Input
853
+ }], isMobileView: [{
854
+ type: Input
855
+ }], viewAll: [{
856
+ type: Output
857
+ }], viewEvent: [{
858
+ type: Output
859
+ }], openMeeting: [{
860
+ type: Output
861
+ }], logAttendance: [{
862
+ type: Output
863
+ }], leaveMeeting: [{
864
+ type: Output
865
+ }], meetingPageChange: [{
866
+ type: Output
867
+ }] } });
868
+
869
+ /**
870
+ * Identifies which dashboard section a "Jump to" shortcut targets, emitted via
871
+ * {@link DashboardWelcomeHeaderComponent.shortcutSelected} for the host/container
872
+ * to scroll to or navigate.
873
+ */
874
+ // eslint-disable-next-line no-unused-vars
875
+ var DashboardJumpTarget;
876
+ (function (DashboardJumpTarget) {
877
+ // eslint-disable-next-line no-unused-vars
878
+ DashboardJumpTarget["MEETINGS"] = "MEETINGS";
879
+ // eslint-disable-next-line no-unused-vars
880
+ DashboardJumpTarget["GROUPS"] = "GROUPS";
881
+ })(DashboardJumpTarget || (DashboardJumpTarget = {}));
882
+ /**
883
+ * Welcome_Header renders the personalized greeting and the "Jump to" shortcut
884
+ * control at the top of the dashboard.
885
+ *
886
+ * The greeting is composed from the greeting label in `constants.json` and the
887
+ * supplied `userName`, falling back to the configured fallback greeting when the
888
+ * name is empty or undefined. The "Jump to" control shows one circular icon per
889
+ * dashboard section (Upcoming Meetings & Events, Your Groups); hovering or
890
+ * focusing an icon expands it into a pill with the section label and a count
891
+ * badge (the counts are supplied by the host via `meetingsCount` /
892
+ * `groupsCount`). Activating a shortcut emits {@link shortcutSelected} with the
893
+ * target section for the host to act on. Purely presentational — no API work.
894
+ * @export
895
+ * @class DashboardWelcomeHeaderComponent
896
+ */
897
+ class DashboardWelcomeHeaderComponent {
898
+ constructor() {
899
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
900
+ this.constants = constants$1;
901
+ /** User-facing strings sourced from `constants.json`. */
902
+ this.texts = this.constants?.welcomeHeader;
903
+ /** Enum reference for template comparisons. */
904
+ this.jumpTarget = DashboardJumpTarget;
905
+ this.userNameValue = '';
906
+ this.meetingsCountValue = 0;
907
+ this.groupsCountValue = 0;
908
+ /** Emits the selected "Jump to" target for the host to act on. */
909
+ this.shortcutSelected = new EventEmitter();
910
+ /** The jump shortcuts rendered in the control, rebuilt when counts change. */
911
+ this.shortcuts = this.buildShortcutList();
912
+ }
913
+ /**
914
+ * The signed-in user's display name. Drives the personalized greeting; when
915
+ * empty or undefined the greeting falls back to the configured fallback text.
916
+ * @memberof DashboardWelcomeHeaderComponent
917
+ */
918
+ set userName(value) {
919
+ this.userNameValue = value ?? '';
920
+ }
921
+ get userName() {
922
+ return this.userNameValue;
923
+ }
924
+ /** Count shown in the Upcoming Meetings & Events shortcut badge. */
925
+ set meetingsCount(value) {
926
+ this.meetingsCountValue = value ?? 0;
927
+ this.buildShortcuts();
928
+ }
929
+ get meetingsCount() {
930
+ return this.meetingsCountValue;
931
+ }
932
+ /** Count shown in the Your Groups shortcut badge. */
933
+ set groupsCount(value) {
934
+ this.groupsCountValue = value ?? 0;
935
+ this.buildShortcuts();
936
+ }
937
+ get groupsCount() {
938
+ return this.groupsCountValue;
939
+ }
940
+ /**
941
+ * The personalized greeting: the greeting label plus the user's name when
942
+ * present, otherwise the configured fallback greeting.
943
+ * @readonly
944
+ * @memberof DashboardWelcomeHeaderComponent
945
+ */
946
+ get greeting() {
947
+ const name = this.userName?.trim();
948
+ return name
949
+ ? `${this.texts?.greeting}${name}!`
950
+ : `${this.texts?.fallbackGreeting}!`;
951
+ }
952
+ /**
953
+ * Emits the chosen shortcut's target for the host to scroll/navigate to.
954
+ * @param {DashboardJumpTarget} target - The selected section.
955
+ * @memberof DashboardWelcomeHeaderComponent
956
+ */
957
+ onShortcutClick(target) {
958
+ this.shortcutSelected.emit(target);
959
+ }
960
+ /**
961
+ * TrackBy for the shortcut list.
962
+ * @param {number} _index
963
+ * @param {JumpShortcut} shortcut
964
+ * @return {string}
965
+ * @memberof DashboardWelcomeHeaderComponent
966
+ */
967
+ trackByTarget(_index, shortcut) {
968
+ return shortcut.target;
969
+ }
970
+ /** Rebuilds the shortcut list so the template reflects the latest counts. */
971
+ buildShortcuts() {
972
+ this.shortcuts = this.buildShortcutList();
973
+ }
974
+ /**
975
+ * Builds the shortcut view models from `constants.json` and the current
976
+ * counts.
977
+ * @return {JumpShortcut[]}
978
+ * @memberof DashboardWelcomeHeaderComponent
979
+ */
980
+ buildShortcutList() {
981
+ const shortcutTexts = this.constants?.welcomeHeader?.shortcuts;
982
+ return [
983
+ {
984
+ target: DashboardJumpTarget.MEETINGS,
985
+ label: shortcutTexts?.meetings?.label,
986
+ iconUrl: shortcutTexts?.meetings?.iconUrl,
987
+ ariaLabel: shortcutTexts?.meetings?.ariaLabel,
988
+ count: this.meetingsCountValue,
989
+ },
990
+ {
991
+ target: DashboardJumpTarget.GROUPS,
992
+ label: shortcutTexts?.groups?.label,
993
+ iconUrl: shortcutTexts?.groups?.iconUrl,
994
+ ariaLabel: shortcutTexts?.groups?.ariaLabel,
995
+ count: this.groupsCountValue,
996
+ },
997
+ ];
998
+ }
999
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardWelcomeHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1000
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DashboardWelcomeHeaderComponent, isStandalone: true, selector: "ieeesa-dashboard-welcome-header", inputs: { userName: "userName", meetingsCount: "meetingsCount", groupsCount: "groupsCount" }, outputs: { shortcutSelected: "shortcutSelected" }, ngImport: i0, template: "<div class=\"ieeesa-dashboard-welcome-header\">\r\n <!-- Greeting + helper line -->\r\n <div class=\"ieeesa-dashboard-welcome-header__intro\">\r\n <h1 class=\"ieeesa-dashboard-welcome-header__greeting m-0\">\r\n {{ greeting }}\r\n </h1>\r\n <p class=\"ieeesa-dashboard-welcome-header__helper-text m-0\">\r\n {{ texts?.helperText }}\r\n </p>\r\n </div>\r\n\r\n <!-- \"Jump to\" shortcuts: each icon expands on hover/focus into a pill with\r\n the section label and its count badge. -->\r\n <div class=\"ieeesa-dashboard-welcome-header__jump-to\">\r\n <span class=\"ieeesa-dashboard-welcome-header__jump-to-label\">\r\n {{ texts?.jumpToLabel }}\r\n </span>\r\n\r\n <button\r\n *ngFor=\"let shortcut of shortcuts; trackBy: trackByTarget\"\r\n type=\"button\"\r\n class=\"ieeesa-dashboard-welcome-header__shortcut\"\r\n [attr.aria-label]=\"shortcut.ariaLabel + ' (' + shortcut.count + ')'\"\r\n (click)=\"onShortcutClick(shortcut.target)\"\r\n >\r\n <img\r\n class=\"ieeesa-dashboard-welcome-header__shortcut-icon\"\r\n [src]=\"shortcut.iconUrl\"\r\n alt=\"\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"ieeesa-dashboard-welcome-header__shortcut-label\">\r\n {{ shortcut.label }}\r\n </span>\r\n <span class=\"ieeesa-dashboard-welcome-header__shortcut-count\">\r\n {{ shortcut.count }}\r\n </span>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-dashboard-welcome-header{display:flex;align-items:center;justify-content:flex-start;gap:10%;flex-wrap:wrap}.ieeesa-dashboard-welcome-header__intro{display:flex;flex-direction:column;gap:4px}.ieeesa-dashboard-welcome-header__greeting{font-family:Calibri Bold;font-weight:700;font-style:normal;font-size:18px;line-height:27px;letter-spacing:0px;color:#111}.ieeesa-dashboard-welcome-header__helper-text{font-family:Calibri Regular;font-weight:400;font-style:normal;font-size:12px;line-height:16.5px;letter-spacing:0px;color:#6a7282}.ieeesa-dashboard-welcome-header__jump-to{display:inline-flex;align-items:center;gap:20px;min-width:228px;width:-moz-fit-content;width:fit-content;height:60px;padding-left:18px;padding-right:18px;background-color:#fff;border-radius:10px;box-shadow:0 1px 2px #0003}.ieeesa-dashboard-welcome-header__jump-to-label{font-family:Calibri Bold;font-weight:700;font-size:.8125rem;letter-spacing:.03125em;text-transform:uppercase;color:#333436;white-space:nowrap}.ieeesa-dashboard-welcome-header__shortcut{display:inline-flex;align-items:center;justify-content:center;gap:0;width:40px;height:40px;padding:0;border:1.5px solid #D1D5DC;border-radius:20px;background-color:#fff;color:#00629b;cursor:pointer;overflow:hidden;transition:width .25s ease,padding .25s ease,gap .2s ease,background-color .2s ease,border-color .2s ease}.ieeesa-dashboard-welcome-header__shortcut:hover,.ieeesa-dashboard-welcome-header__shortcut:focus-visible{width:auto;gap:8px;padding:0 14px;border-color:#00629b;background-color:#eaf3f9;outline:none}.ieeesa-dashboard-welcome-header__shortcut-icon{flex:0 0 auto;width:20px;height:20px;display:block}.ieeesa-dashboard-welcome-header__shortcut-label{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#333436;transition:max-width .25s ease,opacity .2s ease}.ieeesa-dashboard-welcome-header__shortcut-count{display:inline-flex;align-items:center;justify-content:center;max-width:0;padding:0;opacity:0;overflow:hidden;border-radius:12px;background-color:#eaf3f9;color:#00629b;font-family:Calibri Bold;font-weight:700;font-size:.75rem;white-space:nowrap;transition:max-width .25s ease,opacity .2s ease,padding .2s ease}.ieeesa-dashboard-welcome-header__shortcut:hover .ieeesa-dashboard-welcome-header__shortcut-label,.ieeesa-dashboard-welcome-header__shortcut:focus-visible .ieeesa-dashboard-welcome-header__shortcut-label{max-width:240px;opacity:1}.ieeesa-dashboard-welcome-header__shortcut:hover .ieeesa-dashboard-welcome-header__shortcut-count,.ieeesa-dashboard-welcome-header__shortcut:focus-visible .ieeesa-dashboard-welcome-header__shortcut-count{max-width:48px;padding:2px 10px;opacity:1}@media (max-width: 767px){.ieeesa-dashboard-welcome-header{align-items:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], encapsulation: i0.ViewEncapsulation.None }); }
1001
+ }
1002
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardWelcomeHeaderComponent, decorators: [{
1003
+ type: Component,
1004
+ args: [{ selector: 'ieeesa-dashboard-welcome-header', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"ieeesa-dashboard-welcome-header\">\r\n <!-- Greeting + helper line -->\r\n <div class=\"ieeesa-dashboard-welcome-header__intro\">\r\n <h1 class=\"ieeesa-dashboard-welcome-header__greeting m-0\">\r\n {{ greeting }}\r\n </h1>\r\n <p class=\"ieeesa-dashboard-welcome-header__helper-text m-0\">\r\n {{ texts?.helperText }}\r\n </p>\r\n </div>\r\n\r\n <!-- \"Jump to\" shortcuts: each icon expands on hover/focus into a pill with\r\n the section label and its count badge. -->\r\n <div class=\"ieeesa-dashboard-welcome-header__jump-to\">\r\n <span class=\"ieeesa-dashboard-welcome-header__jump-to-label\">\r\n {{ texts?.jumpToLabel }}\r\n </span>\r\n\r\n <button\r\n *ngFor=\"let shortcut of shortcuts; trackBy: trackByTarget\"\r\n type=\"button\"\r\n class=\"ieeesa-dashboard-welcome-header__shortcut\"\r\n [attr.aria-label]=\"shortcut.ariaLabel + ' (' + shortcut.count + ')'\"\r\n (click)=\"onShortcutClick(shortcut.target)\"\r\n >\r\n <img\r\n class=\"ieeesa-dashboard-welcome-header__shortcut-icon\"\r\n [src]=\"shortcut.iconUrl\"\r\n alt=\"\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"ieeesa-dashboard-welcome-header__shortcut-label\">\r\n {{ shortcut.label }}\r\n </span>\r\n <span class=\"ieeesa-dashboard-welcome-header__shortcut-count\">\r\n {{ shortcut.count }}\r\n </span>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-dashboard-welcome-header{display:flex;align-items:center;justify-content:flex-start;gap:10%;flex-wrap:wrap}.ieeesa-dashboard-welcome-header__intro{display:flex;flex-direction:column;gap:4px}.ieeesa-dashboard-welcome-header__greeting{font-family:Calibri Bold;font-weight:700;font-style:normal;font-size:18px;line-height:27px;letter-spacing:0px;color:#111}.ieeesa-dashboard-welcome-header__helper-text{font-family:Calibri Regular;font-weight:400;font-style:normal;font-size:12px;line-height:16.5px;letter-spacing:0px;color:#6a7282}.ieeesa-dashboard-welcome-header__jump-to{display:inline-flex;align-items:center;gap:20px;min-width:228px;width:-moz-fit-content;width:fit-content;height:60px;padding-left:18px;padding-right:18px;background-color:#fff;border-radius:10px;box-shadow:0 1px 2px #0003}.ieeesa-dashboard-welcome-header__jump-to-label{font-family:Calibri Bold;font-weight:700;font-size:.8125rem;letter-spacing:.03125em;text-transform:uppercase;color:#333436;white-space:nowrap}.ieeesa-dashboard-welcome-header__shortcut{display:inline-flex;align-items:center;justify-content:center;gap:0;width:40px;height:40px;padding:0;border:1.5px solid #D1D5DC;border-radius:20px;background-color:#fff;color:#00629b;cursor:pointer;overflow:hidden;transition:width .25s ease,padding .25s ease,gap .2s ease,background-color .2s ease,border-color .2s ease}.ieeesa-dashboard-welcome-header__shortcut:hover,.ieeesa-dashboard-welcome-header__shortcut:focus-visible{width:auto;gap:8px;padding:0 14px;border-color:#00629b;background-color:#eaf3f9;outline:none}.ieeesa-dashboard-welcome-header__shortcut-icon{flex:0 0 auto;width:20px;height:20px;display:block}.ieeesa-dashboard-welcome-header__shortcut-label{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#333436;transition:max-width .25s ease,opacity .2s ease}.ieeesa-dashboard-welcome-header__shortcut-count{display:inline-flex;align-items:center;justify-content:center;max-width:0;padding:0;opacity:0;overflow:hidden;border-radius:12px;background-color:#eaf3f9;color:#00629b;font-family:Calibri Bold;font-weight:700;font-size:.75rem;white-space:nowrap;transition:max-width .25s ease,opacity .2s ease,padding .2s ease}.ieeesa-dashboard-welcome-header__shortcut:hover .ieeesa-dashboard-welcome-header__shortcut-label,.ieeesa-dashboard-welcome-header__shortcut:focus-visible .ieeesa-dashboard-welcome-header__shortcut-label{max-width:240px;opacity:1}.ieeesa-dashboard-welcome-header__shortcut:hover .ieeesa-dashboard-welcome-header__shortcut-count,.ieeesa-dashboard-welcome-header__shortcut:focus-visible .ieeesa-dashboard-welcome-header__shortcut-count{max-width:48px;padding:2px 10px;opacity:1}@media (max-width: 767px){.ieeesa-dashboard-welcome-header{align-items:flex-start}}\n"] }]
1005
+ }], propDecorators: { userName: [{
1006
+ type: Input
1007
+ }], meetingsCount: [{
1008
+ type: Input
1009
+ }], groupsCount: [{
1010
+ type: Input
1011
+ }], shortcutSelected: [{
1012
+ type: Output
1013
+ }] } });
1014
+
1015
+ /**
1016
+ * Mock upcoming-events + groups fixtures for the dashboard library.
1017
+ *
1018
+ * These exercise the key presentation edge cases:
1019
+ * - empty/undefined `groupOrCommittee` and `roomOrLocation` (empty-field placeholder)
1020
+ * - a mix of `CURRENTLY_ATTENDING` / `NOT_ATTENDING` attendance states
1021
+ * - events with many meetings so per-card pagination is exercised
1022
+ *
1023
+ * TODO: Replace mock with real API call when BE is ready
1024
+ */
1025
+ const DashboardUpcomingEventsMock = [
1026
+ {
1027
+ eventId: 'EVT-001',
1028
+ title: 'NESC Revision Cycle Kickoff',
1029
+ status: 'In Progress',
1030
+ dayIndicator: 'Day 1 of 3',
1031
+ meetingCount: 6,
1032
+ openForAttendanceCount: 3,
1033
+ startDate: '2025-03-14T09:00:00',
1034
+ endDate: '2025-03-16T17:00:00',
1035
+ timezone: 'America/New_York',
1036
+ meetings: [
1037
+ {
1038
+ meetingId: 'MTG-001',
1039
+ meetingName: 'Opening Plenary',
1040
+ groupOrCommittee: 'NESC Main Committee',
1041
+ roomOrLocation: 'Grand Ballroom A',
1042
+ meetingDate: '2025-03-14T09:00:00',
1043
+ meetingTime: '2025-03-14T09:00:00',
1044
+ timezone: 'America/New_York',
1045
+ isOpenForAttendance: true,
1046
+ attendanceState: AttendanceState.CURRENTLY_ATTENDING,
1047
+ },
1048
+ {
1049
+ meetingId: 'MTG-002',
1050
+ meetingName: 'Subcommittee 1 Working Session',
1051
+ groupOrCommittee: 'Subcommittee 1 - Grounding',
1052
+ // RoomOrLocation intentionally omitted to exercise the empty-field placeholder.
1053
+ meetingDate: '2025-03-14T11:00:00',
1054
+ meetingTime: '2025-03-14T11:00:00',
1055
+ timezone: 'America/New_York',
1056
+ isOpenForAttendance: true,
1057
+ attendanceState: AttendanceState.NOT_ATTENDING,
1058
+ },
1059
+ {
1060
+ meetingId: 'MTG-003',
1061
+ meetingName: 'Subcommittee 2 Working Session',
1062
+ // GroupOrCommittee intentionally empty to exercise the empty-field placeholder.
1063
+ groupOrCommittee: '',
1064
+ roomOrLocation: 'Room 204',
1065
+ meetingDate: '2025-03-14T13:30:00',
1066
+ meetingTime: '2025-03-14T13:30:00',
1067
+ timezone: 'America/New_York',
1068
+ isOpenForAttendance: true,
1069
+ attendanceState: AttendanceState.NOT_ATTENDING,
1070
+ },
1071
+ {
1072
+ meetingId: 'MTG-004',
1073
+ meetingName: 'Editorial Review',
1074
+ groupOrCommittee: 'Editorial Task Force',
1075
+ roomOrLocation: 'Room 118',
1076
+ meetingDate: '2025-03-15T09:00:00',
1077
+ meetingTime: '2025-03-15T09:00:00',
1078
+ timezone: 'America/New_York',
1079
+ isOpenForAttendance: false,
1080
+ attendanceState: AttendanceState.NOT_ATTENDING,
1081
+ },
1082
+ {
1083
+ meetingId: 'MTG-005',
1084
+ meetingName: 'Interpretations Panel',
1085
+ groupOrCommittee: 'Interpretations Subcommittee',
1086
+ roomOrLocation: 'Room 310',
1087
+ meetingDate: '2025-03-15T14:00:00',
1088
+ meetingTime: '2025-03-15T14:00:00',
1089
+ timezone: 'America/New_York',
1090
+ isOpenForAttendance: true,
1091
+ attendanceState: AttendanceState.CURRENTLY_ATTENDING,
1092
+ },
1093
+ {
1094
+ meetingId: 'MTG-006',
1095
+ meetingName: 'Closing Plenary',
1096
+ groupOrCommittee: 'NESC Main Committee',
1097
+ roomOrLocation: 'Grand Ballroom A',
1098
+ meetingDate: '2025-03-16T15:00:00',
1099
+ meetingTime: '2025-03-16T15:00:00',
1100
+ timezone: 'America/New_York',
1101
+ isOpenForAttendance: false,
1102
+ attendanceState: AttendanceState.NOT_ATTENDING,
1103
+ },
1104
+ ],
1105
+ },
1106
+ {
1107
+ eventId: 'EVT-002',
1108
+ title: 'Standards Board Quarterly Meeting',
1109
+ status: 'Upcoming',
1110
+ dayIndicator: 'Day 1 of 1',
1111
+ meetingCount: 3,
1112
+ openForAttendanceCount: 1,
1113
+ startDate: '2025-04-02T08:30:00',
1114
+ endDate: '2025-04-02T16:00:00',
1115
+ timezone: 'America/Los_Angeles',
1116
+ meetings: [
1117
+ {
1118
+ meetingId: 'MTG-101',
1119
+ meetingName: 'Board Opening Remarks',
1120
+ groupOrCommittee: 'Standards Board',
1121
+ roomOrLocation: 'Pacific Hall',
1122
+ meetingDate: '2025-04-02T08:30:00',
1123
+ meetingTime: '2025-04-02T08:30:00',
1124
+ timezone: 'America/Los_Angeles',
1125
+ isOpenForAttendance: true,
1126
+ attendanceState: AttendanceState.NOT_ATTENDING,
1127
+ },
1128
+ {
1129
+ meetingId: 'MTG-102',
1130
+ meetingName: 'Ballot Review Session',
1131
+ // Both optional location/group fields omitted to exercise placeholders.
1132
+ meetingDate: '2025-04-02T10:30:00',
1133
+ meetingTime: '2025-04-02T10:30:00',
1134
+ timezone: 'America/Los_Angeles',
1135
+ isOpenForAttendance: false,
1136
+ attendanceState: AttendanceState.NOT_ATTENDING,
1137
+ },
1138
+ {
1139
+ meetingId: 'MTG-103',
1140
+ meetingName: 'Action Items & Wrap-up',
1141
+ groupOrCommittee: 'Standards Board',
1142
+ roomOrLocation: 'Pacific Hall',
1143
+ meetingDate: '2025-04-02T15:00:00',
1144
+ meetingTime: '2025-04-02T15:00:00',
1145
+ timezone: 'America/Los_Angeles',
1146
+ isOpenForAttendance: false,
1147
+ attendanceState: AttendanceState.CURRENTLY_ATTENDING,
1148
+ },
1149
+ ],
1150
+ },
1151
+ {
1152
+ eventId: 'EVT-003',
1153
+ title: 'Working Group Interim',
1154
+ status: 'Upcoming',
1155
+ // DayIndicator intentionally omitted (optional field).
1156
+ meetingCount: 0,
1157
+ openForAttendanceCount: 0,
1158
+ startDate: '2025-05-20T09:00:00',
1159
+ endDate: '2025-05-20T12:00:00',
1160
+ timezone: 'Europe/London',
1161
+ meetings: [],
1162
+ },
1163
+ ];
1164
+ /**
1165
+ * Mock a single meeting row with an empty `meetingId` to exercise the
1166
+ * non-actionable (empty/undefined id) path in the meeting row component.
1167
+ *
1168
+ * TODO: Replace mock with real API call when BE is ready
1169
+ */
1170
+ const DashboardNonActionableMeetingMock = {
1171
+ meetingId: '',
1172
+ meetingName: 'Unscheduled Placeholder Session',
1173
+ groupOrCommittee: '',
1174
+ meetingDate: '2025-06-01T09:00:00',
1175
+ meetingTime: '2025-06-01T09:00:00',
1176
+ timezone: 'America/New_York',
1177
+ isOpenForAttendance: false,
1178
+ attendanceState: AttendanceState.NOT_ATTENDING,
1179
+ };
1180
+ /**
1181
+ * Mock groups fixtures for the dashboard "Your Groups" section.
1182
+ *
1183
+ * Includes rows with missing optional fields (`type`, `officerRole`,
1184
+ * `affiliation`) and a spread of member levels so the member-level badge
1185
+ * colour map and empty-field placeholders are exercised.
1186
+ *
1187
+ * TODO: Replace mock with real API call when BE is ready
1188
+ */
1189
+ const DashboardGroupsMock = [
1190
+ {
1191
+ groupId: 'GRP-001',
1192
+ group: 'NESC Main Committee',
1193
+ type: 'Committee',
1194
+ officerRole: 'Chair',
1195
+ affiliation: 'Employer Corp',
1196
+ memberLevel: 'Senior Member',
1197
+ },
1198
+ {
1199
+ groupId: 'GRP-002',
1200
+ group: 'Subcommittee 1 - Grounding',
1201
+ type: 'Subcommittee',
1202
+ // OfficerRole intentionally omitted (member with no officer role).
1203
+ affiliation: 'Standards Member',
1204
+ memberLevel: 'Member',
1205
+ },
1206
+ {
1207
+ groupId: 'GRP-003',
1208
+ group: 'Editorial Task Force',
1209
+ // Type and affiliation intentionally omitted to exercise placeholders.
1210
+ officerRole: 'Secretary',
1211
+ memberLevel: 'Fellow',
1212
+ },
1213
+ {
1214
+ groupId: 'GRP-004',
1215
+ group: 'Interpretations Subcommittee',
1216
+ type: 'Subcommittee',
1217
+ officerRole: 'Member',
1218
+ affiliation: 'Tech Solutions Inc',
1219
+ memberLevel: 'Associate Member',
1220
+ },
1221
+ {
1222
+ groupId: 'GRP-005',
1223
+ group: 'Standards Board',
1224
+ type: 'Board',
1225
+ officerRole: 'Vice Chair',
1226
+ affiliation: 'CodeCraft Studio',
1227
+ memberLevel: 'Senior Member',
1228
+ },
1229
+ ];
1230
+
1231
+ /**
1232
+ * Groups_Section (`ieeesa-your-groups`) renders the signed-in user's groups as a
1233
+ * paginated table inside a collapsible card. It shows the section title and a
1234
+ * "{n} Groups" count, a "View All" link, and a collapse/expand toggle that
1235
+ * controls the table's visibility (reflected via `[attr.aria-expanded]`). When
1236
+ * loaded it renders the groups table with the Presentation_Library
1237
+ * {@link DataTableComponent} using the columns Group, Type, Officer Role,
1238
+ * Affiliation, and Member Level (labels sourced from `constants.json`). The
1239
+ * Group cell is a LINK column that emits `groupSelected(groupId)`, and the
1240
+ * Member Level cell renders as a colored pill via the data-table's inline-badge
1241
+ * mechanism (green for voting-type levels, amber otherwise).
1242
+ *
1243
+ * The section is purely presentational: it emits navigation and pagination
1244
+ * intents via `@Output()` and never performs navigation or HTTP itself. The
1245
+ * Loader / empty-state / error regions are mutually exclusive and driven solely
1246
+ * by the `sectionState` input.
1247
+ * @export
1248
+ * @class YourGroupsComponent
1249
+ */
1250
+ class YourGroupsComponent {
1251
+ constructor() {
1252
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1253
+ this.constants = constants$1;
1254
+ /** User-facing strings sourced from `constants.json`. */
1255
+ this.texts = this.constants?.groupsSection;
1256
+ /** Enum reference for template comparisons against `sectionState`. */
1257
+ this.sectionStates = DashboardSectionState;
1258
+ /**
1259
+ * The groups rendered in the table. Defaults to the dummy fixture so the
1260
+ * table shows immediately while the API integration is pending; the host can
1261
+ * override it once real data is wired in.
1262
+ */
1263
+ this.groups = DashboardGroupsMock;
1264
+ /**
1265
+ * The section's load/empty/error state driving the mutually-exclusive
1266
+ * regions. Defaults to LOADED (no loader) since the component renders dummy
1267
+ * data for now; the host can set LOADING/EMPTY/ERROR once the API is wired.
1268
+ */
1269
+ this.sectionState = DashboardSectionState.LOADED;
1270
+ /** Total number of groups (for the "{n} Groups" count and paginator). */
1271
+ this.totalGroups = 0;
1272
+ /** Current zero-based page index. */
1273
+ this.pageIndex = 0;
1274
+ /** Current page size. */
1275
+ this.pageSize = 10;
1276
+ /** Emits the selected group's id when its name link is clicked. */
1277
+ this.groupSelected = new EventEmitter();
1278
+ /** Emits when the "View All" link is activated. */
1279
+ this.viewAllGroups = new EventEmitter();
1280
+ /** Emits the requested page when the paginator changes. */
1281
+ this.pageChange = new EventEmitter();
1282
+ /** Whether the card is expanded (table visible). Starts collapsed. */
1283
+ this.isExpanded = false;
1284
+ /** Data-table action flags: pagination only (no search/filter/add/edit). */
1285
+ this.tableActions = {
1286
+ isPaginationNeeded: true,
1287
+ };
1288
+ /** Column schema for the groups data table. */
1289
+ this.columnSchema = [
1290
+ {
1291
+ id: 1,
1292
+ columnDef: 'group',
1293
+ heading: this.texts?.columns?.group,
1294
+ // LINK so the group name is a clickable link that opens the group.
1295
+ columnType: TableColumnType.LINK,
1296
+ cellData: (row) => row.group,
1297
+ },
1298
+ {
1299
+ id: 2,
1300
+ columnDef: 'type',
1301
+ heading: this.texts?.columns?.type,
1302
+ columnType: TableColumnType.TEXT,
1303
+ cellData: (row) => row.type || this.texts?.emptyValue,
1304
+ },
1305
+ {
1306
+ id: 3,
1307
+ columnDef: 'officerRole',
1308
+ heading: this.texts?.columns?.officerRole,
1309
+ columnType: TableColumnType.TEXT,
1310
+ // "-" placeholder when the user holds no officer role (matches the design).
1311
+ cellData: (row) => row.officerRole || this.texts?.emptyValue,
1312
+ },
1313
+ {
1314
+ id: 4,
1315
+ columnDef: 'affiliation',
1316
+ heading: this.texts?.columns?.affiliation,
1317
+ columnType: TableColumnType.TEXT,
1318
+ cellData: (row) => row.affiliation || this.texts?.emptyValue,
1319
+ },
1320
+ {
1321
+ id: 5,
1322
+ columnDef: 'memberLevel',
1323
+ heading: this.texts?.columns?.memberLevel,
1324
+ columnType: TableColumnType.TEXT,
1325
+ cellData: (row) => row.memberLevel,
1326
+ // Render the member level as a colored pill via the data-table's inline
1327
+ // badge; green for voting-type levels, amber for the rest (e.g. Observer).
1328
+ showInlineBadge: (row) => !!row.memberLevel,
1329
+ inlineBadgeText: (row) => row.memberLevel,
1330
+ inlineBadgeClass: (row) => this.resolveBadgeClass(row.memberLevel),
1331
+ },
1332
+ ];
1333
+ }
1334
+ /**
1335
+ * The count shown in the header subtitle, preferring the server total and
1336
+ * falling back to the current page length.
1337
+ * @readonly
1338
+ * @memberof YourGroupsComponent
1339
+ */
1340
+ get groupCount() {
1341
+ return this.totalGroups || this.groups?.length || 0;
1342
+ }
1343
+ /**
1344
+ * The paginator config derived from the total/pageSize inputs.
1345
+ * @readonly
1346
+ * @memberof YourGroupsComponent
1347
+ */
1348
+ get paginatorConfig() {
1349
+ return {
1350
+ recordsPerPage: this.pageSize,
1351
+ pageSizeOptions: [5, 10, 25, 50],
1352
+ totalRecords: this.groupCount,
1353
+ };
1354
+ }
1355
+ /**
1356
+ * Toggles the card's expanded/collapsed state (table visibility).
1357
+ * @memberof YourGroupsComponent
1358
+ */
1359
+ onToggleExpand() {
1360
+ this.isExpanded = !this.isExpanded;
1361
+ }
1362
+ /**
1363
+ * Emits the "View All" intent for the host.
1364
+ * @memberof YourGroupsComponent
1365
+ */
1366
+ onViewAll() {
1367
+ this.viewAllGroups.emit();
1368
+ }
1369
+ /**
1370
+ * Emits the selected group's id from the data-table link click.
1371
+ * @param {{ row: GroupRow }} event - The data-table link-click payload.
1372
+ * @memberof YourGroupsComponent
1373
+ */
1374
+ onGroupLinkClick(event) {
1375
+ const groupId = event?.row?.groupId;
1376
+ if (groupId) {
1377
+ this.groupSelected.emit(groupId);
1378
+ }
1379
+ }
1380
+ /**
1381
+ * Re-emits the paginator change as a {@link PageChange}.
1382
+ * @param {PageEvent} event - The Material paginator event.
1383
+ * @memberof YourGroupsComponent
1384
+ */
1385
+ onPageChange(event) {
1386
+ this.pageChange.emit({
1387
+ pageIndex: event.pageIndex,
1388
+ pageSize: event.pageSize,
1389
+ });
1390
+ }
1391
+ /**
1392
+ * Resolves the pill CSS class for a member level: the configured "success"
1393
+ * (green) class for voting-type levels, otherwise the "warning" (amber) class.
1394
+ * @param {string} memberLevel - The member level label.
1395
+ * @return {string}
1396
+ * @memberof YourGroupsComponent
1397
+ */
1398
+ resolveBadgeClass(memberLevel) {
1399
+ const badgeTexts = this.texts?.memberLevelBadge;
1400
+ const isVoting = (memberLevel ?? '')
1401
+ .toLowerCase()
1402
+ .includes('voting');
1403
+ return isVoting ? badgeTexts?.votingMember : badgeTexts?.default;
1404
+ }
1405
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: YourGroupsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1406
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: YourGroupsComponent, isStandalone: true, selector: "ieeesa-your-groups", inputs: { groups: "groups", sectionState: "sectionState", totalGroups: "totalGroups", pageIndex: "pageIndex", pageSize: "pageSize" }, outputs: { groupSelected: "groupSelected", viewAllGroups: "viewAllGroups", pageChange: "pageChange" }, ngImport: i0, template: "<section class=\"ieeesa-your-groups\">\r\n <!-- Header: title + count, View All link, collapse/expand toggle -->\r\n <div class=\"ieeesa-your-groups__header\">\r\n <div class=\"ieeesa-your-groups__heading\">\r\n <h2 class=\"ieeesa-your-groups__title m-0\">{{ texts?.title }}</h2>\r\n <p class=\"ieeesa-your-groups__count m-0\">\r\n {{ groupCount }} {{ texts?.countSuffix }}\r\n </p>\r\n </div>\r\n\r\n <div class=\"ieeesa-your-groups__actions\">\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-your-groups__view-all\"\r\n [attr.aria-label]=\"texts?.ariaLabel?.viewAll\"\r\n (click)=\"onViewAll()\"\r\n >\r\n {{ texts?.viewAllLabel }}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-your-groups__toggle\"\r\n [attr.aria-expanded]=\"isExpanded\"\r\n [attr.aria-label]=\"texts?.ariaLabel?.toggle\"\r\n (click)=\"onToggleExpand()\"\r\n >\r\n <span>{{ isExpanded ? texts?.collapseLabel : texts?.expandLabel }}</span>\r\n <i\r\n class=\"fa-solid\"\r\n [ngClass]=\"isExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Body: only when expanded. Loader / error / empty / table are mutually\r\n exclusive, driven by sectionState. -->\r\n <div class=\"ieeesa-your-groups__body\" *ngIf=\"isExpanded\">\r\n <ieeesa-loader\r\n *ngIf=\"sectionState === sectionStates.LOADING\"\r\n ></ieeesa-loader>\r\n\r\n <p\r\n *ngIf=\"sectionState === sectionStates.ERROR\"\r\n class=\"ieeesa-your-groups__message ieeesa-your-groups__message--error\"\r\n role=\"alert\"\r\n >\r\n {{ texts?.errorMessage }}\r\n </p>\r\n\r\n <p\r\n *ngIf=\"sectionState === sectionStates.EMPTY\"\r\n class=\"ieeesa-your-groups__message\"\r\n role=\"status\"\r\n >\r\n {{ texts?.emptyMessage }}\r\n </p>\r\n\r\n <ieeesa-data-table\r\n *ngIf=\"sectionState === sectionStates.LOADED\"\r\n class=\"ieeesa-your-groups__table\"\r\n [tableDataInfo]=\"groups\"\r\n [columnSchemaInfo]=\"columnSchema\"\r\n [tableActions]=\"tableActions\"\r\n [paginatorConfig]=\"paginatorConfig\"\r\n [pageIndex]=\"pageIndex\"\r\n [pageSize]=\"pageSize\"\r\n (columnDataOnRowLinkClick)=\"onGroupLinkClick($event)\"\r\n (paginationChange)=\"onPageChange($event)\"\r\n ></ieeesa-data-table>\r\n </div>\r\n</section>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-your-groups{display:block;background-color:#fff;border-radius:12px;box-shadow:0 1px 2px #0003;padding:20px 24px;border:1px solid #E2E8F0}.ieeesa-your-groups__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.ieeesa-your-groups__heading{display:flex;flex-direction:column;gap:2px}.ieeesa-your-groups__title{font-family:Calibri Bold;font-weight:700;font-size:1.125rem;color:#333436}.ieeesa-your-groups__count{font-family:Calibri Regular;font-size:.75rem;color:#777a7e}.ieeesa-your-groups__actions{display:flex;align-items:center;gap:16px}.ieeesa-your-groups__view-all{background:none;border:none;padding:0;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-your-groups__view-all:hover{text-decoration:underline}.ieeesa-your-groups__toggle{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border:1px solid #dbe2eb;border-radius:8px;background-color:#fff;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-your-groups__toggle:hover{border-color:#00629b}.ieeesa-your-groups__toggle i{font-size:.75rem}.ieeesa-your-groups__body{margin-top:16px}.ieeesa-your-groups__message{text-align:center;padding:32px 0;font-family:Calibri Regular;font-size:.875rem;color:#777a7e}.ieeesa-your-groups__message--error{color:#ba0c2f}.ieeesa-your-groups .ieeesa-your-groups__badge--success{background-color:#78d7ef2e;color:#002c37}.ieeesa-your-groups .ieeesa-your-groups__badge--warning{background-color:#ffd92e38;color:#333436}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DataTableComponent, selector: "ieeesa-data-table", inputs: ["tableDataInfo", "nestedTableDataInfo", "columnSchemaInfo", "nestedTableColumnSchemaInfo", "tableActions", "hasNestedTable", "tableColumnActions", "tableColumnActionMenuSize", "tableRowActions", "nestedTableRowActions", "caption", "viewAll", "paginatorConfig", "nestedPaginatorConfig", "legends", "pageIndex", "pageSize", "searchPlaceHolderText", "rowEditButton", "rowDeleteButton", "tableEditButton", "tableDeleteButton", "rowExpandButton", "rowCollapseButton", "isNestedTableHeaderNeeded", "addButton", "defaultColumnSortDirection", "defaultSortedColumn", "isClearSortNeeded", "filters", "selectedFilterOptions", "appliedFilterOptions", "searchType", "className", "searchSupportMessage", "inbuiltSortingNeeded", "isCellTextOverflowEllipsis", "isTableHeaderNeeded", "tableColumnsHeaderText", "verticalColumnHeaderNumber", "scrollbarSupportMessage", "isScrollSupportMessageNeeded", "isStickyHeaderNeeded", "customStickyHeaderNeeded", "headerElementClassName", "minCharToSearch", "searchResultMessage", "rowMenuActionIcon", "canDisableCheckbox", "isEllipsisRequiredForLink"], outputs: ["rowSelected", "selectedRowToEdit", "selectedRowToDelete", "selectedRowsToDelete", "rowLink", "addRow", "columnDataOnRowLinkClick", "menuActionClick", "selectActionMenu", "paginationChange", "selectedFilter", "removeFilteredOption", "filteredOptions", "searchedValue", "sortChange", "selectedRowsInfo", "rowExpansionClick", "tableColumnMenuActionClick", "tableColumnMenuToggleButton", "rowSlideToggle", "rowDropdownChange"] }, { kind: "component", type: LoaderComponent, selector: "ieeesa-loader", inputs: ["diameter"] }], encapsulation: i0.ViewEncapsulation.None }); }
1407
+ }
1408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: YourGroupsComponent, decorators: [{
1409
+ type: Component,
1410
+ args: [{ selector: 'ieeesa-your-groups', standalone: true, imports: [CommonModule, DataTableComponent, LoaderComponent], encapsulation: ViewEncapsulation.None, template: "<section class=\"ieeesa-your-groups\">\r\n <!-- Header: title + count, View All link, collapse/expand toggle -->\r\n <div class=\"ieeesa-your-groups__header\">\r\n <div class=\"ieeesa-your-groups__heading\">\r\n <h2 class=\"ieeesa-your-groups__title m-0\">{{ texts?.title }}</h2>\r\n <p class=\"ieeesa-your-groups__count m-0\">\r\n {{ groupCount }} {{ texts?.countSuffix }}\r\n </p>\r\n </div>\r\n\r\n <div class=\"ieeesa-your-groups__actions\">\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-your-groups__view-all\"\r\n [attr.aria-label]=\"texts?.ariaLabel?.viewAll\"\r\n (click)=\"onViewAll()\"\r\n >\r\n {{ texts?.viewAllLabel }}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"ieeesa-your-groups__toggle\"\r\n [attr.aria-expanded]=\"isExpanded\"\r\n [attr.aria-label]=\"texts?.ariaLabel?.toggle\"\r\n (click)=\"onToggleExpand()\"\r\n >\r\n <span>{{ isExpanded ? texts?.collapseLabel : texts?.expandLabel }}</span>\r\n <i\r\n class=\"fa-solid\"\r\n [ngClass]=\"isExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Body: only when expanded. Loader / error / empty / table are mutually\r\n exclusive, driven by sectionState. -->\r\n <div class=\"ieeesa-your-groups__body\" *ngIf=\"isExpanded\">\r\n <ieeesa-loader\r\n *ngIf=\"sectionState === sectionStates.LOADING\"\r\n ></ieeesa-loader>\r\n\r\n <p\r\n *ngIf=\"sectionState === sectionStates.ERROR\"\r\n class=\"ieeesa-your-groups__message ieeesa-your-groups__message--error\"\r\n role=\"alert\"\r\n >\r\n {{ texts?.errorMessage }}\r\n </p>\r\n\r\n <p\r\n *ngIf=\"sectionState === sectionStates.EMPTY\"\r\n class=\"ieeesa-your-groups__message\"\r\n role=\"status\"\r\n >\r\n {{ texts?.emptyMessage }}\r\n </p>\r\n\r\n <ieeesa-data-table\r\n *ngIf=\"sectionState === sectionStates.LOADED\"\r\n class=\"ieeesa-your-groups__table\"\r\n [tableDataInfo]=\"groups\"\r\n [columnSchemaInfo]=\"columnSchema\"\r\n [tableActions]=\"tableActions\"\r\n [paginatorConfig]=\"paginatorConfig\"\r\n [pageIndex]=\"pageIndex\"\r\n [pageSize]=\"pageSize\"\r\n (columnDataOnRowLinkClick)=\"onGroupLinkClick($event)\"\r\n (paginationChange)=\"onPageChange($event)\"\r\n ></ieeesa-data-table>\r\n </div>\r\n</section>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-your-groups{display:block;background-color:#fff;border-radius:12px;box-shadow:0 1px 2px #0003;padding:20px 24px;border:1px solid #E2E8F0}.ieeesa-your-groups__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.ieeesa-your-groups__heading{display:flex;flex-direction:column;gap:2px}.ieeesa-your-groups__title{font-family:Calibri Bold;font-weight:700;font-size:1.125rem;color:#333436}.ieeesa-your-groups__count{font-family:Calibri Regular;font-size:.75rem;color:#777a7e}.ieeesa-your-groups__actions{display:flex;align-items:center;gap:16px}.ieeesa-your-groups__view-all{background:none;border:none;padding:0;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-your-groups__view-all:hover{text-decoration:underline}.ieeesa-your-groups__toggle{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border:1px solid #dbe2eb;border-radius:8px;background-color:#fff;cursor:pointer;font-family:Calibri Bold;font-weight:700;font-size:.875rem;color:#00629b}.ieeesa-your-groups__toggle:hover{border-color:#00629b}.ieeesa-your-groups__toggle i{font-size:.75rem}.ieeesa-your-groups__body{margin-top:16px}.ieeesa-your-groups__message{text-align:center;padding:32px 0;font-family:Calibri Regular;font-size:.875rem;color:#777a7e}.ieeesa-your-groups__message--error{color:#ba0c2f}.ieeesa-your-groups .ieeesa-your-groups__badge--success{background-color:#78d7ef2e;color:#002c37}.ieeesa-your-groups .ieeesa-your-groups__badge--warning{background-color:#ffd92e38;color:#333436}\n"] }]
1411
+ }], propDecorators: { groups: [{
1412
+ type: Input
1413
+ }], sectionState: [{
1414
+ type: Input
1415
+ }], totalGroups: [{
1416
+ type: Input
1417
+ }], pageIndex: [{
1418
+ type: Input
1419
+ }], pageSize: [{
1420
+ type: Input
1421
+ }], groupSelected: [{
1422
+ type: Output
1423
+ }], viewAllGroups: [{
1424
+ type: Output
1425
+ }], pageChange: [{
1426
+ type: Output
1427
+ }] } });
1428
+
1429
+ /**
1430
+ * Pure reducers for the dashboard attendance state. These functions never
1431
+ * mutate their inputs; each returns a new object/set so they can be exercised
1432
+ * directly by property tests and composed by the DashboardService.
1433
+ */
1434
+ /**
1435
+ * Produce a new attendance-state map with the target meeting set to
1436
+ * CURRENTLY_ATTENDING. Every other entry is copied unchanged (frame property).
1437
+ *
1438
+ * @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
1439
+ * @param {string} meetingId The meeting whose state transitions to CURRENTLY_ATTENDING.
1440
+ * @return {Record<string, AttendanceState>} A new map reflecting the successful log-attendance action.
1441
+ */
1442
+ const applyLogAttendanceSuccess = (map, meetingId) => ({
1443
+ ...map,
1444
+ [meetingId]: AttendanceState.CURRENTLY_ATTENDING,
1445
+ });
1446
+ /**
1447
+ * Produce a new attendance-state map with the target meeting set to
1448
+ * NOT_ATTENDING. Every other entry is copied unchanged (frame property).
1449
+ *
1450
+ * @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
1451
+ * @param {string} meetingId The meeting whose state transitions to NOT_ATTENDING.
1452
+ * @return {Record<string, AttendanceState>} A new map reflecting the successful leave-meeting action.
1453
+ */
1454
+ const applyLeaveMeetingSuccess = (map, meetingId) => ({
1455
+ ...map,
1456
+ [meetingId]: AttendanceState.NOT_ATTENDING,
1457
+ });
1458
+ /**
1459
+ * Add a meeting to the in-flight set, returning a new set. Prior membership is
1460
+ * retained so the displayed attendance state is preserved while the request
1461
+ * resolves.
1462
+ *
1463
+ * @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
1464
+ * @param {string} meetingId The meeting whose attendance action has started.
1465
+ * @return {Set<string>} A new set that additionally contains the meeting id.
1466
+ */
1467
+ const beginAttendanceAction = (set, meetingId) => new Set([...set, meetingId]);
1468
+ /**
1469
+ * Remove a meeting from the in-flight set, returning a new set. All other
1470
+ * in-flight ids are retained.
1471
+ *
1472
+ * @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
1473
+ * @param {string} meetingId The meeting whose attendance action has resolved.
1474
+ * @return {Set<string>} A new set that no longer contains the meeting id.
1475
+ */
1476
+ const endAttendanceAction = (set, meetingId) => {
1477
+ const next = new Set(set);
1478
+ next.delete(meetingId);
1479
+ return next;
1480
+ };
1481
+
1482
+ /**
1483
+ * DashboardService is the single source of truth for the dashboard landing
1484
+ * page's data and attendance state. It mirrors the `events-and-meetings`
1485
+ * service conventions: it is a `providedIn: 'root'` singleton, holds the host
1486
+ * `apiBaseUrl` / `userPermissions` set via {@link setAppConfig}, owns its state
1487
+ * via `BehaviorSubject`s exposed as observables, and reaches the backend only
1488
+ * through the shared `HttpService` from `@ieeesa-npm/utility` (never
1489
+ * `HttpClient` directly).
1490
+ *
1491
+ * The upcoming-events and groups loads currently return annotated mock data
1492
+ * because their endpoints are not yet available; the attendance actions compose
1493
+ * the pure reducers from `attendance-reducers.ts` so the displayed
1494
+ * `AttendanceState` only advances on a successful resolution and the prior
1495
+ * state is retained on failure.
1496
+ * @export
1497
+ * @class DashboardService
1498
+ */
1499
+ class DashboardService {
1500
+ constructor(
1501
+ // eslint-disable-next-line no-unused-vars
1502
+ httpService // eslint-disable-next-line no-empty-function
1503
+ ) {
1504
+ this.httpService = httpService;
1505
+ this.upcomingEvents = new BehaviorSubject([]);
1506
+ this.groups = new BehaviorSubject([]);
1507
+ this.upcomingState = new BehaviorSubject(DashboardSectionState.LOADING);
1508
+ this.groupsState = new BehaviorSubject(DashboardSectionState.LOADING);
1509
+ this.attendanceStates = new BehaviorSubject({});
1510
+ this.inFlightMeetingIds = new BehaviorSubject(new Set());
1511
+ /** Emits the list of the user's upcoming events. */
1512
+ this.upcomingEvents$ = this.upcomingEvents.asObservable();
1513
+ /** Emits the list of the user's groups. */
1514
+ this.groups$ = this.groups.asObservable();
1515
+ /** Emits the load/empty/error state of the upcoming-events section. */
1516
+ this.upcomingState$ = this.upcomingState.asObservable();
1517
+ /** Emits the load/empty/error state of the groups section. */
1518
+ this.groupsState$ = this.groupsState.asObservable();
1519
+ /** Emits the per-meeting attendance-state map. */
1520
+ this.attendanceStates$ = this.attendanceStates.asObservable();
1521
+ /** Emits the set of meeting ids with an attendance action in flight. */
1522
+ this.inFlightMeetingIds$ = this.inFlightMeetingIds.asObservable();
1523
+ }
1524
+ /**
1525
+ * Stores the host-supplied API base URL and user permissions used to build
1526
+ * request URLs and gate permission-controlled actions. Mirrors the
1527
+ * `events-and-meetings` service `setAppConfig`.
1528
+ * @param {string} apiBaseURL - The host application's API base URL.
1529
+ * @param {UserPermission[]} userPermissions - The signed-in user's permissions.
1530
+ * @return {void}
1531
+ * @memberof DashboardService
1532
+ */
1533
+ setAppConfig(apiBaseURL, userPermissions) {
1534
+ this.apiBaseUrl = apiBaseURL;
1535
+ this.userPermissions = userPermissions;
1536
+ }
1537
+ /**
1538
+ * Loads the user's upcoming events, driving the upcoming section through
1539
+ * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
1540
+ * failure. Follows the `pipe(map, catchError(throw))` pattern and seeds the
1541
+ * per-meeting attendance-state map from the loaded meetings.
1542
+ *
1543
+ * TODO: Replace mock with real API call when BE is ready
1544
+ * @return {Observable<DashboardListResponse<UpcomingEvent[]>>} The upcoming-events response envelope.
1545
+ * @memberof DashboardService
1546
+ */
1547
+ loadUpcomingEvents() {
1548
+ this.upcomingState.next(DashboardSectionState.LOADING);
1549
+ // TODO: Replace mock with real API call when BE is ready
1550
+ const response$ = of({
1551
+ status: true,
1552
+ body: DashboardUpcomingEventsMock,
1553
+ });
1554
+ return response$.pipe(map((response) => {
1555
+ const events = response?.body ?? [];
1556
+ this.upcomingEvents.next(events);
1557
+ this.seedAttendanceStates(events);
1558
+ this.upcomingState.next(events.length > 0
1559
+ ? DashboardSectionState.LOADED
1560
+ : DashboardSectionState.EMPTY);
1561
+ return response;
1562
+ }), catchError((error) => {
1563
+ this.upcomingState.next(DashboardSectionState.ERROR);
1564
+ throw error;
1565
+ }));
1566
+ }
1567
+ /**
1568
+ * Loads the user's groups, driving the groups section through
1569
+ * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
1570
+ * failure. Follows the `pipe(map, catchError(throw))` pattern.
1571
+ *
1572
+ * TODO: Replace mock with real API call when BE is ready
1573
+ * @return {Observable<DashboardListResponse<GroupRow[]>>} The groups response envelope.
1574
+ * @memberof DashboardService
1575
+ */
1576
+ loadGroups() {
1577
+ this.groupsState.next(DashboardSectionState.LOADING);
1578
+ // TODO: Replace mock with real API call when BE is ready
1579
+ const response$ = of({
1580
+ status: true,
1581
+ body: DashboardGroupsMock,
1582
+ });
1583
+ return response$.pipe(map((response) => {
1584
+ const groups = response?.body ?? [];
1585
+ this.groups.next(groups);
1586
+ this.groupsState.next(groups.length > 0
1587
+ ? DashboardSectionState.LOADED
1588
+ : DashboardSectionState.EMPTY);
1589
+ return response;
1590
+ }), catchError((error) => {
1591
+ this.groupsState.next(DashboardSectionState.ERROR);
1592
+ throw error;
1593
+ }));
1594
+ }
1595
+ /**
1596
+ * Logs attendance for a meeting. Marks the meeting in-flight (retaining the
1597
+ * prior displayed state), posts through `HttpService`, applies the
1598
+ * log-attendance-success reducer on success, clears the in-flight flag on
1599
+ * completion, and rethrows while retaining prior state on failure.
1600
+ * @param {string} meetingId - The meeting to log attendance for.
1601
+ * @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
1602
+ * @memberof DashboardService
1603
+ */
1604
+ logAttendance(meetingId) {
1605
+ this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
1606
+ return this.httpService
1607
+ .postData(`${this.apiBaseUrl}/meetings/attendance/log`, { meetingId })
1608
+ .pipe(map((response) => {
1609
+ this.attendanceStates.next(applyLogAttendanceSuccess(this.attendanceStates.value, meetingId));
1610
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
1611
+ return response;
1612
+ }), catchError((error) => {
1613
+ // Retain prior attendance state; only clear the in-flight flag.
1614
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
1615
+ throw error;
1616
+ }));
1617
+ }
1618
+ /**
1619
+ * Leaves a meeting. Marks the meeting in-flight (retaining the prior
1620
+ * displayed state), posts through `HttpService`, applies the
1621
+ * leave-meeting-success reducer on success, clears the in-flight flag on
1622
+ * completion, and rethrows while retaining prior state on failure.
1623
+ * @param {string} meetingId - The meeting to leave.
1624
+ * @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
1625
+ * @memberof DashboardService
1626
+ */
1627
+ leaveMeeting(meetingId) {
1628
+ this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
1629
+ return this.httpService
1630
+ .postData(`${this.apiBaseUrl}/meetings/attendance/leave`, { meetingId })
1631
+ .pipe(map((response) => {
1632
+ this.attendanceStates.next(applyLeaveMeetingSuccess(this.attendanceStates.value, meetingId));
1633
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
1634
+ return response;
1635
+ }), catchError((error) => {
1636
+ // Retain prior attendance state; only clear the in-flight flag.
1637
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
1638
+ throw error;
1639
+ }));
1640
+ }
1641
+ /**
1642
+ * Returns a synchronous snapshot of the per-meeting attendance-state map.
1643
+ * @return {Record<string, AttendanceState>} The current attendance-state map.
1644
+ * @memberof DashboardService
1645
+ */
1646
+ getAttendanceStatesSnapshot() {
1647
+ return this.attendanceStates.value;
1648
+ }
1649
+ /**
1650
+ * Seeds the attendance-state map from a freshly loaded list of events, using
1651
+ * each meeting's `attendanceState` (defaulting to `NOT_ATTENDING`). Keeps the
1652
+ * displayed state in sync with the data load without overwriting ids that are
1653
+ * not present in the new list.
1654
+ * @param {UpcomingEvent[]} events - The loaded upcoming events.
1655
+ * @return {void}
1656
+ * @memberof DashboardService
1657
+ */
1658
+ seedAttendanceStates(events) {
1659
+ const next = {
1660
+ ...this.attendanceStates.value,
1661
+ };
1662
+ events.forEach((event) => {
1663
+ event.meetings?.forEach((meeting) => {
1664
+ if (meeting.meetingId) {
1665
+ next[meeting.meetingId] =
1666
+ meeting.attendanceState ?? AttendanceState.NOT_ATTENDING;
1667
+ }
1668
+ });
1669
+ });
1670
+ this.attendanceStates.next(next);
1671
+ }
1672
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, deps: [{ token: i1$1.HttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1673
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, providedIn: 'root' }); }
1674
+ }
1675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, decorators: [{
1676
+ type: Injectable,
1677
+ args: [{
1678
+ providedIn: 'root',
1679
+ }]
1680
+ }], ctorParameters: function () { return [{ type: i1$1.HttpService }]; } });
1681
+
1682
+ /**
1683
+ * Permission identifiers (by name) that gate the dashboard attendance actions.
1684
+ * Mirrors the permission-type pattern used by the `events-and-meetings` and
1685
+ * `groups` user-permissions services.
1686
+ */
1687
+ /* eslint-disable no-unused-vars */
1688
+ var DashboardPermissionType;
1689
+ (function (DashboardPermissionType) {
1690
+ DashboardPermissionType["LOG_ATTENDANCE"] = "Log Attendance";
1691
+ DashboardPermissionType["LEAVE_MEETING"] = "Leave Meeting";
1692
+ })(DashboardPermissionType || (DashboardPermissionType = {}));
1693
+ /* eslint-enable no-unused-vars */
1694
+ class UserPermissionsService {
1695
+ /**
1696
+ * Returns access provision for the passed action/feature based on whether the signed in user has appropriate permission.
1697
+ * @param {DashboardPermissionType} permission
1698
+ * @param {UserPermission[]} userPermissions
1699
+ * @return {boolean}
1700
+ * @memberof UserPermissionsService
1701
+ */
1702
+ validateAccessPermission(permission, userPermissions) {
1703
+ const isPermitted = userPermissions?.length > 0
1704
+ ? userPermissions?.some(({ permissionName }) => permissionName === permission)
1705
+ : false;
1706
+ return isPermitted;
1707
+ }
1708
+ /**
1709
+ * Maps the host-supplied user permissions to the attendance-action permissions consumed by the dashboard rows.
1710
+ * @param {UserPermission[]} userPermissions
1711
+ * @return {AttendanceActionPermissions}
1712
+ * @memberof UserPermissionsService
1713
+ */
1714
+ mapToAttendanceActionPermissions(userPermissions) {
1715
+ return {
1716
+ canLogAttendance: this.validateAccessPermission(DashboardPermissionType.LOG_ATTENDANCE, userPermissions),
1717
+ canLeaveMeeting: this.validateAccessPermission(DashboardPermissionType.LEAVE_MEETING, userPermissions),
1718
+ };
1719
+ }
1720
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1721
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, providedIn: 'root' }); }
1722
+ }
1723
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, decorators: [{
1724
+ type: Injectable,
1725
+ args: [{
1726
+ providedIn: 'root',
1727
+ }]
1728
+ }] });
1729
+
1730
+ /**
1731
+ * Dashboard (`ieeesa-dashboard`) is the root container and single host entry
1732
+ * point for the "NESC Revision Cycle" dashboard landing page. It owns the
1733
+ * host-supplied configuration (`routePaths`, `apiBaseURL`, `userInfo`,
1734
+ * `userPermissions`), composes the four regions — welcome header, upcoming
1735
+ * meetings & events, your groups, and footer — and orchestrates data loading
1736
+ * and attendance actions through the {@link DashboardService}.
1737
+ *
1738
+ * The component is composition-first and host-agnostic: it subscribes to the
1739
+ * service observables (`upcomingEvents$`, `groups$`, the per-section states, the
1740
+ * attendance-state map, and the in-flight set) with `takeUntil(destroy$)` and
1741
+ * tracks `isMobileView` from the Presentation_Library
1742
+ * {@link BreakpointObserverService} (Req 13.1, 13.2, 13.5, 15.1, 15.2). Child
1743
+ * navigation `@Output()`s are composed into a single {@link dashboardNavigate}
1744
+ * stream of `{ path, id }` intents resolved from `routePaths` (falling back to
1745
+ * the default route configuration in `constants.json` when `routePaths` is
1746
+ * omitted) (Req 5.2, 6.4, 7.4, 8.2, 8.7, 11.1, 11.5). Attendance `@Output()`s
1747
+ * are delegated to the service, and on failure the attendance-action error
1748
+ * message from `constants.json` is surfaced via the shared {@link AlertsService}
1749
+ * (Req 7.7, 7.8, 13.7). Per-row {@link AttendanceActionPermissions} are computed
1750
+ * from `userPermissions` and passed down to the rows (Req 12.3).
1751
+ * @export
1752
+ * @class DashboardComponent
1753
+ */
1754
+ class DashboardComponent {
1755
+ /**
1756
+ * Total number of meetings across the loaded upcoming events, shown in the
1757
+ * welcome header's "Upcoming Meetings & Events" shortcut badge.
1758
+ * @readonly
1759
+ * @memberof DashboardComponent
1760
+ */
1761
+ get meetingsCount() {
1762
+ return this.upcomingEvents.reduce((total, event) => total + (event?.meetingCount ?? 0), 0);
1763
+ }
1764
+ /**
1765
+ * Number of loaded groups, shown in the welcome header's "Your Groups"
1766
+ * shortcut badge.
1767
+ * @readonly
1768
+ * @memberof DashboardComponent
1769
+ */
1770
+ get groupsCount() {
1771
+ return this.groups.length;
1772
+ }
1773
+ constructor(
1774
+ // eslint-disable-next-line no-unused-vars
1775
+ dashboardService,
1776
+ // eslint-disable-next-line no-unused-vars
1777
+ userPermissionsService,
1778
+ // eslint-disable-next-line no-unused-vars
1779
+ breakpointObserverService,
1780
+ // eslint-disable-next-line no-unused-vars
1781
+ alertService // eslint-disable-next-line no-empty-function
1782
+ ) {
1783
+ this.dashboardService = dashboardService;
1784
+ this.userPermissionsService = userPermissionsService;
1785
+ this.breakpointObserverService = breakpointObserverService;
1786
+ this.alertService = alertService;
1787
+ /** User-facing strings and the default route config sourced from `constants.json`. */
1788
+ this.constants = constants$1;
1789
+ /** Emits a resolved navigation intent for the host to act on (Req 5.2, 6.4, 7.4, 8.2, 8.7, 11.1). */
1790
+ this.dashboardNavigate = new EventEmitter();
1791
+ /** The user's upcoming events, bound to the upcoming section (Req 13.1, 13.2). */
1792
+ this.upcomingEvents = [];
1793
+ /** The user's groups, bound to the groups section (Req 13.1, 13.2). */
1794
+ this.groups = [];
1795
+ /** The upcoming-events section's load/empty/error state (Req 13.1, 13.2, 13.5). */
1796
+ this.upcomingState = DashboardSectionState.LOADING;
1797
+ /** The groups section's load/empty/error state (Req 13.1, 13.2, 13.5). */
1798
+ this.groupsState = DashboardSectionState.LOADING;
1799
+ /** The per-meeting attendance-state map passed down to the rows. */
1800
+ this.attendanceStates = {};
1801
+ /** The set of meeting ids with an attendance action awaiting resolution. */
1802
+ this.inFlightMeetingIds = new Set();
1803
+ /** The per-row attendance-action permissions derived from `userPermissions` (Req 12.3). */
1804
+ this.attendancePermissions = {
1805
+ canLogAttendance: false,
1806
+ canLeaveMeeting: false,
1807
+ };
1808
+ /** Whether the viewport is at/below the mobile breakpoint (Req 15.1, 15.2). */
1809
+ this.isMobileView = false;
1810
+ /** The current zero-based page index of the groups table. */
1811
+ this.groupsPageIndex = 0;
1812
+ /** The current page size of the groups table. */
1813
+ this.groupsPageSize = 10;
1814
+ /** Completes on destroy to tear down all subscriptions (Req 2.4, 2.5). */
1815
+ this.destroy$ = new Subject();
1816
+ }
1817
+ /**
1818
+ * Initializes the dashboard: forwards the host config to the service, derives
1819
+ * the per-row attendance permissions, kicks off the upcoming-events and groups
1820
+ * loads, and wires up subscriptions to the service state observables and the
1821
+ * breakpoint observer — all cleaned up via `takeUntil(destroy$)` (Req 11.2,
1822
+ * 11.4, 12.3, 13.1, 13.2, 13.5, 15.1, 15.2).
1823
+ * @return {void}
1824
+ * @memberof DashboardComponent
1825
+ */
1826
+ ngOnInit() {
1827
+ this.dashboardService.setAppConfig(this.apiBaseURL, this.userPermissions);
1828
+ this.attendancePermissions =
1829
+ this.userPermissionsService.mapToAttendanceActionPermissions(this.userPermissions);
1830
+ this.subscribeToServiceState();
1831
+ this.subscribeToBreakpoint();
1832
+ this.loadUpcomingEvents();
1833
+ this.loadGroups();
1834
+ }
1835
+ /**
1836
+ * Tears down all subscriptions on destroy (Req 2.4, 2.5).
1837
+ * @return {void}
1838
+ * @memberof DashboardComponent
1839
+ */
1840
+ ngOnDestroy() {
1841
+ this.destroy$.next(true);
1842
+ this.destroy$.complete();
1843
+ }
1844
+ /**
1845
+ * Handles the welcome-header "Jump to" date selection. The dashboard currently
1846
+ * has no date-scoped data load, so the selection is accepted without side
1847
+ * effects; the hook keeps the header's contract satisfied for future filtering.
1848
+ * @return {void}
1849
+ * @memberof DashboardComponent
1850
+ */
1851
+ onJumpToDateSelected() {
1852
+ // No date-scoped reload yet; retained for future date filtering (Req 4.4).
1853
+ }
1854
+ /**
1855
+ * Handles a welcome-header "Jump to" shortcut, emitting the navigation intent
1856
+ * for the matching section so the host app routes to it: MEETINGS →
1857
+ * `viewAllEvents` (/events-and-meetings/view-events-meetings-list), GROUPS →
1858
+ * `viewAllGroups` (/groups).
1859
+ * @param {DashboardJumpTarget} target - The selected shortcut target.
1860
+ * @return {void}
1861
+ * @memberof DashboardComponent
1862
+ */
1863
+ onJumpToShortcut(target) {
1864
+ const path = target === DashboardJumpTarget.MEETINGS
1865
+ ? this.activeRouteConfig.viewAllEvents
1866
+ : this.activeRouteConfig.viewAllGroups;
1867
+ this.emitNavigation(path);
1868
+ }
1869
+ /**
1870
+ * Emits the "View All" upcoming-events navigation intent, targeting the
1871
+ * `viewAllEvents` route with no id (Req 5.2, 11.1).
1872
+ * @return {void}
1873
+ * @memberof DashboardComponent
1874
+ */
1875
+ onViewAllEvents() {
1876
+ this.emitNavigation(this.activeRouteConfig.viewAllEvents);
1877
+ }
1878
+ /**
1879
+ * Emits the "View Event" navigation intent, targeting the `eventDetail` route
1880
+ * with the event id (Req 6.4, 11.1).
1881
+ * @param {string} eventId - The id of the event to view.
1882
+ * @return {void}
1883
+ * @memberof DashboardComponent
1884
+ */
1885
+ onViewEvent(eventId) {
1886
+ this.emitNavigation(this.activeRouteConfig.eventDetail, eventId);
1887
+ }
1888
+ /**
1889
+ * Emits the open-meeting navigation intent, targeting the `meetingDetail`
1890
+ * route with the meeting id (Req 7.4, 11.1).
1891
+ * @param {string} meetingId - The id of the meeting to open.
1892
+ * @return {void}
1893
+ * @memberof DashboardComponent
1894
+ */
1895
+ onOpenMeeting(meetingId) {
1896
+ this.emitNavigation(this.activeRouteConfig.meetingDetail, meetingId);
1897
+ }
1898
+ /**
1899
+ * Emits the "View All" groups navigation intent, targeting the
1900
+ * `viewAllGroups` route with no id (Req 8.2, 11.1).
1901
+ * @return {void}
1902
+ * @memberof DashboardComponent
1903
+ */
1904
+ onViewAllGroups() {
1905
+ this.emitNavigation(this.activeRouteConfig.viewAllGroups);
1906
+ }
1907
+ /**
1908
+ * Emits the group-detail navigation intent, targeting the `groupDetail` route
1909
+ * with the group id (Req 8.7, 11.1).
1910
+ * @param {string} groupId - The id of the selected group.
1911
+ * @return {void}
1912
+ * @memberof DashboardComponent
1913
+ */
1914
+ onGroupSelected(groupId) {
1915
+ this.emitNavigation(this.activeRouteConfig.groupDetail, groupId);
1916
+ }
1917
+ /**
1918
+ * Updates the groups table paging state in response to a paginator change so
1919
+ * the groups section reflects the requested page (Req 8.10).
1920
+ * @param {PageChange} page - The requested page index and size.
1921
+ * @return {void}
1922
+ * @memberof DashboardComponent
1923
+ */
1924
+ onGroupsPageChange(page) {
1925
+ this.groupsPageIndex = page.pageIndex;
1926
+ this.groupsPageSize = page.pageSize;
1927
+ }
1928
+ /**
1929
+ * Delegates a log-attendance request to the service, surfacing the
1930
+ * attendance-action error message via the shared {@link AlertsService} on
1931
+ * failure while the service retains the prior displayed state (Req 7.7, 13.7).
1932
+ * @param {string} meetingId - The meeting to log attendance for.
1933
+ * @return {void}
1934
+ * @memberof DashboardComponent
1935
+ */
1936
+ onLogAttendance(meetingId) {
1937
+ this.dashboardService
1938
+ .logAttendance(meetingId)
1939
+ .pipe(takeUntil(this.destroy$))
1940
+ .subscribe({
1941
+ error: () => this.showAttendanceError(),
1942
+ });
1943
+ }
1944
+ /**
1945
+ * Delegates a leave-meeting request to the service, surfacing the
1946
+ * attendance-action error message via the shared {@link AlertsService} on
1947
+ * failure while the service retains the prior displayed state (Req 7.8, 13.7).
1948
+ * @param {string} meetingId - The meeting to leave.
1949
+ * @return {void}
1950
+ * @memberof DashboardComponent
1951
+ */
1952
+ onLeaveMeeting(meetingId) {
1953
+ this.dashboardService
1954
+ .leaveMeeting(meetingId)
1955
+ .pipe(takeUntil(this.destroy$))
1956
+ .subscribe({
1957
+ error: () => this.showAttendanceError(),
1958
+ });
1959
+ }
1960
+ /**
1961
+ * The route configuration in effect: the host-supplied `routePaths` when
1962
+ * provided, otherwise the default route config from `constants.json` so
1963
+ * navigation intents always carry valid targets (Req 11.1, 11.5).
1964
+ * @return {DashboardRouteConfig} The active route configuration.
1965
+ * @memberof DashboardComponent
1966
+ */
1967
+ get activeRouteConfig() {
1968
+ return this.routePaths ?? this.constants.defaultRouteConfig;
1969
+ }
1970
+ /**
1971
+ * Subscribes to the service's state observables, mirroring each into a local
1972
+ * field for the template to bind. All subscriptions are torn down via
1973
+ * `takeUntil(destroy$)` (Req 13.1, 13.2, 13.5).
1974
+ * @return {void}
1975
+ * @memberof DashboardComponent
1976
+ */
1977
+ subscribeToServiceState() {
1978
+ this.dashboardService.upcomingEvents$
1979
+ .pipe(takeUntil(this.destroy$))
1980
+ .subscribe((events) => (this.upcomingEvents = events));
1981
+ this.dashboardService.groups$
1982
+ .pipe(takeUntil(this.destroy$))
1983
+ .subscribe((groups) => {
1984
+ this.groups = groups;
1985
+ });
1986
+ this.dashboardService.upcomingState$
1987
+ .pipe(takeUntil(this.destroy$))
1988
+ .subscribe((state) => (this.upcomingState = state));
1989
+ this.dashboardService.groupsState$
1990
+ .pipe(takeUntil(this.destroy$))
1991
+ .subscribe((state) => (this.groupsState = state));
1992
+ this.dashboardService.attendanceStates$
1993
+ .pipe(takeUntil(this.destroy$))
1994
+ .subscribe((states) => (this.attendanceStates = states));
1995
+ this.dashboardService.inFlightMeetingIds$
1996
+ .pipe(takeUntil(this.destroy$))
1997
+ .subscribe((ids) => (this.inFlightMeetingIds = ids));
1998
+ }
1999
+ /**
2000
+ * Subscribes to the Presentation_Library breakpoint observer to keep
2001
+ * `isMobileView` in sync with the viewport (Req 15.1, 15.2).
2002
+ * @return {void}
2003
+ * @memberof DashboardComponent
2004
+ */
2005
+ subscribeToBreakpoint() {
2006
+ this.breakpointObserverService
2007
+ .getBreakpoint()
2008
+ .pipe(takeUntil(this.destroy$))
2009
+ .subscribe((result) => {
2010
+ this.isMobileView = result?.matches;
2011
+ });
2012
+ }
2013
+ /**
2014
+ * Triggers the upcoming-events load, setting the section to `ERROR` on failure
2015
+ * so only the section error region renders (Req 13.1, 13.2, 13.5).
2016
+ * @return {void}
2017
+ * @memberof DashboardComponent
2018
+ */
2019
+ loadUpcomingEvents() {
2020
+ this.dashboardService
2021
+ .loadUpcomingEvents()
2022
+ .pipe(takeUntil(this.destroy$))
2023
+ .subscribe({
2024
+ error: () => (this.upcomingState = DashboardSectionState.ERROR),
2025
+ });
2026
+ }
2027
+ /**
2028
+ * Triggers the groups load, setting the section to `ERROR` on failure so only
2029
+ * the section error region renders. Isolated from the upcoming-events load so
2030
+ * one failing does not affect the other (Req 13.1, 13.2, 13.5).
2031
+ * @return {void}
2032
+ * @memberof DashboardComponent
2033
+ */
2034
+ loadGroups() {
2035
+ this.dashboardService
2036
+ .loadGroups()
2037
+ .pipe(takeUntil(this.destroy$))
2038
+ .subscribe({
2039
+ error: () => (this.groupsState = DashboardSectionState.ERROR),
2040
+ });
2041
+ }
2042
+ /**
2043
+ * Composes and emits a {@link DashboardNavigationIntent} for the host from the
2044
+ * resolved target path and an optional triggering id (Req 11.1).
2045
+ * @param {string} path - The resolved target route path.
2046
+ * @param {string} [id] - The triggering identifier, when applicable.
2047
+ * @return {void}
2048
+ * @memberof DashboardComponent
2049
+ */
2050
+ emitNavigation(path, id) {
2051
+ this.dashboardNavigate.emit(id ? { path, id } : { path });
2052
+ }
2053
+ /**
2054
+ * Surfaces the attendance-action error message from `constants.json` via the
2055
+ * shared {@link AlertsService} (Req 13.7).
2056
+ * @return {void}
2057
+ * @memberof DashboardComponent
2058
+ */
2059
+ showAttendanceError() {
2060
+ this.alertService?.showMessage({
2061
+ status: 'custom',
2062
+ message: this.constants?.attendance?.errorMessage ??
2063
+ 'Unable to update your attendance. Please try again.',
2064
+ alertType: AlertType.ERROR,
2065
+ isCloseNeeded: true,
2066
+ });
2067
+ }
2068
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardComponent, deps: [{ token: DashboardService }, { token: UserPermissionsService }, { token: i3.BreakpointObserverService }, { token: i1$1.AlertsService }], target: i0.ɵɵFactoryTarget.Component }); }
2069
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DashboardComponent, isStandalone: true, selector: "ieeesa-dashboard", inputs: { routePaths: "routePaths", apiBaseURL: "apiBaseURL", userInfo: "userInfo", userPermissions: "userPermissions" }, outputs: { dashboardNavigate: "dashboardNavigate" }, providers: [AlertsService], ngImport: i0, template: "<div\r\n class=\"ieeesa-dashboard\"\r\n [ngClass]=\"{ 'ieeesa-dashboard--mobile': isMobileView }\"\r\n>\r\n <ieeesa-dashboard-welcome-header\r\n [userName]=\"userInfo?.name ?? ''\"\r\n [meetingsCount]=\"meetingsCount\"\r\n [groupsCount]=\"groupsCount\"\r\n (shortcutSelected)=\"onJumpToShortcut($event)\"\r\n ></ieeesa-dashboard-welcome-header>\r\n\r\n <main class=\"ieeesa-dashboard__content\">\r\n <ieeesa-upcoming-meetings-events\r\n class=\"ieeesa-dashboard__upcoming\"\r\n [events]=\"upcomingEvents\"\r\n [sectionState]=\"upcomingState\"\r\n [permissions]=\"attendancePermissions\"\r\n [attendanceStates]=\"attendanceStates\"\r\n [inFlightMeetingIds]=\"inFlightMeetingIds\"\r\n [isMobileView]=\"isMobileView\"\r\n (viewAll)=\"onViewAllEvents()\"\r\n (viewEvent)=\"onViewEvent($event)\"\r\n (openMeeting)=\"onOpenMeeting($event)\"\r\n (logAttendance)=\"onLogAttendance($event)\"\r\n (leaveMeeting)=\"onLeaveMeeting($event)\"\r\n ></ieeesa-upcoming-meetings-events>\r\n\r\n <ieeesa-your-groups\r\n [groups]=\"groups | slice: (groupsPageIndex * groupsPageSize) : ((groupsPageIndex + 1) * groupsPageSize)\"\r\n [sectionState]=\"groupsState\"\r\n [totalGroups]=\"groups.length\"\r\n [pageIndex]=\"groupsPageIndex\"\r\n [pageSize]=\"groupsPageSize\"\r\n (groupSelected)=\"onGroupSelected($event)\"\r\n (viewAllGroups)=\"onViewAllGroups()\"\r\n (pageChange)=\"onGroupsPageChange($event)\"\r\n ></ieeesa-your-groups>\r\n </main>\r\n</div>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-dashboard{display:flex;flex-direction:column;gap:24px;padding:16px}.ieeesa-dashboard__content{display:flex;flex-direction:column;gap:24px}.ieeesa-dashboard__welcome,.ieeesa-dashboard__upcoming,.ieeesa-dashboard__groups,.ieeesa-dashboard__footer{display:block}.ieeesa-dashboard--mobile{padding:8px;gap:16px}.ieeesa-dashboard--mobile .ieeesa-dashboard__content{gap:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.SlicePipe, name: "slice" }, { kind: "component", type: UpcomingMeetingsEventsComponent, selector: "ieeesa-upcoming-meetings-events", inputs: ["events", "sectionState", "permissions", "attendanceStates", "inFlightMeetingIds", "isMobileView"], outputs: ["viewAll", "viewEvent", "openMeeting", "logAttendance", "leaveMeeting", "meetingPageChange"] }, { kind: "component", type: YourGroupsComponent, selector: "ieeesa-your-groups", inputs: ["groups", "sectionState", "totalGroups", "pageIndex", "pageSize"], outputs: ["groupSelected", "viewAllGroups", "pageChange"] }, { kind: "component", type: DashboardWelcomeHeaderComponent, selector: "ieeesa-dashboard-welcome-header", inputs: ["userName", "meetingsCount", "groupsCount"], outputs: ["shortcutSelected"] }], encapsulation: i0.ViewEncapsulation.None }); }
2070
+ }
2071
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardComponent, decorators: [{
2072
+ type: Component,
2073
+ args: [{ selector: 'ieeesa-dashboard', standalone: true, imports: [
2074
+ CommonModule,
2075
+ UpcomingMeetingsEventsComponent,
2076
+ YourGroupsComponent,
2077
+ DashboardWelcomeHeaderComponent
2078
+ ], encapsulation: ViewEncapsulation.None, providers: [AlertsService], template: "<div\r\n class=\"ieeesa-dashboard\"\r\n [ngClass]=\"{ 'ieeesa-dashboard--mobile': isMobileView }\"\r\n>\r\n <ieeesa-dashboard-welcome-header\r\n [userName]=\"userInfo?.name ?? ''\"\r\n [meetingsCount]=\"meetingsCount\"\r\n [groupsCount]=\"groupsCount\"\r\n (shortcutSelected)=\"onJumpToShortcut($event)\"\r\n ></ieeesa-dashboard-welcome-header>\r\n\r\n <main class=\"ieeesa-dashboard__content\">\r\n <ieeesa-upcoming-meetings-events\r\n class=\"ieeesa-dashboard__upcoming\"\r\n [events]=\"upcomingEvents\"\r\n [sectionState]=\"upcomingState\"\r\n [permissions]=\"attendancePermissions\"\r\n [attendanceStates]=\"attendanceStates\"\r\n [inFlightMeetingIds]=\"inFlightMeetingIds\"\r\n [isMobileView]=\"isMobileView\"\r\n (viewAll)=\"onViewAllEvents()\"\r\n (viewEvent)=\"onViewEvent($event)\"\r\n (openMeeting)=\"onOpenMeeting($event)\"\r\n (logAttendance)=\"onLogAttendance($event)\"\r\n (leaveMeeting)=\"onLeaveMeeting($event)\"\r\n ></ieeesa-upcoming-meetings-events>\r\n\r\n <ieeesa-your-groups\r\n [groups]=\"groups | slice: (groupsPageIndex * groupsPageSize) : ((groupsPageIndex + 1) * groupsPageSize)\"\r\n [sectionState]=\"groupsState\"\r\n [totalGroups]=\"groups.length\"\r\n [pageIndex]=\"groupsPageIndex\"\r\n [pageSize]=\"groupsPageSize\"\r\n (groupSelected)=\"onGroupSelected($event)\"\r\n (viewAllGroups)=\"onViewAllGroups()\"\r\n (pageChange)=\"onGroupsPageChange($event)\"\r\n ></ieeesa-your-groups>\r\n </main>\r\n</div>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-dashboard{display:flex;flex-direction:column;gap:24px;padding:16px}.ieeesa-dashboard__content{display:flex;flex-direction:column;gap:24px}.ieeesa-dashboard__welcome,.ieeesa-dashboard__upcoming,.ieeesa-dashboard__groups,.ieeesa-dashboard__footer{display:block}.ieeesa-dashboard--mobile{padding:8px;gap:16px}.ieeesa-dashboard--mobile .ieeesa-dashboard__content{gap:16px}\n"] }]
2079
+ }], ctorParameters: function () { return [{ type: DashboardService }, { type: UserPermissionsService }, { type: i3.BreakpointObserverService }, { type: i1$1.AlertsService }]; }, propDecorators: { routePaths: [{
2080
+ type: Input
2081
+ }], apiBaseURL: [{
2082
+ type: Input
2083
+ }], userInfo: [{
2084
+ type: Input
2085
+ }], userPermissions: [{
2086
+ type: Input
2087
+ }], dashboardNavigate: [{
2088
+ type: Output
2089
+ }] } });
2090
+
2091
+ var dashboard_component = /*#__PURE__*/Object.freeze({
2092
+ __proto__: null,
2093
+ DashboardComponent: DashboardComponent
2094
+ });
2095
+
2096
+ /**
2097
+ * Member_Level_Badge renders a single member-level value as a colored pill.
2098
+ * It reuses the Presentation_Library Legend component for the pill primitive,
2099
+ * sourcing the level-to-color mapping from `constants.json` (`memberLevel.colorMap`)
2100
+ * with a nullish-coalescing fallback to the configured default color.
2101
+ * @export
2102
+ * @class MemberLevelBadgeComponent
2103
+ */
2104
+ class MemberLevelBadgeComponent {
2105
+ constructor() {
2106
+ this.constants = constants$1;
2107
+ this.memberLevelValue = '';
2108
+ /** The Legend input consumed by the Presentation_Library Legend component. */
2109
+ this.legends = this.buildLegends('');
2110
+ }
2111
+ set memberLevel(value) {
2112
+ this.memberLevelValue = value ?? '';
2113
+ this.legends = this.buildLegends(this.memberLevelValue);
2114
+ }
2115
+ get memberLevel() {
2116
+ return this.memberLevelValue;
2117
+ }
2118
+ /**
2119
+ * Builds the single-item Legend list for the supplied member level, resolving
2120
+ * the pill color from the `constants.json` color map and falling back to the
2121
+ * configured default color when the level has no explicit mapping.
2122
+ * @param {string} memberLevel - The member-level label to render.
2123
+ * @return {Legend[]} A single-element Legend array for the Legend component.
2124
+ * @memberof MemberLevelBadgeComponent
2125
+ */
2126
+ buildLegends(memberLevel) {
2127
+ return [
2128
+ {
2129
+ label: memberLevel,
2130
+ color: this.resolveColorClass(memberLevel),
2131
+ hierarchy: 0,
2132
+ },
2133
+ ];
2134
+ }
2135
+ /**
2136
+ * Resolves the CSS modifier class for a member level from the `constants.json`
2137
+ * color map, using the `??` fallback to the `default` entry when the level is
2138
+ * missing from the map.
2139
+ * @param {string} memberLevel - The member-level label to resolve a color for.
2140
+ * @return {string} The CSS modifier class applied to the pill.
2141
+ * @memberof MemberLevelBadgeComponent
2142
+ */
2143
+ resolveColorClass(memberLevel) {
2144
+ const colorMap = this.constants?.memberLevel?.colorMap;
2145
+ const token = colorMap?.[memberLevel] ?? colorMap?.['default'] ?? '$ieeesa-color-neutral';
2146
+ return this.toColorClass(token);
2147
+ }
2148
+ /**
2149
+ * Converts a shared-styles color token (for example `$ieeesa-color-success`)
2150
+ * into a valid BEM-style CSS modifier class defined in this component's SCSS.
2151
+ * @param {string} token - The color token from the color map.
2152
+ * @return {string} A valid CSS class name.
2153
+ * @memberof MemberLevelBadgeComponent
2154
+ */
2155
+ toColorClass(token) {
2156
+ const normalized = token.replace(/^\$ieeesa-color-/, '').replace(/^\$/, '');
2157
+ return `ieeesa-member-level-badge--${normalized || 'neutral'}`;
2158
+ }
2159
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MemberLevelBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2160
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MemberLevelBadgeComponent, isStandalone: true, selector: "ieeesa-member-level-badge", inputs: { memberLevel: "memberLevel" }, ngImport: i0, template: "<span\r\n class=\"ieeesa-member-level-badge\"\r\n [attr.aria-label]=\"memberLevel\"\r\n>\r\n <ieeesa-legend\r\n *ngIf=\"memberLevel\"\r\n [legends]=\"legends\"\r\n ></ieeesa-legend>\r\n</span>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-member-level-badge,.ieeesa-member-level-badge .ieeesa-legend{display:inline-flex}.ieeesa-member-level-badge .ieeesa-legend__indicator{align-items:center;gap:4px;padding:4px 12px;border-radius:16px;background-color:#f0f5f9}.ieeesa-member-level-badge .ieeesa-legend__square{width:8px;min-width:8px;height:8px;margin:0;border-radius:50%}.ieeesa-member-level-badge .ieeesa-legend p{margin:0}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--success{background-color:#78d7ef}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--info{background-color:#00b5e2}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--warning{background-color:#ffd92e}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--primary{background-color:#00629b}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--neutral{background-color:#939094}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LegendComponent, selector: "ieeesa-legend", inputs: ["legends", "isSorting"] }], encapsulation: i0.ViewEncapsulation.None }); }
2161
+ }
2162
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MemberLevelBadgeComponent, decorators: [{
2163
+ type: Component,
2164
+ args: [{ selector: 'ieeesa-member-level-badge', standalone: true, imports: [CommonModule, LegendComponent], encapsulation: ViewEncapsulation.None, template: "<span\r\n class=\"ieeesa-member-level-badge\"\r\n [attr.aria-label]=\"memberLevel\"\r\n>\r\n <ieeesa-legend\r\n *ngIf=\"memberLevel\"\r\n [legends]=\"legends\"\r\n ></ieeesa-legend>\r\n</span>\r\n", styles: [".ieeesa-subtitle{text-align:left;font-family:Calibri Regular;font-size:1.5625rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-body{text-align:left;font-family:Calibri Regular;font-size:1.25rem;letter-spacing:0;color:#000;opacity:1}.ieeesa-display-lg-57{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:3.5625rem;line-height:64px;color:#000;letter-spacing:0}.ieeesa-display-md-45{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.813rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-md-47{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.9375rem;line-height:52px;color:#000;letter-spacing:0}.ieeesa-display-sm-38{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.375rem;line-height:44px;color:#000;letter-spacing:0}.ieeesa-headline-lg-32{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-lg-34{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:2.125rem;line-height:40px;color:#000;letter-spacing:0}.ieeesa-headline-md-30{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.875rem;line-height:36px;color:#000;letter-spacing:0}.ieeesa-headline-sm-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:32px;color:#00629b;letter-spacing:0}.ieeesa-headline-sm-26{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.625rem;line-height:32px;color:#000;letter-spacing:0}.ieeesa-title-lg-bold-24{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-lg-24{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.5rem;line-height:28px;color:#000;letter-spacing:0}.ieeesa-title-md-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.009375em}.ieeesa-title-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-title-sm-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-label-lg-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.ieeesa-btn-label-lg-bold-16{font-family:Calibri Regular;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#00629b;letter-spacing:.00625em}.ieeesa-label-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-label-sm-13{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.8125rem;line-height:16px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-16{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-bold-18{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-lg-18{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1.125rem;line-height:24px;color:#000;letter-spacing:.03125em}.ieeesa-body-md-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:20px;color:#1c1b1f;letter-spacing:.015625em}.ieeesa-body-md-16{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:20px;color:#000;letter-spacing:.015625em}.ieeesa-body-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-sm-12{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.75rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-body-color-sm-14{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:.875rem;line-height:18px;color:#49454f;letter-spacing:.025em}.ieeesa-body-sm-bold-14{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:.875rem;line-height:16px;color:#000;letter-spacing:.025em}.ieeesa-title-inter-lg-bold-24{font-family:Inter Bold;font-style:normal;font-weight:700;font-size:1.5rem;line-height:29px;color:#000;letter-spacing:0}.mat-mdc-button.mat-mdc-button-base.mat-primary-button,.mat-mdc-button.mat-mdc-button-base.mat-secondary-button,.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button,.mat-mdc-button.mat-mdc-button-base.mat-text-button{min-width:103px;width:auto;min-height:40px;height:auto;border-radius:3px;text-align:center;padding:.625em 1.5em;border:none;font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#000;letter-spacing:.00625em}.mat-mdc-button.mat-mdc-button-base>.mat-icon{margin-right:11px}.mat-mdc-button.mat-mdc-button-base.mat-primary-button{background-color:#00629b;color:#fff}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:focus{background:#1f75a7}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:hover{background-color:#003e65}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:active{background-color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-primary-button:disabled{background-color:#1c1b1f1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button{color:#fff;background:#a7a8aa;box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:hover{background:#a7a8aa}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:focus{background:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:active{background:#1d192b1f}.mat-mdc-button.mat-mdc-button-base.mat-secondary-button:disabled{background:#1c1b1f1f;color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button{background-color:#fff;border:1px solid #00629b;color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:hover{background-color:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:focus{background-color:#f0f5f9}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:active{background:#6750a41f}.mat-mdc-button.mat-mdc-button-base.mat-tertiary-button:disabled{border:1px solid rgba(28,27,31,.12);color:#1c1b1f;opacity:.38}.mat-mdc-button.mat-mdc-button-base.mat-text-button{color:#00629b}.mat-mdc-button.mat-mdc-button-base.mat-text-button:hover,.mat-mdc-button.mat-mdc-button-base.mat-text-button:active{background:#6750a414}.mat-mdc-button.mat-mdc-button-base.mat-text-button:disabled{color:#1c1b1f;opacity:.38}.ieeesa-text-button{color:#cac4d0;background:none;border:none}.ieeesa-view-more-or-less-button{border:none;background:none;text-decoration:underline;color:#00629b}.flex-align-center{display:flex;align-items:center;justify-content:center}.mat-button-toggle-checked{background-color:#a7a8aa}.mat-button-toggle-checked .mat-button-toggle-label-content:before{font-family:\"Font Awesome 5 Free\";font-weight:900;content:\"\\f00c\";padding-right:.5625em}.mat-button-toggle-group .mat-button-toggle-label-content{font-family:Calibri Bold;font-style:normal;font-weight:700;font-size:1rem;line-height:20px;color:#1c1b1f;letter-spacing:.00625em}.no-bg-color-btn{color:#00629b;border-radius:3px;border:1px solid #00629b;min-height:40px;height:auto}@media (max-width: 768px){.mat-button-toggle-group .mat-button-toggle-label-content{max-width:8ch;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative}}.cdk-overlay-pane .mat-mdc-tooltip .mdc-tooltip__surface{color:#525252;padding:6px 12px;font-family:Calibri Regular;font-size:1rem;border:1px solid #cac4d0;background:#fff;box-shadow:0 4px 8px #00000040;max-width:unset!important}.cdk-overlay-pane .mat-mdc-option .mdc-list-item__primary-text{font-family:Calibri Regular!important}.cdk-overlay-pane.ieeesa-modal-confirm-dialog,.cdk-overlay-pane.ieeesa-modal-dialog,.cdk-overlay-pane.ieeesa-alert-dialog{width:100%;min-width:312px}.mat-mdc-form-field{font-family:Calibri Regular;font-style:normal;font-weight:400;font-size:1rem;line-height:24px;color:#49454f;letter-spacing:.03125em}.ieeesa-cancel-modal-confirm-dialog{width:25vw!important}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation{padding:1.5em 1.5em 1em}.ieeesa-cancel-modal-confirm-dialog .ieeesa-confirmation .mat-mdc-dialog-content{text-align:center;padding:0 0 1em!important}.mat-mdc-button,.mat-mdc-outlined-button{--mat-mdc-button-persistent-ripple-color: unset}@media (max-width: 768px){.ieeesa-cancel-modal-confirm-dialog{width:90vw!important}}.ieeesa-wrapper-border{border:1px solid #b2b7be;border-top:none;padding:1.5em;border-radius:0 0 4px 4px}.ieeesa-member-level-badge,.ieeesa-member-level-badge .ieeesa-legend{display:inline-flex}.ieeesa-member-level-badge .ieeesa-legend__indicator{align-items:center;gap:4px;padding:4px 12px;border-radius:16px;background-color:#f0f5f9}.ieeesa-member-level-badge .ieeesa-legend__square{width:8px;min-width:8px;height:8px;margin:0;border-radius:50%}.ieeesa-member-level-badge .ieeesa-legend p{margin:0}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--success{background-color:#78d7ef}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--info{background-color:#00b5e2}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--warning{background-color:#ffd92e}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--primary{background-color:#00629b}.ieeesa-member-level-badge .ieeesa-legend__square.ieeesa-member-level-badge--neutral{background-color:#939094}\n"] }]
2165
+ }], propDecorators: { memberLevel: [{
2166
+ type: Input
2167
+ }] } });
2168
+
2169
+ class DashboardModule {
2170
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2171
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: DashboardModule, imports: [DashboardComponent], exports: [DashboardComponent] }); }
2172
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardModule, imports: [DashboardComponent] }); }
2173
+ }
2174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardModule, decorators: [{
2175
+ type: NgModule,
2176
+ args: [{
2177
+ imports: [DashboardComponent],
2178
+ exports: [DashboardComponent],
2179
+ }]
2180
+ }] });
2181
+
2182
+ const DASHBOARD_ROUTES = [
2183
+ {
2184
+ path: '',
2185
+ loadComponent: () => Promise.resolve().then(function () { return dashboard_component; }).then((m) => m.DashboardComponent),
2186
+ },
2187
+ ];
2188
+
2189
+ const DashboardRoutePathsMock = {
2190
+ eventDetail: 'events-and-meetings/view-event',
2191
+ meetingDetail: 'events-and-meetings/view-meeting',
2192
+ // The demo app only registers a flat `groups` route (no group-detail screen),
2193
+ // so group-row navigation targets it rather than a `view-group` child that
2194
+ // the demo does not implement. A consuming app with a real group-detail route
2195
+ // supplies its own path via the `routePaths` input.
2196
+ groupDetail: 'groups',
2197
+ viewAllEvents: 'events-and-meetings/view-events-meetings-list',
2198
+ viewAllGroups: 'groups',
2199
+ };
2200
+
2201
+ const DashboardUserPermissionsMock = [
2202
+ {
2203
+ permissionName: 'View Events',
2204
+ permissionId: 'PERM_5dd65526-5df3-428d-8acc-cee7ffb5f261',
2205
+ },
2206
+ {
2207
+ permissionName: 'View Meetings',
2208
+ permissionId: 'PERM_5dd65526-5df3-428d-8acc-cee7ffb5f261',
2209
+ },
2210
+ {
2211
+ permissionName: 'View Groups',
2212
+ permissionId: 'PERM_9a1f0c84-2b77-4e2a-9f3d-1c6b4e9a8d20',
2213
+ },
2214
+ {
2215
+ permissionName: 'Log Attendance',
2216
+ permissionId: 'PERM_1b2c3d4e-5f60-4718-8293-aabbccddeeff',
2217
+ },
2218
+ {
2219
+ permissionName: 'Leave Meeting',
2220
+ permissionId: 'PERM_6f5e4d3c-2b1a-4908-8716-ffeeddccbbaa',
2221
+ },
2222
+ ];
2223
+
2224
+ /*
2225
+ * Public API Surface of dashboard
2226
+ */
2227
+ // Container component + navigation intent type (DashboardComponent, DashboardNavigationIntent)
2228
+
2229
+ /**
2230
+ * Generated bundle index. Do not edit.
2231
+ */
2232
+
2233
+ export { AttendanceState, DASHBOARD_ROUTES, DashboardComponent, DashboardGroupsMock, DashboardJumpTarget, DashboardModule, DashboardNonActionableMeetingMock, DashboardPermissionType, DashboardRoutePathsMock, DashboardSectionState, DashboardService, DashboardUpcomingEventsMock, DashboardUserPermissionsMock, DashboardWelcomeHeaderComponent, EventGroupCardComponent, MeetingAttendanceRowComponent, MemberLevelBadgeComponent, UpcomingMeetingsEventsComponent, UserPermissionsService, YourGroupsComponent };
2234
+ //# sourceMappingURL=ieeesa-npm-dashboard.mjs.map