@muxima-ui/notification-center 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Notification Center
2
+
3
+ Centro de notificações com painel, toasts e gerenciamento completo.
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ npm install @muxima-ui/notification-center
9
+ ```
10
+
11
+ ## Uso
12
+
13
+ ```typescript
14
+ import { NotificationCenterComponent } from '@muxima-ui/notification-center';
15
+
16
+ @Component({
17
+ standalone: true,
18
+ imports: [NotificationCenterComponent],
19
+ template: `
20
+ <muxima-notification-center
21
+ [notifications]="notifications"
22
+ [position]="'top-right'"
23
+ (notificationRead)="onRead($event)">
24
+ </muxima-notification-center>
25
+ `
26
+ })
27
+ export class MyComponent {
28
+ notifications = [
29
+ {
30
+ id: '1',
31
+ type: 'success',
32
+ title: 'Sucesso!',
33
+ message: 'Operação concluída',
34
+ timestamp: new Date(),
35
+ read: false
36
+ }
37
+ ];
38
+
39
+ onRead(id: string) {
40
+ console.log('Notification read:', id);
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Licença
46
+
47
+ MIT
@@ -0,0 +1,2 @@
1
+ export * from './lib/notification-center/notification-center.component';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9vdmVybGF5L25vdGlmaWNhdGlvbi1jZW50ZXIvc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMseURBQXlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi9ub3RpZmljYXRpb24tY2VudGVyL25vdGlmaWNhdGlvbi1jZW50ZXIuY29tcG9uZW50JztcclxuIl19
@@ -0,0 +1,202 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { trigger, transition, style, animate } from '@angular/animations';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ export class NotificationCenterComponent {
7
+ constructor() {
8
+ this.notifications = [];
9
+ this.position = 'top-right';
10
+ this.maxToasts = 3;
11
+ this.defaultDuration = 5000;
12
+ this.showBadge = true;
13
+ this.groupByCategory = false;
14
+ this.notificationRead = new EventEmitter();
15
+ this.notificationDismissed = new EventEmitter();
16
+ this.notificationAction = new EventEmitter();
17
+ this.allRead = new EventEmitter();
18
+ this.allCleared = new EventEmitter();
19
+ this.isOpen = false;
20
+ this.activeToasts = [];
21
+ this.autoCloseTimers = new Map();
22
+ }
23
+ ngOnDestroy() {
24
+ this.autoCloseTimers.forEach(timer => clearTimeout(timer));
25
+ }
26
+ togglePanel() {
27
+ this.isOpen = !this.isOpen;
28
+ }
29
+ closePanel() {
30
+ this.isOpen = false;
31
+ }
32
+ get unreadCount() {
33
+ return this.notifications.filter(n => !n.read).length;
34
+ }
35
+ get groupedNotifications() {
36
+ if (!this.groupByCategory) {
37
+ return [{ category: 'all', notifications: this.notifications }];
38
+ }
39
+ const groups = new Map();
40
+ this.notifications.forEach(notification => {
41
+ const category = notification.category || 'Outros';
42
+ if (!groups.has(category)) {
43
+ groups.set(category, []);
44
+ }
45
+ groups.get(category).push(notification);
46
+ });
47
+ return Array.from(groups.entries()).map(([category, notifications]) => ({
48
+ category,
49
+ notifications
50
+ }));
51
+ }
52
+ showToast(notification) {
53
+ // Add to active toasts
54
+ if (this.activeToasts.length >= this.maxToasts) {
55
+ this.activeToasts.shift();
56
+ }
57
+ this.activeToasts.push(notification);
58
+ // Auto close if enabled
59
+ if (notification.autoClose !== false) {
60
+ const duration = notification.duration || this.defaultDuration;
61
+ const timer = setTimeout(() => {
62
+ this.dismissToast(notification.id);
63
+ }, duration);
64
+ this.autoCloseTimers.set(notification.id, timer);
65
+ }
66
+ }
67
+ dismissToast(id) {
68
+ const index = this.activeToasts.findIndex(t => t.id === id);
69
+ if (index !== -1) {
70
+ this.activeToasts.splice(index, 1);
71
+ }
72
+ if (this.autoCloseTimers.has(id)) {
73
+ clearTimeout(this.autoCloseTimers.get(id));
74
+ this.autoCloseTimers.delete(id);
75
+ }
76
+ }
77
+ markAsRead(notification) {
78
+ if (!notification.read) {
79
+ notification.read = true;
80
+ this.notificationRead.emit(notification.id);
81
+ }
82
+ }
83
+ markAllAsRead() {
84
+ this.notifications.forEach(n => n.read = true);
85
+ this.allRead.emit();
86
+ }
87
+ dismissNotification(notification, event) {
88
+ event?.stopPropagation();
89
+ const index = this.notifications.indexOf(notification);
90
+ if (index !== -1) {
91
+ this.notifications.splice(index, 1);
92
+ this.notificationDismissed.emit(notification.id);
93
+ }
94
+ }
95
+ clearAll() {
96
+ this.notifications.length = 0;
97
+ this.allCleared.emit();
98
+ }
99
+ executeAction(notification, event) {
100
+ event?.stopPropagation();
101
+ if (notification.actionCallback) {
102
+ notification.actionCallback();
103
+ }
104
+ this.notificationAction.emit(notification);
105
+ this.markAsRead(notification);
106
+ }
107
+ getIcon(type) {
108
+ const icons = {
109
+ success: '✅',
110
+ info: 'ℹ️',
111
+ warning: '⚠️',
112
+ error: '❌'
113
+ };
114
+ return icons[type];
115
+ }
116
+ formatTimestamp(date) {
117
+ const now = new Date();
118
+ const diff = now.getTime() - date.getTime();
119
+ const minutes = Math.floor(diff / 60000);
120
+ const hours = Math.floor(diff / 3600000);
121
+ const days = Math.floor(diff / 86400000);
122
+ if (minutes < 1)
123
+ return 'Agora';
124
+ if (minutes < 60)
125
+ return `${minutes}m atrás`;
126
+ if (hours < 24)
127
+ return `${hours}h atrás`;
128
+ if (days < 7)
129
+ return `${days}d atrás`;
130
+ return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });
131
+ }
132
+ get positionClass() {
133
+ return `position-${this.position}`;
134
+ }
135
+ }
136
+ NotificationCenterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NotificationCenterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
137
+ NotificationCenterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NotificationCenterComponent, isStandalone: true, selector: "muxima-notification-center", inputs: { notifications: "notifications", position: "position", maxToasts: "maxToasts", defaultDuration: "defaultDuration", showBadge: "showBadge", groupByCategory: "groupByCategory" }, outputs: { notificationRead: "notificationRead", notificationDismissed: "notificationDismissed", notificationAction: "notificationAction", allRead: "allRead", allCleared: "allCleared" }, ngImport: i0, template: "<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">\uD83D\uDD14</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notifica\u00E7\u00F5es</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>\u2713</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>\uD83D\uDDD1\uFE0F</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">\uD83D\uDD15</div>\r\n <p>Nenhuma notifica\u00E7\u00E3o</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n", styles: [".notification-bell{position:relative;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:50%;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 8px #667eea4d}.notification-bell:hover{transform:scale(1.1);box-shadow:0 6px 12px #667eea66}.notification-bell:active{transform:scale(.95)}.notification-bell .bell-icon{font-size:1.5rem;animation:ring 2s ease-in-out infinite}.notification-bell .badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 4px;background:#ef4444;color:#fff;font-size:.75rem;font-weight:700;border-radius:10px;display:flex;align-items:center;justify-content:center;border:2px solid white;animation:pulse 2s ease-in-out infinite}@keyframes ring{0%,to{transform:rotate(0)}10%,30%{transform:rotate(-10deg)}20%,40%{transform:rotate(10deg)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}.notification-panel{position:fixed;top:60px;right:20px;width:400px;max-height:600px;background:white;border-radius:12px;box-shadow:0 10px 25px #0003;transform:translateY(-20px);opacity:0;pointer-events:none;transition:all .3s ease;z-index:1000;display:flex;flex-direction:column}.notification-panel.open{transform:translateY(0);opacity:1;pointer-events:all}.panel-header{padding:1.25rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:space-between}.panel-header h3{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.panel-header .header-actions{display:flex;gap:.5rem}.panel-header .action-btn{padding:.5rem;background:transparent;border:none;color:#6b7280;font-size:1rem;cursor:pointer;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.panel-header .action-btn:hover{background:#f3f4f6;color:#667eea}.panel-header .action-btn.close-btn:hover{color:#ef4444}.panel-body{flex:1;overflow-y:auto;max-height:500px}.panel-body::-webkit-scrollbar{width:6px}.panel-body::-webkit-scrollbar-track{background:#f3f4f6}.panel-body::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:3px}.empty-state{padding:3rem 1.5rem;text-align:center}.empty-state .empty-icon{font-size:3rem;margin-bottom:1rem;opacity:.5}.empty-state p{color:#9ca3af;font-size:1rem}.notification-group .group-title{padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;color:#667eea;text-transform:uppercase;letter-spacing:.05em;background:#f9fafb;border-bottom:1px solid #e5e7eb;margin:0}.notification-item{display:flex;gap:1rem;padding:1rem 1.25rem;border-bottom:1px solid #e5e7eb;cursor:pointer;transition:all .2s ease;position:relative}.notification-item:last-child{border-bottom:none}.notification-item:hover{background:#f9fafb}.notification-item.unread{background:rgba(102,126,234,.05)}.notification-item.unread:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.notification-item.type-success .notification-icon{color:#10b981}.notification-item.type-info .notification-icon{color:#3b82f6}.notification-item.type-warning .notification-icon{color:#f59e0b}.notification-item.type-error .notification-icon{color:#ef4444}.notification-item .notification-icon{font-size:1.5rem;flex-shrink:0}.notification-item .notification-content{flex:1;min-width:0}.notification-item .notification-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}.notification-item .notification-title{font-size:.875rem;font-weight:600;color:#111827;margin:0}.notification-item .notification-time{font-size:.75rem;color:#9ca3af;white-space:nowrap}.notification-item .notification-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.notification-item .notification-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.notification-item .notification-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.notification-item .dismiss-btn{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.notification-item .dismiss-btn:hover{background:#f3f4f6;color:#ef4444}.toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:1rem;pointer-events:none}.toast-container.position-top-right{top:20px;right:20px}.toast-container.position-top-left{top:20px;left:20px}.toast-container.position-bottom-right{bottom:20px;right:20px}.toast-container.position-bottom-left{bottom:20px;left:20px}.toast-container.position-top-center{top:20px;left:50%;transform:translate(-50%)}.toast-container.position-bottom-center{bottom:20px;left:50%;transform:translate(-50%)}.toast-notification{display:flex;align-items:flex-start;gap:1rem;min-width:350px;max-width:450px;padding:1rem 1.25rem;background:white;border-radius:12px;box-shadow:0 10px 25px #00000026;pointer-events:all;border-left:4px solid}.toast-notification.type-success{border-left-color:#10b981}.toast-notification.type-success .toast-icon{color:#10b981}.toast-notification.type-info{border-left-color:#3b82f6}.toast-notification.type-info .toast-icon{color:#3b82f6}.toast-notification.type-warning{border-left-color:#f59e0b}.toast-notification.type-warning .toast-icon{color:#f59e0b}.toast-notification.type-error{border-left-color:#ef4444}.toast-notification.type-error .toast-icon{color:#ef4444}.toast-notification .toast-icon{font-size:1.5rem;flex-shrink:0}.toast-notification .toast-content{flex:1;min-width:0}.toast-notification .toast-title{font-size:.875rem;font-weight:600;color:#111827;margin:0 0 .25rem}.toast-notification .toast-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.toast-notification .toast-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.toast-notification .toast-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.toast-notification .toast-close{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.toast-notification .toast-close:hover{background:#f3f4f6;color:#ef4444}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:999;animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media (max-width: 768px){.notification-panel{right:10px;left:10px;width:auto}.toast-notification{min-width:300px;max-width:350px}.toast-container.position-top-right,.toast-container.position-top-left,.toast-container.position-top-center{top:10px;left:10px;right:10px;transform:none}.toast-container.position-bottom-right,.toast-container.position-bottom-left,.toast-container.position-bottom-center{bottom:10px;left:10px;right:10px;transform:none}}\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"] }], animations: [
138
+ trigger('slideIn', [
139
+ transition(':enter', [
140
+ style({ transform: 'translateX(100%)', opacity: 0 }),
141
+ animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
142
+ ]),
143
+ transition(':leave', [
144
+ animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
145
+ ])
146
+ ]),
147
+ trigger('slideDown', [
148
+ transition(':enter', [
149
+ style({ height: 0, opacity: 0 }),
150
+ animate('200ms ease-out', style({ height: '*', opacity: 1 }))
151
+ ]),
152
+ transition(':leave', [
153
+ animate('200ms ease-in', style({ height: 0, opacity: 0 }))
154
+ ])
155
+ ])
156
+ ] });
157
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NotificationCenterComponent, decorators: [{
158
+ type: Component,
159
+ args: [{ selector: 'muxima-notification-center', standalone: true, imports: [CommonModule], animations: [
160
+ trigger('slideIn', [
161
+ transition(':enter', [
162
+ style({ transform: 'translateX(100%)', opacity: 0 }),
163
+ animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
164
+ ]),
165
+ transition(':leave', [
166
+ animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
167
+ ])
168
+ ]),
169
+ trigger('slideDown', [
170
+ transition(':enter', [
171
+ style({ height: 0, opacity: 0 }),
172
+ animate('200ms ease-out', style({ height: '*', opacity: 1 }))
173
+ ]),
174
+ transition(':leave', [
175
+ animate('200ms ease-in', style({ height: 0, opacity: 0 }))
176
+ ])
177
+ ])
178
+ ], template: "<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">\uD83D\uDD14</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notifica\u00E7\u00F5es</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>\u2713</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>\uD83D\uDDD1\uFE0F</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">\uD83D\uDD15</div>\r\n <p>Nenhuma notifica\u00E7\u00E3o</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n", styles: [".notification-bell{position:relative;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:50%;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 8px #667eea4d}.notification-bell:hover{transform:scale(1.1);box-shadow:0 6px 12px #667eea66}.notification-bell:active{transform:scale(.95)}.notification-bell .bell-icon{font-size:1.5rem;animation:ring 2s ease-in-out infinite}.notification-bell .badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 4px;background:#ef4444;color:#fff;font-size:.75rem;font-weight:700;border-radius:10px;display:flex;align-items:center;justify-content:center;border:2px solid white;animation:pulse 2s ease-in-out infinite}@keyframes ring{0%,to{transform:rotate(0)}10%,30%{transform:rotate(-10deg)}20%,40%{transform:rotate(10deg)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}.notification-panel{position:fixed;top:60px;right:20px;width:400px;max-height:600px;background:white;border-radius:12px;box-shadow:0 10px 25px #0003;transform:translateY(-20px);opacity:0;pointer-events:none;transition:all .3s ease;z-index:1000;display:flex;flex-direction:column}.notification-panel.open{transform:translateY(0);opacity:1;pointer-events:all}.panel-header{padding:1.25rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:space-between}.panel-header h3{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.panel-header .header-actions{display:flex;gap:.5rem}.panel-header .action-btn{padding:.5rem;background:transparent;border:none;color:#6b7280;font-size:1rem;cursor:pointer;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.panel-header .action-btn:hover{background:#f3f4f6;color:#667eea}.panel-header .action-btn.close-btn:hover{color:#ef4444}.panel-body{flex:1;overflow-y:auto;max-height:500px}.panel-body::-webkit-scrollbar{width:6px}.panel-body::-webkit-scrollbar-track{background:#f3f4f6}.panel-body::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:3px}.empty-state{padding:3rem 1.5rem;text-align:center}.empty-state .empty-icon{font-size:3rem;margin-bottom:1rem;opacity:.5}.empty-state p{color:#9ca3af;font-size:1rem}.notification-group .group-title{padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;color:#667eea;text-transform:uppercase;letter-spacing:.05em;background:#f9fafb;border-bottom:1px solid #e5e7eb;margin:0}.notification-item{display:flex;gap:1rem;padding:1rem 1.25rem;border-bottom:1px solid #e5e7eb;cursor:pointer;transition:all .2s ease;position:relative}.notification-item:last-child{border-bottom:none}.notification-item:hover{background:#f9fafb}.notification-item.unread{background:rgba(102,126,234,.05)}.notification-item.unread:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.notification-item.type-success .notification-icon{color:#10b981}.notification-item.type-info .notification-icon{color:#3b82f6}.notification-item.type-warning .notification-icon{color:#f59e0b}.notification-item.type-error .notification-icon{color:#ef4444}.notification-item .notification-icon{font-size:1.5rem;flex-shrink:0}.notification-item .notification-content{flex:1;min-width:0}.notification-item .notification-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}.notification-item .notification-title{font-size:.875rem;font-weight:600;color:#111827;margin:0}.notification-item .notification-time{font-size:.75rem;color:#9ca3af;white-space:nowrap}.notification-item .notification-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.notification-item .notification-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.notification-item .notification-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.notification-item .dismiss-btn{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.notification-item .dismiss-btn:hover{background:#f3f4f6;color:#ef4444}.toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:1rem;pointer-events:none}.toast-container.position-top-right{top:20px;right:20px}.toast-container.position-top-left{top:20px;left:20px}.toast-container.position-bottom-right{bottom:20px;right:20px}.toast-container.position-bottom-left{bottom:20px;left:20px}.toast-container.position-top-center{top:20px;left:50%;transform:translate(-50%)}.toast-container.position-bottom-center{bottom:20px;left:50%;transform:translate(-50%)}.toast-notification{display:flex;align-items:flex-start;gap:1rem;min-width:350px;max-width:450px;padding:1rem 1.25rem;background:white;border-radius:12px;box-shadow:0 10px 25px #00000026;pointer-events:all;border-left:4px solid}.toast-notification.type-success{border-left-color:#10b981}.toast-notification.type-success .toast-icon{color:#10b981}.toast-notification.type-info{border-left-color:#3b82f6}.toast-notification.type-info .toast-icon{color:#3b82f6}.toast-notification.type-warning{border-left-color:#f59e0b}.toast-notification.type-warning .toast-icon{color:#f59e0b}.toast-notification.type-error{border-left-color:#ef4444}.toast-notification.type-error .toast-icon{color:#ef4444}.toast-notification .toast-icon{font-size:1.5rem;flex-shrink:0}.toast-notification .toast-content{flex:1;min-width:0}.toast-notification .toast-title{font-size:.875rem;font-weight:600;color:#111827;margin:0 0 .25rem}.toast-notification .toast-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.toast-notification .toast-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.toast-notification .toast-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.toast-notification .toast-close{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.toast-notification .toast-close:hover{background:#f3f4f6;color:#ef4444}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:999;animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media (max-width: 768px){.notification-panel{right:10px;left:10px;width:auto}.toast-notification{min-width:300px;max-width:350px}.toast-container.position-top-right,.toast-container.position-top-left,.toast-container.position-top-center{top:10px;left:10px;right:10px;transform:none}.toast-container.position-bottom-right,.toast-container.position-bottom-left,.toast-container.position-bottom-center{bottom:10px;left:10px;right:10px;transform:none}}\n"] }]
179
+ }], propDecorators: { notifications: [{
180
+ type: Input
181
+ }], position: [{
182
+ type: Input
183
+ }], maxToasts: [{
184
+ type: Input
185
+ }], defaultDuration: [{
186
+ type: Input
187
+ }], showBadge: [{
188
+ type: Input
189
+ }], groupByCategory: [{
190
+ type: Input
191
+ }], notificationRead: [{
192
+ type: Output
193
+ }], notificationDismissed: [{
194
+ type: Output
195
+ }], notificationAction: [{
196
+ type: Output
197
+ }], allRead: [{
198
+ type: Output
199
+ }], allCleared: [{
200
+ type: Output
201
+ }] } });
202
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLWNlbnRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9vdmVybGF5L25vdGlmaWNhdGlvbi1jZW50ZXIvc3JjL2xpYi9ub3RpZmljYXRpb24tY2VudGVyL25vdGlmaWNhdGlvbi1jZW50ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vb3ZlcmxheS9ub3RpZmljYXRpb24tY2VudGVyL3NyYy9saWIvbm90aWZpY2F0aW9uLWNlbnRlci9ub3RpZmljYXRpb24tY2VudGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDbEYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQVMsTUFBTSxxQkFBcUIsQ0FBQzs7O0FBOENqRixNQUFNLE9BQU8sMkJBQTJCO0lBM0J4QztRQTRCVyxrQkFBYSxHQUFtQixFQUFFLENBQUM7UUFDbkMsYUFBUSxHQUF5QixXQUFXLENBQUM7UUFDN0MsY0FBUyxHQUFXLENBQUMsQ0FBQztRQUN0QixvQkFBZSxHQUFXLElBQUksQ0FBQztRQUMvQixjQUFTLEdBQVksSUFBSSxDQUFDO1FBQzFCLG9CQUFlLEdBQVksS0FBSyxDQUFDO1FBRWhDLHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDOUMsMEJBQXFCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUNuRCx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBZ0IsQ0FBQztRQUN0RCxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUNuQyxlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUVoRCxX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LE9BQU8sQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQzs2QkFDM0QsQ0FBQzt5QkFDSCxDQUFDO3FCQUNIOzhCQUdRLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVJLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLE9BQU87c0JBQWhCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgdHJpZ2dlciwgdHJhbnNpdGlvbiwgc3R5bGUsIGFuaW1hdGUsIHN0YXRlIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XHJcblxyXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25UeXBlID0gJ3N1Y2Nlc3MnIHwgJ2luZm8nIHwgJ3dhcm5pbmcnIHwgJ2Vycm9yJztcclxuZXhwb3J0IHR5cGUgTm90aWZpY2F0aW9uUG9zaXRpb24gPSAndG9wLXJpZ2h0JyB8ICd0b3AtbGVmdCcgfCAnYm90dG9tLXJpZ2h0JyB8ICdib3R0b20tbGVmdCcgfCAndG9wLWNlbnRlcicgfCAnYm90dG9tLWNlbnRlcic7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE5vdGlmaWNhdGlvbiB7XHJcbiAgaWQ6IHN0cmluZztcclxuICB0eXBlOiBOb3RpZmljYXRpb25UeXBlO1xyXG4gIHRpdGxlOiBzdHJpbmc7XHJcbiAgbWVzc2FnZTogc3RyaW5nO1xyXG4gIHRpbWVzdGFtcDogRGF0ZTtcclxuICByZWFkOiBib29sZWFuO1xyXG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xyXG4gIGFjdGlvbkxhYmVsPzogc3RyaW5nO1xyXG4gIGFjdGlvbkNhbGxiYWNrPzogKCkgPT4gdm9pZDtcclxuICBhdXRvQ2xvc2U/OiBib29sZWFuO1xyXG4gIGR1cmF0aW9uPzogbnVtYmVyO1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ211eGltYS1ub3RpZmljYXRpb24tY2VudGVyJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9ub3RpZmljYXRpb24tY2VudGVyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9ub3RpZmljYXRpb24tY2VudGVyLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgdHJpZ2dlcignc2xpZGVJbicsIFtcclxuICAgICAgdHJhbnNpdGlvbignOmVudGVyJywgW1xyXG4gICAgICAgIHN0eWxlKHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgxMDAlKScsIG9wYWNpdHk6IDAgfSksXHJcbiAgICAgICAgYW5pbWF0ZSgnMzAwbXMgZWFzZS1vdXQnLCBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknLCBvcGFjaXR5OiAxIH0pKVxyXG4gICAgICBdKSxcclxuICAgICAgdHJhbnNpdGlvbignOmxlYXZlJywgW1xyXG4gICAgICAgIGFuaW1hdGUoJzMwMG1zIGVhc2UtaW4nLCBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMTAwJSknLCBvcGFjaXR5OiAwIH0pKVxyXG4gICAgICBdKVxyXG4gICAgXSksXHJcbiAgICB0cmlnZ2VyKCdzbGlkZURvd24nLCBbXHJcbiAgICAgIHRyYW5zaXRpb24oJzplbnRlcicsIFtcclxuICAgICAgICBzdHlsZSh7IGhlaWdodDogMCwgb3BhY2l0eTogMCB9KSxcclxuICAgICAgICBhbmltYXRlKCcyMDBtcyBlYXNlLW91dCcsIHN0eWxlKHsgaGVpZ2h0OiAnKicsIG9wYWNpdHk6IDEgfSkpXHJcbiAgICAgIF0pLFxyXG4gICAgICB0cmFuc2l0aW9uKCc6bGVhdmUnLCBbXHJcbiAgICAgICAgYW5pbWF0ZSgnMjAwbXMgZWFzZS1pbicsIHN0eWxlKHsgaGVpZ2h0OiAwLCBvcGFjaXR5OiAwIH0pKVxyXG4gICAgICBdKVxyXG4gICAgXSlcclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25DZW50ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIG5vdGlmaWNhdGlvbnM6IE5vdGlmaWNhdGlvbltdID0gW107XHJcbiAgQElucHV0KCkgcG9zaXRpb246IE5vdGlmaWNhdGlvblBvc2l0aW9uID0gJ3RvcC1yaWdodCc7XHJcbiAgQElucHV0KCkgbWF4VG9hc3RzOiBudW1iZXIgPSAzO1xyXG4gIEBJbnB1dCgpIGRlZmF1bHREdXJhdGlvbjogbnVtYmVyID0gNTAwMDtcclxuICBASW5wdXQoKSBzaG93QmFkZ2U6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGdyb3VwQnlDYXRlZ29yeTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBAT3V0cHV0KCkgbm90aWZpY2F0aW9uUmVhZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG4gIEBPdXRwdXQoKSBub3RpZmljYXRpb25EaXNtaXNzZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBAT3V0cHV0KCkgbm90aWZpY2F0aW9uQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxOb3RpZmljYXRpb24+KCk7XHJcbiAgQE91dHB1dCgpIGFsbFJlYWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcbiAgQE91dHB1dCgpIGFsbENsZWFyZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIGlzT3BlbiA9IGZhbHNlO1xyXG4gIGFjdGl2ZVRvYXN0czogTm90aWZpY2F0aW9uW10gPSBbXTtcclxuICBwcml2YXRlIGF1dG9DbG9zZVRpbWVycyA9IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCk7XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5hdXRvQ2xvc2VUaW1lcnMuZm9yRWFjaCh0aW1lciA9PiBjbGVhclRpbWVvdXQodGltZXIpKTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZVBhbmVsKCkge1xyXG4gICAgdGhpcy5pc09wZW4gPSAhdGhpcy5pc09wZW47XHJcbiAgfVxyXG5cclxuICBjbG9zZVBhbmVsKCkge1xyXG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIGdldCB1bnJlYWRDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMubm90aWZpY2F0aW9ucy5maWx0ZXIobiA9PiAhbi5yZWFkKS5sZW5ndGg7XHJcbiAgfVxyXG5cclxuICBnZXQgZ3JvdXBlZE5vdGlmaWNhdGlvbnMoKTogeyBjYXRlZ29yeTogc3RyaW5nOyBub3RpZmljYXRpb25zOiBOb3RpZmljYXRpb25bXSB9W10ge1xyXG4gICAgaWYgKCF0aGlzLmdyb3VwQnlDYXRlZ29yeSkge1xyXG4gICAgICByZXR1cm4gW3sgY2F0ZWdvcnk6ICdhbGwnLCBub3RpZmljYXRpb25zOiB0aGlzLm5vdGlmaWNhdGlvbnMgfV07XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZ3JvdXBzID0gbmV3IE1hcDxzdHJpbmcsIE5vdGlmaWNhdGlvbltdPigpO1xyXG4gICAgXHJcbiAgICB0aGlzLm5vdGlmaWNhdGlvbnMuZm9yRWFjaChub3RpZmljYXRpb24gPT4ge1xyXG4gICAgICBjb25zdCBjYXRlZ29yeSA9IG5vdGlmaWNhdGlvbi5jYXRlZ29yeSB8fCAnT3V0cm9zJztcclxuICAgICAgaWYgKCFncm91cHMuaGFzKGNhdGVnb3J5KSkge1xyXG4gICAgICAgIGdyb3Vwcy5zZXQoY2F0ZWdvcnksIFtdKTtcclxuICAgICAgfVxyXG4gICAgICBncm91cHMuZ2V0KGNhdGVnb3J5KSEucHVzaChub3RpZmljYXRpb24pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIEFycmF5LmZyb20oZ3JvdXBzLmVudHJpZXMoKSkubWFwKChbY2F0ZWdvcnksIG5vdGlmaWNhdGlvbnNdKSA9PiAoe1xyXG4gICAgICBjYXRlZ29yeSxcclxuICAgICAgbm90aWZpY2F0aW9uc1xyXG4gICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgc2hvd1RvYXN0KG5vdGlmaWNhdGlvbjogTm90aWZpY2F0aW9uKSB7XHJcbiAgICAvLyBBZGQgdG8gYWN0aXZlIHRvYXN0c1xyXG4gICAgaWYgKHRoaXMuYWN0aXZlVG9hc3RzLmxlbmd0aCA+PSB0aGlzLm1heFRvYXN0cykge1xyXG4gICAgICB0aGlzLmFjdGl2ZVRvYXN0cy5zaGlmdCgpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICB0aGlzLmFjdGl2ZVRvYXN0cy5wdXNoKG5vdGlmaWNhdGlvbik7XHJcblxyXG4gICAgLy8gQXV0byBjbG9zZSBpZiBlbmFibGVkXHJcbiAgICBpZiAobm90aWZpY2F0aW9uLmF1dG9DbG9zZSAhPT0gZmFsc2UpIHtcclxuICAgICAgY29uc3QgZHVyYXRpb24gPSBub3RpZmljYXRpb24uZHVyYXRpb24gfHwgdGhpcy5kZWZhdWx0RHVyYXRpb247XHJcbiAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5kaXNtaXNzVG9hc3Qobm90aWZpY2F0aW9uLmlkKTtcclxuICAgICAgfSwgZHVyYXRpb24pO1xyXG4gICAgICBcclxuICAgICAgdGhpcy5hdXRvQ2xvc2VUaW1lcnMuc2V0KG5vdGlmaWNhdGlvbi5pZCwgdGltZXIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZGlzbWlzc1RvYXN0KGlkOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5hY3RpdmVUb2FzdHMuZmluZEluZGV4KHQgPT4gdC5pZCA9PT0gaWQpO1xyXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICB0aGlzLmFjdGl2ZVRvYXN0cy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBpZiAodGhpcy5hdXRvQ2xvc2VUaW1lcnMuaGFzKGlkKSkge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5hdXRvQ2xvc2VUaW1lcnMuZ2V0KGlkKSk7XHJcbiAgICAgIHRoaXMuYXV0b0Nsb3NlVGltZXJzLmRlbGV0ZShpZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBtYXJrQXNSZWFkKG5vdGlmaWNhdGlvbjogTm90aWZpY2F0aW9uKSB7XHJcbiAgICBpZiAoIW5vdGlmaWNhdGlvbi5yZWFkKSB7XHJcbiAgICAgIG5vdGlmaWNhdGlvbi5yZWFkID0gdHJ1ZTtcclxuICAgICAgdGhpcy5ub3RpZmljYXRpb25SZWFkLmVtaXQobm90aWZpY2F0aW9uLmlkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG1hcmtBbGxBc1JlYWQoKSB7XHJcbiAgICB0aGlzLm5vdGlmaWNhdGlvbnMuZm9yRWFjaChuID0+IG4ucmVhZCA9IHRydWUpO1xyXG4gICAgdGhpcy5hbGxSZWFkLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIGRpc21pc3NOb3RpZmljYXRpb24obm90aWZpY2F0aW9uOiBOb3RpZmljYXRpb24sIGV2ZW50PzogRXZlbnQpIHtcclxuICAgIGV2ZW50Py5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5ub3RpZmljYXRpb25zLmluZGV4T2Yobm90aWZpY2F0aW9uKTtcclxuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcclxuICAgICAgdGhpcy5ub3RpZmljYXRpb25zLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9uRGlzbWlzc2VkLmVtaXQobm90aWZpY2F0aW9uLmlkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNsZWFyQWxsKCkge1xyXG4gICAgdGhpcy5ub3RpZmljYXRpb25zLmxlbmd0aCA9IDA7XHJcbiAgICB0aGlzLmFsbENsZWFyZWQuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgZXhlY3V0ZUFjdGlvbihub3RpZmljYXRpb246IE5vdGlmaWNhdGlvbiwgZXZlbnQ/OiBFdmVudCkge1xyXG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgXHJcbiAgICBpZiAobm90aWZpY2F0aW9uLmFjdGlvbkNhbGxiYWNrKSB7XHJcbiAgICAgIG5vdGlmaWNhdGlvbi5hY3Rpb25DYWxsYmFjaygpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICB0aGlzLm5vdGlmaWNhdGlvbkFjdGlvbi5lbWl0KG5vdGlmaWNhdGlvbik7XHJcbiAgICB0aGlzLm1hcmtBc1JlYWQobm90aWZpY2F0aW9uKTtcclxuICB9XHJcblxyXG4gIGdldEljb24odHlwZTogTm90aWZpY2F0aW9uVHlwZSk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBpY29ucyA9IHtcclxuICAgICAgc3VjY2VzczogJ+KchScsXHJcbiAgICAgIGluZm86ICfihLnvuI8nLFxyXG4gICAgICB3YXJuaW5nOiAn4pqg77iPJyxcclxuICAgICAgZXJyb3I6ICfinYwnXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIGljb25zW3R5cGVdO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0VGltZXN0YW1wKGRhdGU6IERhdGUpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcclxuICAgIGNvbnN0IGRpZmYgPSBub3cuZ2V0VGltZSgpIC0gZGF0ZS5nZXRUaW1lKCk7XHJcbiAgICBcclxuICAgIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKGRpZmYgLyA2MDAwMCk7XHJcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IoZGlmZiAvIDM2MDAwMDApO1xyXG4gICAgY29uc3QgZGF5cyA9IE1hdGguZmxvb3IoZGlmZiAvIDg2NDAwMDAwKTtcclxuICAgIFxyXG4gICAgaWYgKG1pbnV0ZXMgPCAxKSByZXR1cm4gJ0Fnb3JhJztcclxuICAgIGlmIChtaW51dGVzIDwgNjApIHJldHVybiBgJHttaW51dGVzfW0gYXRyw6FzYDtcclxuICAgIGlmIChob3VycyA8IDI0KSByZXR1cm4gYCR7aG91cnN9aCBhdHLDoXNgO1xyXG4gICAgaWYgKGRheXMgPCA3KSByZXR1cm4gYCR7ZGF5c31kIGF0csOhc2A7XHJcbiAgICBcclxuICAgIHJldHVybiBkYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygncHQtQlInLCB7IGRheTogJzItZGlnaXQnLCBtb250aDogJ3Nob3J0JyB9KTtcclxuICB9XHJcblxyXG4gIGdldCBwb3NpdGlvbkNsYXNzKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gYHBvc2l0aW9uLSR7dGhpcy5wb3NpdGlvbn1gO1xyXG4gIH1cclxufVxyXG4iLCI8IS0tIE5vdGlmaWNhdGlvbiBCZWxsIEljb24gLS0+XHJcbjxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tYmVsbFwiIChjbGljayk9XCJ0b2dnbGVQYW5lbCgpXCI+XHJcbiAgPHNwYW4gY2xhc3M9XCJiZWxsLWljb25cIj7wn5SUPC9zcGFuPlxyXG4gIDxzcGFuIGNsYXNzPVwiYmFkZ2VcIiAqbmdJZj1cInNob3dCYWRnZSAmJiB1bnJlYWRDb3VudCA+IDBcIj57eyB1bnJlYWRDb3VudCA+IDk5ID8gJzk5KycgOiB1bnJlYWRDb3VudCB9fTwvc3Bhbj5cclxuPC9kaXY+XHJcblxyXG48IS0tIE5vdGlmaWNhdGlvbiBQYW5lbCAtLT5cclxuPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1wYW5lbFwiIFtjbGFzcy5vcGVuXT1cImlzT3BlblwiIFtAc2xpZGVEb3duXT5cclxuICA8ZGl2IGNsYXNzPVwicGFuZWwtaGVhZGVyXCI+XHJcbiAgICA8aDM+Tm90aWZpY2HDp8O1ZXM8L2gzPlxyXG4gICAgPGRpdiBjbGFzcz1cImhlYWRlci1hY3Rpb25zXCI+XHJcbiAgICAgIDxidXR0b24gY2xhc3M9XCJhY3Rpb24tYnRuXCIgKGNsaWNrKT1cIm1hcmtBbGxBc1JlYWQoKVwiICpuZ0lmPVwidW5yZWFkQ291bnQgPiAwXCIgdGl0bGU9XCJNYXJjYXIgdG9kYXMgY29tbyBsaWRhc1wiPlxyXG4gICAgICAgIDxzcGFuPuKckzwvc3Bhbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b24gY2xhc3M9XCJhY3Rpb24tYnRuXCIgKGNsaWNrKT1cImNsZWFyQWxsKClcIiAqbmdJZj1cIm5vdGlmaWNhdGlvbnMubGVuZ3RoID4gMFwiIHRpdGxlPVwiTGltcGFyIHRvZGFzXCI+XHJcbiAgICAgICAgPHNwYW4+8J+Xke+4jzwvc3Bhbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b24gY2xhc3M9XCJhY3Rpb24tYnRuIGNsb3NlLWJ0blwiIChjbGljayk9XCJjbG9zZVBhbmVsKClcIiB0aXRsZT1cIkZlY2hhclwiPlxyXG4gICAgICAgIDxzcGFuPuKclTwvc3Bhbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cInBhbmVsLWJvZHlcIj5cclxuICAgIDxkaXYgKm5nSWY9XCJub3RpZmljYXRpb25zLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZW1wdHktc3RhdGVcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LWljb25cIj7wn5SVPC9kaXY+XHJcbiAgICAgIDxwPk5lbmh1bWEgbm90aWZpY2HDp8OjbzwvcD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgKm5nSWY9XCJub3RpZmljYXRpb25zLmxlbmd0aCA+IDBcIj5cclxuICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZ3JvdXAgb2YgZ3JvdXBlZE5vdGlmaWNhdGlvbnNcIiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1ncm91cFwiPlxyXG4gICAgICAgIDxoNCBjbGFzcz1cImdyb3VwLXRpdGxlXCIgKm5nSWY9XCJncm91cEJ5Q2F0ZWdvcnlcIj57eyBncm91cC5jYXRlZ29yeSB9fTwvaDQ+XHJcbiAgICAgICAgXHJcbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbm90aWZpY2F0aW9uIG9mIGdyb3VwLm5vdGlmaWNhdGlvbnNcIiBcclxuICAgICAgICAgICAgIGNsYXNzPVwibm90aWZpY2F0aW9uLWl0ZW1cIlxyXG4gICAgICAgICAgICAgW2NsYXNzLnVucmVhZF09XCIhbm90aWZpY2F0aW9uLnJlYWRcIlxyXG4gICAgICAgICAgICAgW2NsYXNzLnR5cGUtc3VjY2Vzc109XCJub3RpZmljYXRpb24udHlwZSA9PT0gJ3N1Y2Nlc3MnXCJcclxuICAgICAgICAgICAgIFtjbGFzcy50eXBlLWluZm9dPVwibm90aWZpY2F0aW9uLnR5cGUgPT09ICdpbmZvJ1wiXHJcbiAgICAgICAgICAgICBbY2xhc3MudHlwZS13YXJuaW5nXT1cIm5vdGlmaWNhdGlvbi50eXBlID09PSAnd2FybmluZydcIlxyXG4gICAgICAgICAgICAgW2NsYXNzLnR5cGUtZXJyb3JdPVwibm90aWZpY2F0aW9uLnR5cGUgPT09ICdlcnJvcidcIlxyXG4gICAgICAgICAgICAgKGNsaWNrKT1cIm1hcmtBc1JlYWQobm90aWZpY2F0aW9uKVwiPlxyXG4gICAgICAgICAgXHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibm90aWZpY2F0aW9uLWljb25cIj5cclxuICAgICAgICAgICAgPHNwYW4+e3sgZ2V0SWNvbihub3RpZmljYXRpb24udHlwZSkgfX08L3NwYW4+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibm90aWZpY2F0aW9uLWNvbnRlbnRcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1oZWFkZXJcIj5cclxuICAgICAgICAgICAgICA8aDUgY2xhc3M9XCJub3RpZmljYXRpb24tdGl0bGVcIj57eyBub3RpZmljYXRpb24udGl0bGUgfX08L2g1PlxyXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm90aWZpY2F0aW9uLXRpbWVcIj57eyBmb3JtYXRUaW1lc3RhbXAobm90aWZpY2F0aW9uLnRpbWVzdGFtcCkgfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8cCBjbGFzcz1cIm5vdGlmaWNhdGlvbi1tZXNzYWdlXCI+e3sgbm90aWZpY2F0aW9uLm1lc3NhZ2UgfX08L3A+XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwibm90aWZpY2F0aW9uLmFjdGlvbkxhYmVsXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJub3RpZmljYXRpb24tYWN0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhlY3V0ZUFjdGlvbihub3RpZmljYXRpb24sICRldmVudClcIj5cclxuICAgICAgICAgICAgICB7eyBub3RpZmljYXRpb24uYWN0aW9uTGFiZWwgfX1cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZGlzbWlzcy1idG5cIiAoY2xpY2spPVwiZGlzbWlzc05vdGlmaWNhdGlvbihub3RpZmljYXRpb24sICRldmVudClcIiB0aXRsZT1cIkRpc3BlbnNhclwiPlxyXG4gICAgICAgICAgICA8c3Bhbj7inJU8L3NwYW4+XHJcbiAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48IS0tIFRvYXN0IE5vdGlmaWNhdGlvbnMgLS0+XHJcbjxkaXYgY2xhc3M9XCJ0b2FzdC1jb250YWluZXJcIiBbY2xhc3NdPVwicG9zaXRpb25DbGFzc1wiPlxyXG4gIDxkaXYgKm5nRm9yPVwibGV0IHRvYXN0IG9mIGFjdGl2ZVRvYXN0c1wiIFxyXG4gICAgICAgY2xhc3M9XCJ0b2FzdC1ub3RpZmljYXRpb25cIlxyXG4gICAgICAgW2NsYXNzLnR5cGUtc3VjY2Vzc109XCJ0b2FzdC50eXBlID09PSAnc3VjY2VzcydcIlxyXG4gICAgICAgW2NsYXNzLnR5cGUtaW5mb109XCJ0b2FzdC50eXBlID09PSAnaW5mbydcIlxyXG4gICAgICAgW2NsYXNzLnR5cGUtd2FybmluZ109XCJ0b2FzdC50eXBlID09PSAnd2FybmluZydcIlxyXG4gICAgICAgW2NsYXNzLnR5cGUtZXJyb3JdPVwidG9hc3QudHlwZSA9PT0gJ2Vycm9yJ1wiXHJcbiAgICAgICBbQHNsaWRlSW5dPlxyXG4gICAgXHJcbiAgICA8ZGl2IGNsYXNzPVwidG9hc3QtaWNvblwiPlxyXG4gICAgICA8c3Bhbj57eyBnZXRJY29uKHRvYXN0LnR5cGUpIH19PC9zcGFuPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cInRvYXN0LWNvbnRlbnRcIj5cclxuICAgICAgPGg1IGNsYXNzPVwidG9hc3QtdGl0bGVcIj57eyB0b2FzdC50aXRsZSB9fTwvaDU+XHJcbiAgICAgIDxwIGNsYXNzPVwidG9hc3QtbWVzc2FnZVwiPnt7IHRvYXN0Lm1lc3NhZ2UgfX08L3A+XHJcbiAgICAgIFxyXG4gICAgICA8YnV0dG9uICpuZ0lmPVwidG9hc3QuYWN0aW9uTGFiZWxcIiBcclxuICAgICAgICAgICAgICBjbGFzcz1cInRvYXN0LWFjdGlvblwiXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImV4ZWN1dGVBY3Rpb24odG9hc3QsICRldmVudClcIj5cclxuICAgICAgICB7eyB0b2FzdC5hY3Rpb25MYWJlbCB9fVxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b2FzdC1jbG9zZVwiIChjbGljayk9XCJkaXNtaXNzVG9hc3QodG9hc3QuaWQpXCIgdGl0bGU9XCJGZWNoYXJcIj5cclxuICAgICAgPHNwYW4+4pyVPC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPCEtLSBPdmVybGF5IC0tPlxyXG48ZGl2IGNsYXNzPVwib3ZlcmxheVwiICpuZ0lmPVwiaXNPcGVuXCIgKGNsaWNrKT1cImNsb3NlUGFuZWwoKVwiPjwvZGl2PlxyXG4iXX0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXV4aW1hLXVpLW5vdGlmaWNhdGlvbi1jZW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9vdmVybGF5L25vdGlmaWNhdGlvbi1jZW50ZXIvc3JjL211eGltYS11aS1ub3RpZmljYXRpb24tY2VudGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
@@ -0,0 +1,209 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, Component, Input, Output } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { trigger, transition, style, animate } from '@angular/animations';
6
+
7
+ class NotificationCenterComponent {
8
+ constructor() {
9
+ this.notifications = [];
10
+ this.position = 'top-right';
11
+ this.maxToasts = 3;
12
+ this.defaultDuration = 5000;
13
+ this.showBadge = true;
14
+ this.groupByCategory = false;
15
+ this.notificationRead = new EventEmitter();
16
+ this.notificationDismissed = new EventEmitter();
17
+ this.notificationAction = new EventEmitter();
18
+ this.allRead = new EventEmitter();
19
+ this.allCleared = new EventEmitter();
20
+ this.isOpen = false;
21
+ this.activeToasts = [];
22
+ this.autoCloseTimers = new Map();
23
+ }
24
+ ngOnDestroy() {
25
+ this.autoCloseTimers.forEach(timer => clearTimeout(timer));
26
+ }
27
+ togglePanel() {
28
+ this.isOpen = !this.isOpen;
29
+ }
30
+ closePanel() {
31
+ this.isOpen = false;
32
+ }
33
+ get unreadCount() {
34
+ return this.notifications.filter(n => !n.read).length;
35
+ }
36
+ get groupedNotifications() {
37
+ if (!this.groupByCategory) {
38
+ return [{ category: 'all', notifications: this.notifications }];
39
+ }
40
+ const groups = new Map();
41
+ this.notifications.forEach(notification => {
42
+ const category = notification.category || 'Outros';
43
+ if (!groups.has(category)) {
44
+ groups.set(category, []);
45
+ }
46
+ groups.get(category).push(notification);
47
+ });
48
+ return Array.from(groups.entries()).map(([category, notifications]) => ({
49
+ category,
50
+ notifications
51
+ }));
52
+ }
53
+ showToast(notification) {
54
+ // Add to active toasts
55
+ if (this.activeToasts.length >= this.maxToasts) {
56
+ this.activeToasts.shift();
57
+ }
58
+ this.activeToasts.push(notification);
59
+ // Auto close if enabled
60
+ if (notification.autoClose !== false) {
61
+ const duration = notification.duration || this.defaultDuration;
62
+ const timer = setTimeout(() => {
63
+ this.dismissToast(notification.id);
64
+ }, duration);
65
+ this.autoCloseTimers.set(notification.id, timer);
66
+ }
67
+ }
68
+ dismissToast(id) {
69
+ const index = this.activeToasts.findIndex(t => t.id === id);
70
+ if (index !== -1) {
71
+ this.activeToasts.splice(index, 1);
72
+ }
73
+ if (this.autoCloseTimers.has(id)) {
74
+ clearTimeout(this.autoCloseTimers.get(id));
75
+ this.autoCloseTimers.delete(id);
76
+ }
77
+ }
78
+ markAsRead(notification) {
79
+ if (!notification.read) {
80
+ notification.read = true;
81
+ this.notificationRead.emit(notification.id);
82
+ }
83
+ }
84
+ markAllAsRead() {
85
+ this.notifications.forEach(n => n.read = true);
86
+ this.allRead.emit();
87
+ }
88
+ dismissNotification(notification, event) {
89
+ event === null || event === void 0 ? void 0 : event.stopPropagation();
90
+ const index = this.notifications.indexOf(notification);
91
+ if (index !== -1) {
92
+ this.notifications.splice(index, 1);
93
+ this.notificationDismissed.emit(notification.id);
94
+ }
95
+ }
96
+ clearAll() {
97
+ this.notifications.length = 0;
98
+ this.allCleared.emit();
99
+ }
100
+ executeAction(notification, event) {
101
+ event === null || event === void 0 ? void 0 : event.stopPropagation();
102
+ if (notification.actionCallback) {
103
+ notification.actionCallback();
104
+ }
105
+ this.notificationAction.emit(notification);
106
+ this.markAsRead(notification);
107
+ }
108
+ getIcon(type) {
109
+ const icons = {
110
+ success: '✅',
111
+ info: 'ℹ️',
112
+ warning: '⚠️',
113
+ error: '❌'
114
+ };
115
+ return icons[type];
116
+ }
117
+ formatTimestamp(date) {
118
+ const now = new Date();
119
+ const diff = now.getTime() - date.getTime();
120
+ const minutes = Math.floor(diff / 60000);
121
+ const hours = Math.floor(diff / 3600000);
122
+ const days = Math.floor(diff / 86400000);
123
+ if (minutes < 1)
124
+ return 'Agora';
125
+ if (minutes < 60)
126
+ return `${minutes}m atrás`;
127
+ if (hours < 24)
128
+ return `${hours}h atrás`;
129
+ if (days < 7)
130
+ return `${days}d atrás`;
131
+ return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });
132
+ }
133
+ get positionClass() {
134
+ return `position-${this.position}`;
135
+ }
136
+ }
137
+ NotificationCenterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NotificationCenterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
138
+ NotificationCenterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NotificationCenterComponent, isStandalone: true, selector: "muxima-notification-center", inputs: { notifications: "notifications", position: "position", maxToasts: "maxToasts", defaultDuration: "defaultDuration", showBadge: "showBadge", groupByCategory: "groupByCategory" }, outputs: { notificationRead: "notificationRead", notificationDismissed: "notificationDismissed", notificationAction: "notificationAction", allRead: "allRead", allCleared: "allCleared" }, ngImport: i0, template: "<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">\uD83D\uDD14</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notifica\u00E7\u00F5es</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>\u2713</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>\uD83D\uDDD1\uFE0F</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">\uD83D\uDD15</div>\r\n <p>Nenhuma notifica\u00E7\u00E3o</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n", styles: [".notification-bell{position:relative;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:50%;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 8px #667eea4d}.notification-bell:hover{transform:scale(1.1);box-shadow:0 6px 12px #667eea66}.notification-bell:active{transform:scale(.95)}.notification-bell .bell-icon{font-size:1.5rem;animation:ring 2s ease-in-out infinite}.notification-bell .badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 4px;background:#ef4444;color:#fff;font-size:.75rem;font-weight:700;border-radius:10px;display:flex;align-items:center;justify-content:center;border:2px solid white;animation:pulse 2s ease-in-out infinite}@keyframes ring{0%,to{transform:rotate(0)}10%,30%{transform:rotate(-10deg)}20%,40%{transform:rotate(10deg)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}.notification-panel{position:fixed;top:60px;right:20px;width:400px;max-height:600px;background:white;border-radius:12px;box-shadow:0 10px 25px #0003;transform:translateY(-20px);opacity:0;pointer-events:none;transition:all .3s ease;z-index:1000;display:flex;flex-direction:column}.notification-panel.open{transform:translateY(0);opacity:1;pointer-events:all}.panel-header{padding:1.25rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:space-between}.panel-header h3{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.panel-header .header-actions{display:flex;gap:.5rem}.panel-header .action-btn{padding:.5rem;background:transparent;border:none;color:#6b7280;font-size:1rem;cursor:pointer;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.panel-header .action-btn:hover{background:#f3f4f6;color:#667eea}.panel-header .action-btn.close-btn:hover{color:#ef4444}.panel-body{flex:1;overflow-y:auto;max-height:500px}.panel-body::-webkit-scrollbar{width:6px}.panel-body::-webkit-scrollbar-track{background:#f3f4f6}.panel-body::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:3px}.empty-state{padding:3rem 1.5rem;text-align:center}.empty-state .empty-icon{font-size:3rem;margin-bottom:1rem;opacity:.5}.empty-state p{color:#9ca3af;font-size:1rem}.notification-group .group-title{padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;color:#667eea;text-transform:uppercase;letter-spacing:.05em;background:#f9fafb;border-bottom:1px solid #e5e7eb;margin:0}.notification-item{display:flex;gap:1rem;padding:1rem 1.25rem;border-bottom:1px solid #e5e7eb;cursor:pointer;transition:all .2s ease;position:relative}.notification-item:last-child{border-bottom:none}.notification-item:hover{background:#f9fafb}.notification-item.unread{background:rgba(102,126,234,.05)}.notification-item.unread:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.notification-item.type-success .notification-icon{color:#10b981}.notification-item.type-info .notification-icon{color:#3b82f6}.notification-item.type-warning .notification-icon{color:#f59e0b}.notification-item.type-error .notification-icon{color:#ef4444}.notification-item .notification-icon{font-size:1.5rem;flex-shrink:0}.notification-item .notification-content{flex:1;min-width:0}.notification-item .notification-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}.notification-item .notification-title{font-size:.875rem;font-weight:600;color:#111827;margin:0}.notification-item .notification-time{font-size:.75rem;color:#9ca3af;white-space:nowrap}.notification-item .notification-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.notification-item .notification-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.notification-item .notification-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.notification-item .dismiss-btn{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.notification-item .dismiss-btn:hover{background:#f3f4f6;color:#ef4444}.toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:1rem;pointer-events:none}.toast-container.position-top-right{top:20px;right:20px}.toast-container.position-top-left{top:20px;left:20px}.toast-container.position-bottom-right{bottom:20px;right:20px}.toast-container.position-bottom-left{bottom:20px;left:20px}.toast-container.position-top-center{top:20px;left:50%;transform:translate(-50%)}.toast-container.position-bottom-center{bottom:20px;left:50%;transform:translate(-50%)}.toast-notification{display:flex;align-items:flex-start;gap:1rem;min-width:350px;max-width:450px;padding:1rem 1.25rem;background:white;border-radius:12px;box-shadow:0 10px 25px #00000026;pointer-events:all;border-left:4px solid}.toast-notification.type-success{border-left-color:#10b981}.toast-notification.type-success .toast-icon{color:#10b981}.toast-notification.type-info{border-left-color:#3b82f6}.toast-notification.type-info .toast-icon{color:#3b82f6}.toast-notification.type-warning{border-left-color:#f59e0b}.toast-notification.type-warning .toast-icon{color:#f59e0b}.toast-notification.type-error{border-left-color:#ef4444}.toast-notification.type-error .toast-icon{color:#ef4444}.toast-notification .toast-icon{font-size:1.5rem;flex-shrink:0}.toast-notification .toast-content{flex:1;min-width:0}.toast-notification .toast-title{font-size:.875rem;font-weight:600;color:#111827;margin:0 0 .25rem}.toast-notification .toast-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.toast-notification .toast-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.toast-notification .toast-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.toast-notification .toast-close{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.toast-notification .toast-close:hover{background:#f3f4f6;color:#ef4444}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:999;animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media (max-width: 768px){.notification-panel{right:10px;left:10px;width:auto}.toast-notification{min-width:300px;max-width:350px}.toast-container.position-top-right,.toast-container.position-top-left,.toast-container.position-top-center{top:10px;left:10px;right:10px;transform:none}.toast-container.position-bottom-right,.toast-container.position-bottom-left,.toast-container.position-bottom-center{bottom:10px;left:10px;right:10px;transform:none}}\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"] }], animations: [
139
+ trigger('slideIn', [
140
+ transition(':enter', [
141
+ style({ transform: 'translateX(100%)', opacity: 0 }),
142
+ animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
143
+ ]),
144
+ transition(':leave', [
145
+ animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
146
+ ])
147
+ ]),
148
+ trigger('slideDown', [
149
+ transition(':enter', [
150
+ style({ height: 0, opacity: 0 }),
151
+ animate('200ms ease-out', style({ height: '*', opacity: 1 }))
152
+ ]),
153
+ transition(':leave', [
154
+ animate('200ms ease-in', style({ height: 0, opacity: 0 }))
155
+ ])
156
+ ])
157
+ ] });
158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NotificationCenterComponent, decorators: [{
159
+ type: Component,
160
+ args: [{ selector: 'muxima-notification-center', standalone: true, imports: [CommonModule], animations: [
161
+ trigger('slideIn', [
162
+ transition(':enter', [
163
+ style({ transform: 'translateX(100%)', opacity: 0 }),
164
+ animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
165
+ ]),
166
+ transition(':leave', [
167
+ animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
168
+ ])
169
+ ]),
170
+ trigger('slideDown', [
171
+ transition(':enter', [
172
+ style({ height: 0, opacity: 0 }),
173
+ animate('200ms ease-out', style({ height: '*', opacity: 1 }))
174
+ ]),
175
+ transition(':leave', [
176
+ animate('200ms ease-in', style({ height: 0, opacity: 0 }))
177
+ ])
178
+ ])
179
+ ], template: "<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">\uD83D\uDD14</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notifica\u00E7\u00F5es</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>\u2713</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>\uD83D\uDDD1\uFE0F</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">\uD83D\uDD15</div>\r\n <p>Nenhuma notifica\u00E7\u00E3o</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n", styles: [".notification-bell{position:relative;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:50%;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 8px #667eea4d}.notification-bell:hover{transform:scale(1.1);box-shadow:0 6px 12px #667eea66}.notification-bell:active{transform:scale(.95)}.notification-bell .bell-icon{font-size:1.5rem;animation:ring 2s ease-in-out infinite}.notification-bell .badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 4px;background:#ef4444;color:#fff;font-size:.75rem;font-weight:700;border-radius:10px;display:flex;align-items:center;justify-content:center;border:2px solid white;animation:pulse 2s ease-in-out infinite}@keyframes ring{0%,to{transform:rotate(0)}10%,30%{transform:rotate(-10deg)}20%,40%{transform:rotate(10deg)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}.notification-panel{position:fixed;top:60px;right:20px;width:400px;max-height:600px;background:white;border-radius:12px;box-shadow:0 10px 25px #0003;transform:translateY(-20px);opacity:0;pointer-events:none;transition:all .3s ease;z-index:1000;display:flex;flex-direction:column}.notification-panel.open{transform:translateY(0);opacity:1;pointer-events:all}.panel-header{padding:1.25rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:space-between}.panel-header h3{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.panel-header .header-actions{display:flex;gap:.5rem}.panel-header .action-btn{padding:.5rem;background:transparent;border:none;color:#6b7280;font-size:1rem;cursor:pointer;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.panel-header .action-btn:hover{background:#f3f4f6;color:#667eea}.panel-header .action-btn.close-btn:hover{color:#ef4444}.panel-body{flex:1;overflow-y:auto;max-height:500px}.panel-body::-webkit-scrollbar{width:6px}.panel-body::-webkit-scrollbar-track{background:#f3f4f6}.panel-body::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:3px}.empty-state{padding:3rem 1.5rem;text-align:center}.empty-state .empty-icon{font-size:3rem;margin-bottom:1rem;opacity:.5}.empty-state p{color:#9ca3af;font-size:1rem}.notification-group .group-title{padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;color:#667eea;text-transform:uppercase;letter-spacing:.05em;background:#f9fafb;border-bottom:1px solid #e5e7eb;margin:0}.notification-item{display:flex;gap:1rem;padding:1rem 1.25rem;border-bottom:1px solid #e5e7eb;cursor:pointer;transition:all .2s ease;position:relative}.notification-item:last-child{border-bottom:none}.notification-item:hover{background:#f9fafb}.notification-item.unread{background:rgba(102,126,234,.05)}.notification-item.unread:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.notification-item.type-success .notification-icon{color:#10b981}.notification-item.type-info .notification-icon{color:#3b82f6}.notification-item.type-warning .notification-icon{color:#f59e0b}.notification-item.type-error .notification-icon{color:#ef4444}.notification-item .notification-icon{font-size:1.5rem;flex-shrink:0}.notification-item .notification-content{flex:1;min-width:0}.notification-item .notification-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}.notification-item .notification-title{font-size:.875rem;font-weight:600;color:#111827;margin:0}.notification-item .notification-time{font-size:.75rem;color:#9ca3af;white-space:nowrap}.notification-item .notification-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.notification-item .notification-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.notification-item .notification-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.notification-item .dismiss-btn{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.notification-item .dismiss-btn:hover{background:#f3f4f6;color:#ef4444}.toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:1rem;pointer-events:none}.toast-container.position-top-right{top:20px;right:20px}.toast-container.position-top-left{top:20px;left:20px}.toast-container.position-bottom-right{bottom:20px;right:20px}.toast-container.position-bottom-left{bottom:20px;left:20px}.toast-container.position-top-center{top:20px;left:50%;transform:translate(-50%)}.toast-container.position-bottom-center{bottom:20px;left:50%;transform:translate(-50%)}.toast-notification{display:flex;align-items:flex-start;gap:1rem;min-width:350px;max-width:450px;padding:1rem 1.25rem;background:white;border-radius:12px;box-shadow:0 10px 25px #00000026;pointer-events:all;border-left:4px solid}.toast-notification.type-success{border-left-color:#10b981}.toast-notification.type-success .toast-icon{color:#10b981}.toast-notification.type-info{border-left-color:#3b82f6}.toast-notification.type-info .toast-icon{color:#3b82f6}.toast-notification.type-warning{border-left-color:#f59e0b}.toast-notification.type-warning .toast-icon{color:#f59e0b}.toast-notification.type-error{border-left-color:#ef4444}.toast-notification.type-error .toast-icon{color:#ef4444}.toast-notification .toast-icon{font-size:1.5rem;flex-shrink:0}.toast-notification .toast-content{flex:1;min-width:0}.toast-notification .toast-title{font-size:.875rem;font-weight:600;color:#111827;margin:0 0 .25rem}.toast-notification .toast-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.toast-notification .toast-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.toast-notification .toast-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.toast-notification .toast-close{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.toast-notification .toast-close:hover{background:#f3f4f6;color:#ef4444}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:999;animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media (max-width: 768px){.notification-panel{right:10px;left:10px;width:auto}.toast-notification{min-width:300px;max-width:350px}.toast-container.position-top-right,.toast-container.position-top-left,.toast-container.position-top-center{top:10px;left:10px;right:10px;transform:none}.toast-container.position-bottom-right,.toast-container.position-bottom-left,.toast-container.position-bottom-center{bottom:10px;left:10px;right:10px;transform:none}}\n"] }]
180
+ }], propDecorators: { notifications: [{
181
+ type: Input
182
+ }], position: [{
183
+ type: Input
184
+ }], maxToasts: [{
185
+ type: Input
186
+ }], defaultDuration: [{
187
+ type: Input
188
+ }], showBadge: [{
189
+ type: Input
190
+ }], groupByCategory: [{
191
+ type: Input
192
+ }], notificationRead: [{
193
+ type: Output
194
+ }], notificationDismissed: [{
195
+ type: Output
196
+ }], notificationAction: [{
197
+ type: Output
198
+ }], allRead: [{
199
+ type: Output
200
+ }], allCleared: [{
201
+ type: Output
202
+ }] } });
203
+
204
+ /**
205
+ * Generated bundle index. Do not edit.
206
+ */
207
+
208
+ export { NotificationCenterComponent };
209
+ //# sourceMappingURL=muxima-ui-notification-center.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"muxima-ui-notification-center.mjs","sources":["../../../../overlay/notification-center/src/lib/notification-center/notification-center.component.ts","../../../../overlay/notification-center/src/lib/notification-center/notification-center.component.html","../../../../overlay/notification-center/src/muxima-ui-notification-center.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { trigger, transition, style, animate, state } from '@angular/animations';\r\n\r\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error';\r\nexport type NotificationPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';\r\n\r\nexport interface Notification {\r\n id: string;\r\n type: NotificationType;\r\n title: string;\r\n message: string;\r\n timestamp: Date;\r\n read: boolean;\r\n category?: string;\r\n actionLabel?: string;\r\n actionCallback?: () => void;\r\n autoClose?: boolean;\r\n duration?: number;\r\n}\r\n\r\n@Component({\r\n selector: 'muxima-notification-center',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './notification-center.component.html',\r\n styleUrls: ['./notification-center.component.scss'],\r\n animations: [\r\n trigger('slideIn', [\r\n transition(':enter', [\r\n style({ transform: 'translateX(100%)', opacity: 0 }),\r\n animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))\r\n ]),\r\n transition(':leave', [\r\n animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))\r\n ])\r\n ]),\r\n trigger('slideDown', [\r\n transition(':enter', [\r\n style({ height: 0, opacity: 0 }),\r\n animate('200ms ease-out', style({ height: '*', opacity: 1 }))\r\n ]),\r\n transition(':leave', [\r\n animate('200ms ease-in', style({ height: 0, opacity: 0 }))\r\n ])\r\n ])\r\n ]\r\n})\r\nexport class NotificationCenterComponent implements OnDestroy {\r\n @Input() notifications: Notification[] = [];\r\n @Input() position: NotificationPosition = 'top-right';\r\n @Input() maxToasts: number = 3;\r\n @Input() defaultDuration: number = 5000;\r\n @Input() showBadge: boolean = true;\r\n @Input() groupByCategory: boolean = false;\r\n\r\n @Output() notificationRead = new EventEmitter<string>();\r\n @Output() notificationDismissed = new EventEmitter<string>();\r\n @Output() notificationAction = new EventEmitter<Notification>();\r\n @Output() allRead = new EventEmitter<void>();\r\n @Output() allCleared = new EventEmitter<void>();\r\n\r\n isOpen = false;\r\n activeToasts: Notification[] = [];\r\n private autoCloseTimers = new Map<string, any>();\r\n\r\n ngOnDestroy() {\r\n this.autoCloseTimers.forEach(timer => clearTimeout(timer));\r\n }\r\n\r\n togglePanel() {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n closePanel() {\r\n this.isOpen = false;\r\n }\r\n\r\n get unreadCount(): number {\r\n return this.notifications.filter(n => !n.read).length;\r\n }\r\n\r\n get groupedNotifications(): { category: string; notifications: Notification[] }[] {\r\n if (!this.groupByCategory) {\r\n return [{ category: 'all', notifications: this.notifications }];\r\n }\r\n\r\n const groups = new Map<string, Notification[]>();\r\n \r\n this.notifications.forEach(notification => {\r\n const category = notification.category || 'Outros';\r\n if (!groups.has(category)) {\r\n groups.set(category, []);\r\n }\r\n groups.get(category)!.push(notification);\r\n });\r\n\r\n return Array.from(groups.entries()).map(([category, notifications]) => ({\r\n category,\r\n notifications\r\n }));\r\n }\r\n\r\n showToast(notification: Notification) {\r\n // Add to active toasts\r\n if (this.activeToasts.length >= this.maxToasts) {\r\n this.activeToasts.shift();\r\n }\r\n \r\n this.activeToasts.push(notification);\r\n\r\n // Auto close if enabled\r\n if (notification.autoClose !== false) {\r\n const duration = notification.duration || this.defaultDuration;\r\n const timer = setTimeout(() => {\r\n this.dismissToast(notification.id);\r\n }, duration);\r\n \r\n this.autoCloseTimers.set(notification.id, timer);\r\n }\r\n }\r\n\r\n dismissToast(id: string) {\r\n const index = this.activeToasts.findIndex(t => t.id === id);\r\n if (index !== -1) {\r\n this.activeToasts.splice(index, 1);\r\n }\r\n \r\n if (this.autoCloseTimers.has(id)) {\r\n clearTimeout(this.autoCloseTimers.get(id));\r\n this.autoCloseTimers.delete(id);\r\n }\r\n }\r\n\r\n markAsRead(notification: Notification) {\r\n if (!notification.read) {\r\n notification.read = true;\r\n this.notificationRead.emit(notification.id);\r\n }\r\n }\r\n\r\n markAllAsRead() {\r\n this.notifications.forEach(n => n.read = true);\r\n this.allRead.emit();\r\n }\r\n\r\n dismissNotification(notification: Notification, event?: Event) {\r\n event?.stopPropagation();\r\n const index = this.notifications.indexOf(notification);\r\n if (index !== -1) {\r\n this.notifications.splice(index, 1);\r\n this.notificationDismissed.emit(notification.id);\r\n }\r\n }\r\n\r\n clearAll() {\r\n this.notifications.length = 0;\r\n this.allCleared.emit();\r\n }\r\n\r\n executeAction(notification: Notification, event?: Event) {\r\n event?.stopPropagation();\r\n \r\n if (notification.actionCallback) {\r\n notification.actionCallback();\r\n }\r\n \r\n this.notificationAction.emit(notification);\r\n this.markAsRead(notification);\r\n }\r\n\r\n getIcon(type: NotificationType): string {\r\n const icons = {\r\n success: '✅',\r\n info: 'ℹ️',\r\n warning: '⚠️',\r\n error: '❌'\r\n };\r\n return icons[type];\r\n }\r\n\r\n formatTimestamp(date: Date): string {\r\n const now = new Date();\r\n const diff = now.getTime() - date.getTime();\r\n \r\n const minutes = Math.floor(diff / 60000);\r\n const hours = Math.floor(diff / 3600000);\r\n const days = Math.floor(diff / 86400000);\r\n \r\n if (minutes < 1) return 'Agora';\r\n if (minutes < 60) return `${minutes}m atrás`;\r\n if (hours < 24) return `${hours}h atrás`;\r\n if (days < 7) return `${days}d atrás`;\r\n \r\n return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });\r\n }\r\n\r\n get positionClass(): string {\r\n return `position-${this.position}`;\r\n }\r\n}\r\n","<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notificações</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>✓</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>🗑️</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>✕</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">🔕</div>\r\n <p>Nenhuma notificação</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>✕</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>✕</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;MAgDa,2BAA2B,CAAA;AA3BxC,IAAA,WAAA,GAAA;AA4BW,QAAA,IAAa,CAAA,aAAA,GAAmB,EAAE,CAAC;AACnC,QAAA,IAAQ,CAAA,QAAA,GAAyB,WAAW,CAAC;AAC7C,QAAA,IAAS,CAAA,SAAA,GAAW,CAAC,CAAC;AACtB,QAAA,IAAe,CAAA,eAAA,GAAW,IAAI,CAAC;AAC/B,QAAA,IAAS,CAAA,SAAA,GAAY,IAAI,CAAC;AAC1B,QAAA,IAAe,CAAA,eAAA,GAAY,KAAK,CAAC;AAEhC,QAAA,IAAA,CAAA,gBAAgB,GAAG,IAAI,YAAY,EAAU,CAAC;AAC9C,QAAA,IAAA,CAAA,qBAAqB,GAAG,IAAI,YAAY,EAAU,CAAC;AACnD,QAAA,IAAA,CAAA,kBAAkB,GAAG,IAAI,YAAY,EAAgB,CAAC;AACtD,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,YAAY,EAAQ,CAAC;AACnC,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,YAAY,EAAQ,CAAC;AAEhD,QAAA,IAAM,CAAA,MAAA,GAAG,KAAK,CAAC;AACf,QAAA,IAAY,CAAA,YAAA,GAAmB,EAAE,CAAC;AAC1B,QAAA,IAAA,CAAA,eAAe,GAAG,IAAI,GAAG,EAAe,CAAC;KAwIlD;IAtIC,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;KAC5D;IAED,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;KAC5B;IAED,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;KACrB;AAED,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;KACvD;AAED,IAAA,IAAI,oBAAoB,GAAA;AACtB,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;AACzB,YAAA,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;AACjE,SAAA;AAED,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEjD,QAAA,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,IAAG;AACxC,YAAA,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,QAAQ,CAAC;AACnD,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AACzB,gBAAA,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC1B,aAAA;YACD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAC3C,SAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM;YACtE,QAAQ;YACR,aAAa;AACd,SAAA,CAAC,CAAC,CAAC;KACL;AAED,IAAA,SAAS,CAAC,YAA0B,EAAA;;QAElC,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE;AAC9C,YAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;AAC3B,SAAA;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;;AAGrC,QAAA,IAAI,YAAY,CAAC,SAAS,KAAK,KAAK,EAAE;YACpC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC;AAC/D,YAAA,MAAM,KAAK,GAAG,UAAU,CAAC,MAAK;AAC5B,gBAAA,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;aACpC,EAAE,QAAQ,CAAC,CAAC;YAEb,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAClD,SAAA;KACF;AAED,IAAA,YAAY,CAAC,EAAU,EAAA;AACrB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,QAAA,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACpC,SAAA;QAED,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAChC,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3C,YAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACjC,SAAA;KACF;AAED,IAAA,UAAU,CAAC,YAA0B,EAAA;AACnC,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;AACtB,YAAA,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAC7C,SAAA;KACF;IAED,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AAC/C,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;KACrB;IAED,mBAAmB,CAAC,YAA0B,EAAE,KAAa,EAAA;AAC3D,QAAA,KAAK,aAAL,KAAK,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAL,KAAK,CAAE,eAAe,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AACvD,QAAA,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACpC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAClD,SAAA;KACF;IAED,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;KACxB;IAED,aAAa,CAAC,YAA0B,EAAE,KAAa,EAAA;AACrD,QAAA,KAAK,aAAL,KAAK,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAL,KAAK,CAAE,eAAe,EAAE,CAAC;QAEzB,IAAI,YAAY,CAAC,cAAc,EAAE;YAC/B,YAAY,CAAC,cAAc,EAAE,CAAC;AAC/B,SAAA;AAED,QAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAC3C,QAAA,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;KAC/B;AAED,IAAA,OAAO,CAAC,IAAsB,EAAA;AAC5B,QAAA,MAAM,KAAK,GAAG;AACZ,YAAA,OAAO,EAAE,GAAG;AACZ,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,OAAO,EAAE,IAAI;AACb,YAAA,KAAK,EAAE,GAAG;SACX,CAAC;AACF,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;KACpB;AAED,IAAA,eAAe,CAAC,IAAU,EAAA;AACxB,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAE5C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;QAEzC,IAAI,OAAO,GAAG,CAAC;AAAE,YAAA,OAAO,OAAO,CAAC;QAChC,IAAI,OAAO,GAAG,EAAE;YAAE,OAAO,CAAA,EAAG,OAAO,CAAA,OAAA,CAAS,CAAC;QAC7C,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,CAAA,EAAG,KAAK,CAAA,OAAA,CAAS,CAAC;QACzC,IAAI,IAAI,GAAG,CAAC;YAAE,OAAO,CAAA,EAAG,IAAI,CAAA,OAAA,CAAS,CAAC;AAEtC,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;KAC7E;AAED,IAAA,IAAI,aAAa,GAAA;AACf,QAAA,OAAO,CAAY,SAAA,EAAA,IAAI,CAAC,QAAQ,EAAE,CAAC;KACpC;;yHAvJU,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA3B,2BAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,2BAA2B,EChDxC,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,EAAA,OAAA,EAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,OAAA,EAAA,SAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,2pIAsGA,ED9EY,MAAA,EAAA,CAAA,y7NAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EAGV,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,cAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,UAAA,EAAA;QACV,OAAO,CAAC,SAAS,EAAE;YACjB,UAAU,CAAC,QAAQ,EAAE;gBACnB,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACpD,gBAAA,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;aAC7E,CAAC;YACF,UAAU,CAAC,QAAQ,EAAE;AACnB,gBAAA,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;aAC/E,CAAC;SACH,CAAC;QACF,OAAO,CAAC,WAAW,EAAE;YACnB,UAAU,CAAC,QAAQ,EAAE;gBACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAChC,gBAAA,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;aAC9D,CAAC;YACF,UAAU,CAAC,QAAQ,EAAE;AACnB,gBAAA,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;aAC3D,CAAC;SACH,CAAC;AACH,KAAA,EAAA,CAAA,CAAA;4FAEU,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBA3BvC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,cAC1B,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAGX,UAAA,EAAA;wBACV,OAAO,CAAC,SAAS,EAAE;4BACjB,UAAU,CAAC,QAAQ,EAAE;gCACnB,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACpD,gCAAA,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;6BAC7E,CAAC;4BACF,UAAU,CAAC,QAAQ,EAAE;AACnB,gCAAA,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;6BAC/E,CAAC;yBACH,CAAC;wBACF,OAAO,CAAC,WAAW,EAAE;4BACnB,UAAU,CAAC,QAAQ,EAAE;gCACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAChC,gCAAA,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;6BAC9D,CAAC;4BACF,UAAU,CAAC,QAAQ,EAAE;AACnB,gCAAA,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;6BAC3D,CAAC;yBACH,CAAC;qBACH,EAAA,QAAA,EAAA,2pIAAA,EAAA,MAAA,EAAA,CAAA,y7NAAA,CAAA,EAAA,CAAA;8BAGQ,aAAa,EAAA,CAAA;sBAArB,KAAK;gBACG,QAAQ,EAAA,CAAA;sBAAhB,KAAK;gBACG,SAAS,EAAA,CAAA;sBAAjB,KAAK;gBACG,eAAe,EAAA,CAAA;sBAAvB,KAAK;gBACG,SAAS,EAAA,CAAA;sBAAjB,KAAK;gBACG,eAAe,EAAA,CAAA;sBAAvB,KAAK;gBAEI,gBAAgB,EAAA,CAAA;sBAAzB,MAAM;gBACG,qBAAqB,EAAA,CAAA;sBAA9B,MAAM;gBACG,kBAAkB,EAAA,CAAA;sBAA3B,MAAM;gBACG,OAAO,EAAA,CAAA;sBAAhB,MAAM;gBACG,UAAU,EAAA,CAAA;sBAAnB,MAAM;;;AE5DT;;AAEG;;;;"}
@@ -0,0 +1,209 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, Component, Input, Output } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { trigger, transition, style, animate } from '@angular/animations';
6
+
7
+ class NotificationCenterComponent {
8
+ constructor() {
9
+ this.notifications = [];
10
+ this.position = 'top-right';
11
+ this.maxToasts = 3;
12
+ this.defaultDuration = 5000;
13
+ this.showBadge = true;
14
+ this.groupByCategory = false;
15
+ this.notificationRead = new EventEmitter();
16
+ this.notificationDismissed = new EventEmitter();
17
+ this.notificationAction = new EventEmitter();
18
+ this.allRead = new EventEmitter();
19
+ this.allCleared = new EventEmitter();
20
+ this.isOpen = false;
21
+ this.activeToasts = [];
22
+ this.autoCloseTimers = new Map();
23
+ }
24
+ ngOnDestroy() {
25
+ this.autoCloseTimers.forEach(timer => clearTimeout(timer));
26
+ }
27
+ togglePanel() {
28
+ this.isOpen = !this.isOpen;
29
+ }
30
+ closePanel() {
31
+ this.isOpen = false;
32
+ }
33
+ get unreadCount() {
34
+ return this.notifications.filter(n => !n.read).length;
35
+ }
36
+ get groupedNotifications() {
37
+ if (!this.groupByCategory) {
38
+ return [{ category: 'all', notifications: this.notifications }];
39
+ }
40
+ const groups = new Map();
41
+ this.notifications.forEach(notification => {
42
+ const category = notification.category || 'Outros';
43
+ if (!groups.has(category)) {
44
+ groups.set(category, []);
45
+ }
46
+ groups.get(category).push(notification);
47
+ });
48
+ return Array.from(groups.entries()).map(([category, notifications]) => ({
49
+ category,
50
+ notifications
51
+ }));
52
+ }
53
+ showToast(notification) {
54
+ // Add to active toasts
55
+ if (this.activeToasts.length >= this.maxToasts) {
56
+ this.activeToasts.shift();
57
+ }
58
+ this.activeToasts.push(notification);
59
+ // Auto close if enabled
60
+ if (notification.autoClose !== false) {
61
+ const duration = notification.duration || this.defaultDuration;
62
+ const timer = setTimeout(() => {
63
+ this.dismissToast(notification.id);
64
+ }, duration);
65
+ this.autoCloseTimers.set(notification.id, timer);
66
+ }
67
+ }
68
+ dismissToast(id) {
69
+ const index = this.activeToasts.findIndex(t => t.id === id);
70
+ if (index !== -1) {
71
+ this.activeToasts.splice(index, 1);
72
+ }
73
+ if (this.autoCloseTimers.has(id)) {
74
+ clearTimeout(this.autoCloseTimers.get(id));
75
+ this.autoCloseTimers.delete(id);
76
+ }
77
+ }
78
+ markAsRead(notification) {
79
+ if (!notification.read) {
80
+ notification.read = true;
81
+ this.notificationRead.emit(notification.id);
82
+ }
83
+ }
84
+ markAllAsRead() {
85
+ this.notifications.forEach(n => n.read = true);
86
+ this.allRead.emit();
87
+ }
88
+ dismissNotification(notification, event) {
89
+ event?.stopPropagation();
90
+ const index = this.notifications.indexOf(notification);
91
+ if (index !== -1) {
92
+ this.notifications.splice(index, 1);
93
+ this.notificationDismissed.emit(notification.id);
94
+ }
95
+ }
96
+ clearAll() {
97
+ this.notifications.length = 0;
98
+ this.allCleared.emit();
99
+ }
100
+ executeAction(notification, event) {
101
+ event?.stopPropagation();
102
+ if (notification.actionCallback) {
103
+ notification.actionCallback();
104
+ }
105
+ this.notificationAction.emit(notification);
106
+ this.markAsRead(notification);
107
+ }
108
+ getIcon(type) {
109
+ const icons = {
110
+ success: '✅',
111
+ info: 'ℹ️',
112
+ warning: '⚠️',
113
+ error: '❌'
114
+ };
115
+ return icons[type];
116
+ }
117
+ formatTimestamp(date) {
118
+ const now = new Date();
119
+ const diff = now.getTime() - date.getTime();
120
+ const minutes = Math.floor(diff / 60000);
121
+ const hours = Math.floor(diff / 3600000);
122
+ const days = Math.floor(diff / 86400000);
123
+ if (minutes < 1)
124
+ return 'Agora';
125
+ if (minutes < 60)
126
+ return `${minutes}m atrás`;
127
+ if (hours < 24)
128
+ return `${hours}h atrás`;
129
+ if (days < 7)
130
+ return `${days}d atrás`;
131
+ return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });
132
+ }
133
+ get positionClass() {
134
+ return `position-${this.position}`;
135
+ }
136
+ }
137
+ NotificationCenterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NotificationCenterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
138
+ NotificationCenterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NotificationCenterComponent, isStandalone: true, selector: "muxima-notification-center", inputs: { notifications: "notifications", position: "position", maxToasts: "maxToasts", defaultDuration: "defaultDuration", showBadge: "showBadge", groupByCategory: "groupByCategory" }, outputs: { notificationRead: "notificationRead", notificationDismissed: "notificationDismissed", notificationAction: "notificationAction", allRead: "allRead", allCleared: "allCleared" }, ngImport: i0, template: "<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">\uD83D\uDD14</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notifica\u00E7\u00F5es</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>\u2713</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>\uD83D\uDDD1\uFE0F</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">\uD83D\uDD15</div>\r\n <p>Nenhuma notifica\u00E7\u00E3o</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n", styles: [".notification-bell{position:relative;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:50%;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 8px #667eea4d}.notification-bell:hover{transform:scale(1.1);box-shadow:0 6px 12px #667eea66}.notification-bell:active{transform:scale(.95)}.notification-bell .bell-icon{font-size:1.5rem;animation:ring 2s ease-in-out infinite}.notification-bell .badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 4px;background:#ef4444;color:#fff;font-size:.75rem;font-weight:700;border-radius:10px;display:flex;align-items:center;justify-content:center;border:2px solid white;animation:pulse 2s ease-in-out infinite}@keyframes ring{0%,to{transform:rotate(0)}10%,30%{transform:rotate(-10deg)}20%,40%{transform:rotate(10deg)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}.notification-panel{position:fixed;top:60px;right:20px;width:400px;max-height:600px;background:white;border-radius:12px;box-shadow:0 10px 25px #0003;transform:translateY(-20px);opacity:0;pointer-events:none;transition:all .3s ease;z-index:1000;display:flex;flex-direction:column}.notification-panel.open{transform:translateY(0);opacity:1;pointer-events:all}.panel-header{padding:1.25rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:space-between}.panel-header h3{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.panel-header .header-actions{display:flex;gap:.5rem}.panel-header .action-btn{padding:.5rem;background:transparent;border:none;color:#6b7280;font-size:1rem;cursor:pointer;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.panel-header .action-btn:hover{background:#f3f4f6;color:#667eea}.panel-header .action-btn.close-btn:hover{color:#ef4444}.panel-body{flex:1;overflow-y:auto;max-height:500px}.panel-body::-webkit-scrollbar{width:6px}.panel-body::-webkit-scrollbar-track{background:#f3f4f6}.panel-body::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:3px}.empty-state{padding:3rem 1.5rem;text-align:center}.empty-state .empty-icon{font-size:3rem;margin-bottom:1rem;opacity:.5}.empty-state p{color:#9ca3af;font-size:1rem}.notification-group .group-title{padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;color:#667eea;text-transform:uppercase;letter-spacing:.05em;background:#f9fafb;border-bottom:1px solid #e5e7eb;margin:0}.notification-item{display:flex;gap:1rem;padding:1rem 1.25rem;border-bottom:1px solid #e5e7eb;cursor:pointer;transition:all .2s ease;position:relative}.notification-item:last-child{border-bottom:none}.notification-item:hover{background:#f9fafb}.notification-item.unread{background:rgba(102,126,234,.05)}.notification-item.unread:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.notification-item.type-success .notification-icon{color:#10b981}.notification-item.type-info .notification-icon{color:#3b82f6}.notification-item.type-warning .notification-icon{color:#f59e0b}.notification-item.type-error .notification-icon{color:#ef4444}.notification-item .notification-icon{font-size:1.5rem;flex-shrink:0}.notification-item .notification-content{flex:1;min-width:0}.notification-item .notification-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}.notification-item .notification-title{font-size:.875rem;font-weight:600;color:#111827;margin:0}.notification-item .notification-time{font-size:.75rem;color:#9ca3af;white-space:nowrap}.notification-item .notification-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.notification-item .notification-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.notification-item .notification-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.notification-item .dismiss-btn{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.notification-item .dismiss-btn:hover{background:#f3f4f6;color:#ef4444}.toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:1rem;pointer-events:none}.toast-container.position-top-right{top:20px;right:20px}.toast-container.position-top-left{top:20px;left:20px}.toast-container.position-bottom-right{bottom:20px;right:20px}.toast-container.position-bottom-left{bottom:20px;left:20px}.toast-container.position-top-center{top:20px;left:50%;transform:translate(-50%)}.toast-container.position-bottom-center{bottom:20px;left:50%;transform:translate(-50%)}.toast-notification{display:flex;align-items:flex-start;gap:1rem;min-width:350px;max-width:450px;padding:1rem 1.25rem;background:white;border-radius:12px;box-shadow:0 10px 25px #00000026;pointer-events:all;border-left:4px solid}.toast-notification.type-success{border-left-color:#10b981}.toast-notification.type-success .toast-icon{color:#10b981}.toast-notification.type-info{border-left-color:#3b82f6}.toast-notification.type-info .toast-icon{color:#3b82f6}.toast-notification.type-warning{border-left-color:#f59e0b}.toast-notification.type-warning .toast-icon{color:#f59e0b}.toast-notification.type-error{border-left-color:#ef4444}.toast-notification.type-error .toast-icon{color:#ef4444}.toast-notification .toast-icon{font-size:1.5rem;flex-shrink:0}.toast-notification .toast-content{flex:1;min-width:0}.toast-notification .toast-title{font-size:.875rem;font-weight:600;color:#111827;margin:0 0 .25rem}.toast-notification .toast-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.toast-notification .toast-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.toast-notification .toast-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.toast-notification .toast-close{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.toast-notification .toast-close:hover{background:#f3f4f6;color:#ef4444}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:999;animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media (max-width: 768px){.notification-panel{right:10px;left:10px;width:auto}.toast-notification{min-width:300px;max-width:350px}.toast-container.position-top-right,.toast-container.position-top-left,.toast-container.position-top-center{top:10px;left:10px;right:10px;transform:none}.toast-container.position-bottom-right,.toast-container.position-bottom-left,.toast-container.position-bottom-center{bottom:10px;left:10px;right:10px;transform:none}}\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"] }], animations: [
139
+ trigger('slideIn', [
140
+ transition(':enter', [
141
+ style({ transform: 'translateX(100%)', opacity: 0 }),
142
+ animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
143
+ ]),
144
+ transition(':leave', [
145
+ animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
146
+ ])
147
+ ]),
148
+ trigger('slideDown', [
149
+ transition(':enter', [
150
+ style({ height: 0, opacity: 0 }),
151
+ animate('200ms ease-out', style({ height: '*', opacity: 1 }))
152
+ ]),
153
+ transition(':leave', [
154
+ animate('200ms ease-in', style({ height: 0, opacity: 0 }))
155
+ ])
156
+ ])
157
+ ] });
158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NotificationCenterComponent, decorators: [{
159
+ type: Component,
160
+ args: [{ selector: 'muxima-notification-center', standalone: true, imports: [CommonModule], animations: [
161
+ trigger('slideIn', [
162
+ transition(':enter', [
163
+ style({ transform: 'translateX(100%)', opacity: 0 }),
164
+ animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
165
+ ]),
166
+ transition(':leave', [
167
+ animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
168
+ ])
169
+ ]),
170
+ trigger('slideDown', [
171
+ transition(':enter', [
172
+ style({ height: 0, opacity: 0 }),
173
+ animate('200ms ease-out', style({ height: '*', opacity: 1 }))
174
+ ]),
175
+ transition(':leave', [
176
+ animate('200ms ease-in', style({ height: 0, opacity: 0 }))
177
+ ])
178
+ ])
179
+ ], template: "<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">\uD83D\uDD14</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notifica\u00E7\u00F5es</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>\u2713</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>\uD83D\uDDD1\uFE0F</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">\uD83D\uDD15</div>\r\n <p>Nenhuma notifica\u00E7\u00E3o</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>\u2715</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n", styles: [".notification-bell{position:relative;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:50%;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 8px #667eea4d}.notification-bell:hover{transform:scale(1.1);box-shadow:0 6px 12px #667eea66}.notification-bell:active{transform:scale(.95)}.notification-bell .bell-icon{font-size:1.5rem;animation:ring 2s ease-in-out infinite}.notification-bell .badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 4px;background:#ef4444;color:#fff;font-size:.75rem;font-weight:700;border-radius:10px;display:flex;align-items:center;justify-content:center;border:2px solid white;animation:pulse 2s ease-in-out infinite}@keyframes ring{0%,to{transform:rotate(0)}10%,30%{transform:rotate(-10deg)}20%,40%{transform:rotate(10deg)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}.notification-panel{position:fixed;top:60px;right:20px;width:400px;max-height:600px;background:white;border-radius:12px;box-shadow:0 10px 25px #0003;transform:translateY(-20px);opacity:0;pointer-events:none;transition:all .3s ease;z-index:1000;display:flex;flex-direction:column}.notification-panel.open{transform:translateY(0);opacity:1;pointer-events:all}.panel-header{padding:1.25rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:space-between}.panel-header h3{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.panel-header .header-actions{display:flex;gap:.5rem}.panel-header .action-btn{padding:.5rem;background:transparent;border:none;color:#6b7280;font-size:1rem;cursor:pointer;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.panel-header .action-btn:hover{background:#f3f4f6;color:#667eea}.panel-header .action-btn.close-btn:hover{color:#ef4444}.panel-body{flex:1;overflow-y:auto;max-height:500px}.panel-body::-webkit-scrollbar{width:6px}.panel-body::-webkit-scrollbar-track{background:#f3f4f6}.panel-body::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:3px}.empty-state{padding:3rem 1.5rem;text-align:center}.empty-state .empty-icon{font-size:3rem;margin-bottom:1rem;opacity:.5}.empty-state p{color:#9ca3af;font-size:1rem}.notification-group .group-title{padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;color:#667eea;text-transform:uppercase;letter-spacing:.05em;background:#f9fafb;border-bottom:1px solid #e5e7eb;margin:0}.notification-item{display:flex;gap:1rem;padding:1rem 1.25rem;border-bottom:1px solid #e5e7eb;cursor:pointer;transition:all .2s ease;position:relative}.notification-item:last-child{border-bottom:none}.notification-item:hover{background:#f9fafb}.notification-item.unread{background:rgba(102,126,234,.05)}.notification-item.unread:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.notification-item.type-success .notification-icon{color:#10b981}.notification-item.type-info .notification-icon{color:#3b82f6}.notification-item.type-warning .notification-icon{color:#f59e0b}.notification-item.type-error .notification-icon{color:#ef4444}.notification-item .notification-icon{font-size:1.5rem;flex-shrink:0}.notification-item .notification-content{flex:1;min-width:0}.notification-item .notification-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}.notification-item .notification-title{font-size:.875rem;font-weight:600;color:#111827;margin:0}.notification-item .notification-time{font-size:.75rem;color:#9ca3af;white-space:nowrap}.notification-item .notification-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.notification-item .notification-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.notification-item .notification-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.notification-item .dismiss-btn{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.notification-item .dismiss-btn:hover{background:#f3f4f6;color:#ef4444}.toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:1rem;pointer-events:none}.toast-container.position-top-right{top:20px;right:20px}.toast-container.position-top-left{top:20px;left:20px}.toast-container.position-bottom-right{bottom:20px;right:20px}.toast-container.position-bottom-left{bottom:20px;left:20px}.toast-container.position-top-center{top:20px;left:50%;transform:translate(-50%)}.toast-container.position-bottom-center{bottom:20px;left:50%;transform:translate(-50%)}.toast-notification{display:flex;align-items:flex-start;gap:1rem;min-width:350px;max-width:450px;padding:1rem 1.25rem;background:white;border-radius:12px;box-shadow:0 10px 25px #00000026;pointer-events:all;border-left:4px solid}.toast-notification.type-success{border-left-color:#10b981}.toast-notification.type-success .toast-icon{color:#10b981}.toast-notification.type-info{border-left-color:#3b82f6}.toast-notification.type-info .toast-icon{color:#3b82f6}.toast-notification.type-warning{border-left-color:#f59e0b}.toast-notification.type-warning .toast-icon{color:#f59e0b}.toast-notification.type-error{border-left-color:#ef4444}.toast-notification.type-error .toast-icon{color:#ef4444}.toast-notification .toast-icon{font-size:1.5rem;flex-shrink:0}.toast-notification .toast-content{flex:1;min-width:0}.toast-notification .toast-title{font-size:.875rem;font-weight:600;color:#111827;margin:0 0 .25rem}.toast-notification .toast-message{font-size:.875rem;color:#6b7280;margin:0 0 .75rem;line-height:1.5}.toast-notification .toast-action{padding:.375rem .75rem;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;border:none;border-radius:6px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.toast-notification .toast-action:hover{transform:translateY(-1px);box-shadow:0 4px 8px #667eea4d}.toast-notification .toast-close{padding:.25rem;background:transparent;border:none;color:#9ca3af;font-size:1rem;cursor:pointer;border-radius:4px;transition:all .2s ease;flex-shrink:0}.toast-notification .toast-close:hover{background:#f3f4f6;color:#ef4444}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:999;animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media (max-width: 768px){.notification-panel{right:10px;left:10px;width:auto}.toast-notification{min-width:300px;max-width:350px}.toast-container.position-top-right,.toast-container.position-top-left,.toast-container.position-top-center{top:10px;left:10px;right:10px;transform:none}.toast-container.position-bottom-right,.toast-container.position-bottom-left,.toast-container.position-bottom-center{bottom:10px;left:10px;right:10px;transform:none}}\n"] }]
180
+ }], propDecorators: { notifications: [{
181
+ type: Input
182
+ }], position: [{
183
+ type: Input
184
+ }], maxToasts: [{
185
+ type: Input
186
+ }], defaultDuration: [{
187
+ type: Input
188
+ }], showBadge: [{
189
+ type: Input
190
+ }], groupByCategory: [{
191
+ type: Input
192
+ }], notificationRead: [{
193
+ type: Output
194
+ }], notificationDismissed: [{
195
+ type: Output
196
+ }], notificationAction: [{
197
+ type: Output
198
+ }], allRead: [{
199
+ type: Output
200
+ }], allCleared: [{
201
+ type: Output
202
+ }] } });
203
+
204
+ /**
205
+ * Generated bundle index. Do not edit.
206
+ */
207
+
208
+ export { NotificationCenterComponent };
209
+ //# sourceMappingURL=muxima-ui-notification-center.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"muxima-ui-notification-center.mjs","sources":["../../../../overlay/notification-center/src/lib/notification-center/notification-center.component.ts","../../../../overlay/notification-center/src/lib/notification-center/notification-center.component.html","../../../../overlay/notification-center/src/muxima-ui-notification-center.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { trigger, transition, style, animate, state } from '@angular/animations';\r\n\r\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error';\r\nexport type NotificationPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';\r\n\r\nexport interface Notification {\r\n id: string;\r\n type: NotificationType;\r\n title: string;\r\n message: string;\r\n timestamp: Date;\r\n read: boolean;\r\n category?: string;\r\n actionLabel?: string;\r\n actionCallback?: () => void;\r\n autoClose?: boolean;\r\n duration?: number;\r\n}\r\n\r\n@Component({\r\n selector: 'muxima-notification-center',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './notification-center.component.html',\r\n styleUrls: ['./notification-center.component.scss'],\r\n animations: [\r\n trigger('slideIn', [\r\n transition(':enter', [\r\n style({ transform: 'translateX(100%)', opacity: 0 }),\r\n animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))\r\n ]),\r\n transition(':leave', [\r\n animate('300ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))\r\n ])\r\n ]),\r\n trigger('slideDown', [\r\n transition(':enter', [\r\n style({ height: 0, opacity: 0 }),\r\n animate('200ms ease-out', style({ height: '*', opacity: 1 }))\r\n ]),\r\n transition(':leave', [\r\n animate('200ms ease-in', style({ height: 0, opacity: 0 }))\r\n ])\r\n ])\r\n ]\r\n})\r\nexport class NotificationCenterComponent implements OnDestroy {\r\n @Input() notifications: Notification[] = [];\r\n @Input() position: NotificationPosition = 'top-right';\r\n @Input() maxToasts: number = 3;\r\n @Input() defaultDuration: number = 5000;\r\n @Input() showBadge: boolean = true;\r\n @Input() groupByCategory: boolean = false;\r\n\r\n @Output() notificationRead = new EventEmitter<string>();\r\n @Output() notificationDismissed = new EventEmitter<string>();\r\n @Output() notificationAction = new EventEmitter<Notification>();\r\n @Output() allRead = new EventEmitter<void>();\r\n @Output() allCleared = new EventEmitter<void>();\r\n\r\n isOpen = false;\r\n activeToasts: Notification[] = [];\r\n private autoCloseTimers = new Map<string, any>();\r\n\r\n ngOnDestroy() {\r\n this.autoCloseTimers.forEach(timer => clearTimeout(timer));\r\n }\r\n\r\n togglePanel() {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n closePanel() {\r\n this.isOpen = false;\r\n }\r\n\r\n get unreadCount(): number {\r\n return this.notifications.filter(n => !n.read).length;\r\n }\r\n\r\n get groupedNotifications(): { category: string; notifications: Notification[] }[] {\r\n if (!this.groupByCategory) {\r\n return [{ category: 'all', notifications: this.notifications }];\r\n }\r\n\r\n const groups = new Map<string, Notification[]>();\r\n \r\n this.notifications.forEach(notification => {\r\n const category = notification.category || 'Outros';\r\n if (!groups.has(category)) {\r\n groups.set(category, []);\r\n }\r\n groups.get(category)!.push(notification);\r\n });\r\n\r\n return Array.from(groups.entries()).map(([category, notifications]) => ({\r\n category,\r\n notifications\r\n }));\r\n }\r\n\r\n showToast(notification: Notification) {\r\n // Add to active toasts\r\n if (this.activeToasts.length >= this.maxToasts) {\r\n this.activeToasts.shift();\r\n }\r\n \r\n this.activeToasts.push(notification);\r\n\r\n // Auto close if enabled\r\n if (notification.autoClose !== false) {\r\n const duration = notification.duration || this.defaultDuration;\r\n const timer = setTimeout(() => {\r\n this.dismissToast(notification.id);\r\n }, duration);\r\n \r\n this.autoCloseTimers.set(notification.id, timer);\r\n }\r\n }\r\n\r\n dismissToast(id: string) {\r\n const index = this.activeToasts.findIndex(t => t.id === id);\r\n if (index !== -1) {\r\n this.activeToasts.splice(index, 1);\r\n }\r\n \r\n if (this.autoCloseTimers.has(id)) {\r\n clearTimeout(this.autoCloseTimers.get(id));\r\n this.autoCloseTimers.delete(id);\r\n }\r\n }\r\n\r\n markAsRead(notification: Notification) {\r\n if (!notification.read) {\r\n notification.read = true;\r\n this.notificationRead.emit(notification.id);\r\n }\r\n }\r\n\r\n markAllAsRead() {\r\n this.notifications.forEach(n => n.read = true);\r\n this.allRead.emit();\r\n }\r\n\r\n dismissNotification(notification: Notification, event?: Event) {\r\n event?.stopPropagation();\r\n const index = this.notifications.indexOf(notification);\r\n if (index !== -1) {\r\n this.notifications.splice(index, 1);\r\n this.notificationDismissed.emit(notification.id);\r\n }\r\n }\r\n\r\n clearAll() {\r\n this.notifications.length = 0;\r\n this.allCleared.emit();\r\n }\r\n\r\n executeAction(notification: Notification, event?: Event) {\r\n event?.stopPropagation();\r\n \r\n if (notification.actionCallback) {\r\n notification.actionCallback();\r\n }\r\n \r\n this.notificationAction.emit(notification);\r\n this.markAsRead(notification);\r\n }\r\n\r\n getIcon(type: NotificationType): string {\r\n const icons = {\r\n success: '✅',\r\n info: 'ℹ️',\r\n warning: '⚠️',\r\n error: '❌'\r\n };\r\n return icons[type];\r\n }\r\n\r\n formatTimestamp(date: Date): string {\r\n const now = new Date();\r\n const diff = now.getTime() - date.getTime();\r\n \r\n const minutes = Math.floor(diff / 60000);\r\n const hours = Math.floor(diff / 3600000);\r\n const days = Math.floor(diff / 86400000);\r\n \r\n if (minutes < 1) return 'Agora';\r\n if (minutes < 60) return `${minutes}m atrás`;\r\n if (hours < 24) return `${hours}h atrás`;\r\n if (days < 7) return `${days}d atrás`;\r\n \r\n return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });\r\n }\r\n\r\n get positionClass(): string {\r\n return `position-${this.position}`;\r\n }\r\n}\r\n","<!-- Notification Bell Icon -->\r\n<div class=\"notification-bell\" (click)=\"togglePanel()\">\r\n <span class=\"bell-icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"showBadge && unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\r\n</div>\r\n\r\n<!-- Notification Panel -->\r\n<div class=\"notification-panel\" [class.open]=\"isOpen\" [@slideDown]>\r\n <div class=\"panel-header\">\r\n <h3>Notificações</h3>\r\n <div class=\"header-actions\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadCount > 0\" title=\"Marcar todas como lidas\">\r\n <span>✓</span>\r\n </button>\r\n <button class=\"action-btn\" (click)=\"clearAll()\" *ngIf=\"notifications.length > 0\" title=\"Limpar todas\">\r\n <span>🗑️</span>\r\n </button>\r\n <button class=\"action-btn close-btn\" (click)=\"closePanel()\" title=\"Fechar\">\r\n <span>✕</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"panel-body\">\r\n <div *ngIf=\"notifications.length === 0\" class=\"empty-state\">\r\n <div class=\"empty-icon\">🔕</div>\r\n <p>Nenhuma notificação</p>\r\n </div>\r\n\r\n <div *ngIf=\"notifications.length > 0\">\r\n <div *ngFor=\"let group of groupedNotifications\" class=\"notification-group\">\r\n <h4 class=\"group-title\" *ngIf=\"groupByCategory\">{{ group.category }}</h4>\r\n \r\n <div *ngFor=\"let notification of group.notifications\" \r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.read\"\r\n [class.type-success]=\"notification.type === 'success'\"\r\n [class.type-info]=\"notification.type === 'info'\"\r\n [class.type-warning]=\"notification.type === 'warning'\"\r\n [class.type-error]=\"notification.type === 'error'\"\r\n (click)=\"markAsRead(notification)\">\r\n \r\n <div class=\"notification-icon\">\r\n <span>{{ getIcon(notification.type) }}</span>\r\n </div>\r\n\r\n <div class=\"notification-content\">\r\n <div class=\"notification-header\">\r\n <h5 class=\"notification-title\">{{ notification.title }}</h5>\r\n <span class=\"notification-time\">{{ formatTimestamp(notification.timestamp) }}</span>\r\n </div>\r\n <p class=\"notification-message\">{{ notification.message }}</p>\r\n \r\n <button *ngIf=\"notification.actionLabel\" \r\n class=\"notification-action\"\r\n (click)=\"executeAction(notification, $event)\">\r\n {{ notification.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"dismiss-btn\" (click)=\"dismissNotification(notification, $event)\" title=\"Dispensar\">\r\n <span>✕</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Toast Notifications -->\r\n<div class=\"toast-container\" [class]=\"positionClass\">\r\n <div *ngFor=\"let toast of activeToasts\" \r\n class=\"toast-notification\"\r\n [class.type-success]=\"toast.type === 'success'\"\r\n [class.type-info]=\"toast.type === 'info'\"\r\n [class.type-warning]=\"toast.type === 'warning'\"\r\n [class.type-error]=\"toast.type === 'error'\"\r\n [@slideIn]>\r\n \r\n <div class=\"toast-icon\">\r\n <span>{{ getIcon(toast.type) }}</span>\r\n </div>\r\n\r\n <div class=\"toast-content\">\r\n <h5 class=\"toast-title\">{{ toast.title }}</h5>\r\n <p class=\"toast-message\">{{ toast.message }}</p>\r\n \r\n <button *ngIf=\"toast.actionLabel\" \r\n class=\"toast-action\"\r\n (click)=\"executeAction(toast, $event)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n </div>\r\n\r\n <button class=\"toast-close\" (click)=\"dismissToast(toast.id)\" title=\"Fechar\">\r\n <span>✕</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<!-- Overlay -->\r\n<div class=\"overlay\" *ngIf=\"isOpen\" (click)=\"closePanel()\"></div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './lib/notification-center/notification-center.component';
@@ -0,0 +1,53 @@
1
+ import { EventEmitter, OnDestroy } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export type NotificationType = 'success' | 'info' | 'warning' | 'error';
4
+ export type NotificationPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
5
+ export interface Notification {
6
+ id: string;
7
+ type: NotificationType;
8
+ title: string;
9
+ message: string;
10
+ timestamp: Date;
11
+ read: boolean;
12
+ category?: string;
13
+ actionLabel?: string;
14
+ actionCallback?: () => void;
15
+ autoClose?: boolean;
16
+ duration?: number;
17
+ }
18
+ export declare class NotificationCenterComponent implements OnDestroy {
19
+ notifications: Notification[];
20
+ position: NotificationPosition;
21
+ maxToasts: number;
22
+ defaultDuration: number;
23
+ showBadge: boolean;
24
+ groupByCategory: boolean;
25
+ notificationRead: EventEmitter<string>;
26
+ notificationDismissed: EventEmitter<string>;
27
+ notificationAction: EventEmitter<Notification>;
28
+ allRead: EventEmitter<void>;
29
+ allCleared: EventEmitter<void>;
30
+ isOpen: boolean;
31
+ activeToasts: Notification[];
32
+ private autoCloseTimers;
33
+ ngOnDestroy(): void;
34
+ togglePanel(): void;
35
+ closePanel(): void;
36
+ get unreadCount(): number;
37
+ get groupedNotifications(): {
38
+ category: string;
39
+ notifications: Notification[];
40
+ }[];
41
+ showToast(notification: Notification): void;
42
+ dismissToast(id: string): void;
43
+ markAsRead(notification: Notification): void;
44
+ markAllAsRead(): void;
45
+ dismissNotification(notification: Notification, event?: Event): void;
46
+ clearAll(): void;
47
+ executeAction(notification: Notification, event?: Event): void;
48
+ getIcon(type: NotificationType): string;
49
+ formatTimestamp(date: Date): string;
50
+ get positionClass(): string;
51
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotificationCenterComponent, never>;
52
+ static ɵcmp: i0.ɵɵComponentDeclaration<NotificationCenterComponent, "muxima-notification-center", never, { "notifications": "notifications"; "position": "position"; "maxToasts": "maxToasts"; "defaultDuration": "defaultDuration"; "showBadge": "showBadge"; "groupByCategory": "groupByCategory"; }, { "notificationRead": "notificationRead"; "notificationDismissed": "notificationDismissed"; "notificationAction": "notificationAction"; "allRead": "allRead"; "allCleared": "allCleared"; }, never, never, true, never>;
53
+ }
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@muxima-ui/notification-center",
3
+ "version": "1.0.0",
4
+ "description": "Notification center component for Angular 18+ - Muxima UI",
5
+ "keywords": [
6
+ "angular",
7
+ "notification",
8
+ "notification-center",
9
+ "alerts",
10
+ "inbox",
11
+ "muxima-ui"
12
+ ],
13
+ "author": "Muxima UI Team (jokerscript)",
14
+ "license": "MIT",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/Aldemiro20/muxima-ui.git",
18
+ "directory": "packages/overlay/notification-center"
19
+ },
20
+ "homepage": "https://muxima-ui.vercel.app/components/notification-center",
21
+ "bugs": {
22
+ "url": "https://github.com/Aldemiro20/muxima-ui/issues"
23
+ },
24
+ "documentation": "https://muxima-ui.vercel.app",
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "peerDependencies": {
29
+ "@angular/animations": "^18.0.0",
30
+ "@angular/common": "^18.0.0",
31
+ "@angular/core": "^18.0.0"
32
+ },
33
+ "dependencies": {
34
+ "tslib": "^2.3.0"
35
+ },
36
+ "sideEffects": false,
37
+ "module": "fesm2015/muxima-ui-notification-center.mjs",
38
+ "es2020": "fesm2020/muxima-ui-notification-center.mjs",
39
+ "esm2020": "esm2020/muxima-ui-notification-center.mjs",
40
+ "fesm2020": "fesm2020/muxima-ui-notification-center.mjs",
41
+ "fesm2015": "fesm2015/muxima-ui-notification-center.mjs",
42
+ "typings": "index.d.ts",
43
+ "exports": {
44
+ "./package.json": {
45
+ "default": "./package.json"
46
+ },
47
+ ".": {
48
+ "types": "./index.d.ts",
49
+ "esm2020": "./esm2020/muxima-ui-notification-center.mjs",
50
+ "es2020": "./fesm2020/muxima-ui-notification-center.mjs",
51
+ "es2015": "./fesm2015/muxima-ui-notification-center.mjs",
52
+ "node": "./fesm2015/muxima-ui-notification-center.mjs",
53
+ "default": "./fesm2020/muxima-ui-notification-center.mjs"
54
+ }
55
+ }
56
+ }