tudu-components 0.2.11 → 0.2.13

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.
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, Input, HostListener, EventEmitter, Output, NgModule, Injectable } from '@angular/core';
3
- import * as i2 from '@angular/common';
2
+ import { Component, Input, EventEmitter, Output, HostListener, NgModule, Injectable } from '@angular/core';
3
+ import * as i1$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1 from '@angular/router';
6
6
  import { NavigationEnd } from '@angular/router';
@@ -88,7 +88,7 @@ class CardLayoutComponent {
88
88
  }
89
89
  }
90
90
  CardLayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CardLayoutComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
91
- CardLayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CardLayoutComponent, selector: "lib-card-layout", inputs: { statusPedido: "statusPedido", cardTemplateIndicator: "cardTemplateIndicator", hideHeader: "hideHeader" }, ngImport: i0, template: "<div\n class=\"service-card rounded-xl shadow-md overflow-hidden bg-white hover:shadow-lg transition-all duration-300 relative mb-5\"\n>\n <div\n [class.force-show]=\"!hideHeader\"\n class=\"service-card-header flex items-center justify-between p-3 border-b border-gray-200\"\n >\n <div class=\"flex items-center gap-3 w-full min-w-0\">\n <div class=\"icon-style flex-shrink-0\">\n <ng-content select=\"[service-icon]\"></ng-content>\n </div>\n\n <div class=\"flex flex-col flex-1 min-w-0\">\n <div class=\"flex items-center gap-3 w-full min-w-0\">\n <div class=\"service-title truncate flex-1 min-w-0\">\n <ng-content select=\"[service-title]\"></ng-content>\n </div>\n\n <div class=\"flex-shrink-0\">\n <ng-content select=\"[details-btn]\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"truncate w-full\"\n style=\"\n font-size: 12px;\n color: var(--tab-link);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n <ng-content select=\"[service-address]\"></ng-content>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"service-card-body p-4 space-y-3\">\n <div>\n <div\n class=\"flex flex-col items-start gap-3 border-b border-gray-100 pb-3 mb-3\"\n *ngIf=\"cardTemplateIndicator === 1\"\n >\n <div class=\"flex justify-between w-full pb-2\">\n <div class=\"status-badge\" [ngStyle]=\"badgeStyles\">\n <ng-content select=\"[status-badge]\"></ng-content>\n </div>\n\n <div\n class=\"text-xs text-gray-50 font-semibold\"\n style=\"\n background-color: #d3d3d32c;\n color: grey;\n border-radius: 25px;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 4px 10px;\n \"\n >\n <ng-content select=\"[order-number]\"></ng-content>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2 items-center\">\n <ng-content select=\"[filter-tag]\"></ng-content>\n </div>\n </div>\n\n <div class=\"fw-semibold\" *ngIf=\"statusPedido === 'finalizado'\">\n <ng-content select=\"[conclusion-date]\"></ng-content>\n </div>\n </div>\n <ng-content select=\"[info-row]\"></ng-content>\n\n <ng-content select=\"[description]\"></ng-content>\n </div>\n\n <div\n class=\"service-card-footer flex justify-center items-center p-3 border-t border-gray-100 bg-gray-50 gap-1\"\n >\n <div class=\"col-6\">\n <ng-content select=\"[main-btn]\"></ng-content>\n </div>\n <div\n class=\"fw-semibold col-6\"\n style=\"display: flex; justify-content: flex-end\"\n >\n <ng-content select=\"[price]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".service-card{background:var(--light, #fff);border-radius:1rem;transition:all .3s ease;.service-card-header i {color: var(--primary); font-size: 20px;} .order-badge {background-color: #d3d3d32c; color: grey; border-radius: 25px; padding: 5px;} .template-2-order {margin-top: -6em;} &[data-template=\"1\"] {} &[data-template=\"2\"] {} .status-badge {display: inline-flex; align-items: center; gap: 4px; font-weight: 600; font-size: 12px; padding: 4px 10px; border-radius: 25px; text-transform: capitalize; transition: all .3s ease; i {color: inherit !important;}} .filter-tag {background: var(--tag-bg, #f9fafb); border: 1px solid var(--primary); border-radius: 9999px; padding: .25rem .75rem; color: var(--primary); font-size: 12px;} .details-btn {cursor: pointer;} .price {font-weight: 600; font-size: 1rem; color: var(--primary);} .service-address {font-size: 13px; color: rgb(212,212,212) !important;} .icon-style {display: flex; justify-content: center; align-items: center; background-color: var(--primary) !important; width: 40px; height: 40px; font-size: 12px; font-size: 20px; border-radius: 10px;} .price {font-weight: 600; color: var(--background-color);} .service-title {flex: 1; min-width: 0; display: block; font-weight: 600; font-size: 1.1rem; ::ng-deep > * {display: block !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; width: 100%;}} .badge-finalizado {background-color: #e0f7fa; color: #00796b;} .badge-concluido {background-color: #e8f5e9; color: #2e7d32;} .badge-cancelado {background-color: #ffebee; color: #c62828;} .badge-publicado {background-color: #fff3e0; color: #25a5ff;} .badge-default {background-color: #eeeeee; color: #757575;}}.prestador-photo{width:100%;height:100%;object-fit:cover;border-radius:50%}.budget-card-footer button{width:100%;border-radius:8px;font-weight:600;transition:.2s}.status-badge i.notification-pulse{animation:pulse 2s infinite}:host-context(.has-notification) .status-badge i{animation:pulse 2s infinite}.service-card-header{display:none}@media (min-width: 768px){.service-card-header{display:block}}.service-card-header.force-show{display:block}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
91
+ CardLayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CardLayoutComponent, selector: "lib-card-layout", inputs: { statusPedido: "statusPedido", cardTemplateIndicator: "cardTemplateIndicator", hideHeader: "hideHeader" }, ngImport: i0, template: "<div\n class=\"service-card rounded-xl shadow-md overflow-hidden bg-white hover:shadow-lg transition-all duration-300 relative mb-5\"\n>\n <div\n [class.force-show]=\"!hideHeader\"\n class=\"service-card-header flex items-center justify-between p-3 border-b border-gray-200\"\n >\n <div class=\"flex items-center gap-3 w-full min-w-0\">\n <div class=\"icon-style flex-shrink-0\">\n <ng-content select=\"[service-icon]\"></ng-content>\n </div>\n\n <div class=\"flex flex-col flex-1 min-w-0\">\n <div class=\"flex items-center gap-3 w-full min-w-0\">\n <div class=\"service-title truncate flex-1 min-w-0\">\n <ng-content select=\"[service-title]\"></ng-content>\n </div>\n\n <div class=\"flex-shrink-0\">\n <ng-content select=\"[details-btn]\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"truncate w-full\"\n style=\"\n font-size: 12px;\n color: var(--tab-link);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n <ng-content select=\"[service-address]\"></ng-content>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"service-card-body p-4 space-y-3\">\n <div>\n <div\n class=\"flex flex-col items-start gap-3 border-b border-gray-100 pb-3 mb-3\"\n *ngIf=\"cardTemplateIndicator === 1\"\n >\n <div class=\"flex justify-between w-full pb-2\">\n <div class=\"status-badge\" [ngStyle]=\"badgeStyles\">\n <ng-content select=\"[status-badge]\"></ng-content>\n </div>\n\n <div\n class=\"text-xs text-gray-50 font-semibold\"\n style=\"\n background-color: #d3d3d32c;\n color: grey;\n border-radius: 25px;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 4px 10px;\n \"\n >\n <ng-content select=\"[order-number]\"></ng-content>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2 items-center\">\n <ng-content select=\"[filter-tag]\"></ng-content>\n </div>\n </div>\n\n <div class=\"fw-semibold\" *ngIf=\"statusPedido === 'finalizado'\">\n <ng-content select=\"[conclusion-date]\"></ng-content>\n </div>\n </div>\n <ng-content select=\"[info-row]\"></ng-content>\n\n <ng-content select=\"[description]\"></ng-content>\n </div>\n\n <div\n class=\"service-card-footer flex justify-center items-center p-3 border-t border-gray-100 bg-gray-50 gap-1\"\n >\n <div class=\"col-6\">\n <ng-content select=\"[main-btn]\"></ng-content>\n </div>\n <div\n class=\"fw-semibold col-6\"\n style=\"display: flex; justify-content: flex-end\"\n >\n <ng-content select=\"[price]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".service-card{background:var(--light, #fff);border-radius:1rem;transition:all .3s ease;.service-card-header i {color: var(--primary); font-size: 20px;} .order-badge {background-color: #d3d3d32c; color: grey; border-radius: 25px; padding: 5px;} .template-2-order {margin-top: -6em;} &[data-template=\"1\"] {} &[data-template=\"2\"] {} .status-badge {display: inline-flex; align-items: center; gap: 4px; font-weight: 600; font-size: 12px; padding: 4px 10px; border-radius: 25px; text-transform: capitalize; transition: all .3s ease; i {color: inherit !important;}} .filter-tag {background: var(--tag-bg, #f9fafb); border: 1px solid var(--primary); border-radius: 9999px; padding: .25rem .75rem; color: var(--primary); font-size: 12px;} .details-btn {cursor: pointer;} .price {font-weight: 600; font-size: 1rem; color: var(--primary);} .service-address {font-size: 13px; color: rgb(212,212,212) !important;} .icon-style {display: flex; justify-content: center; align-items: center; background-color: var(--primary) !important; width: 40px; height: 40px; font-size: 12px; font-size: 20px; border-radius: 10px;} .price {font-weight: 600; color: var(--background-color);} .service-title {flex: 1; min-width: 0; display: block; font-weight: 600; font-size: 1.1rem; ::ng-deep > * {display: block !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; width: 100%;}} .badge-finalizado {background-color: #e0f7fa; color: #00796b;} .badge-concluido {background-color: #e8f5e9; color: #2e7d32;} .badge-cancelado {background-color: #ffebee; color: #c62828;} .badge-publicado {background-color: #fff3e0; color: #25a5ff;} .badge-default {background-color: #eeeeee; color: #757575;}}.prestador-photo{width:100%;height:100%;object-fit:cover;border-radius:50%}.budget-card-footer button{width:100%;border-radius:8px;font-weight:600;transition:.2s}.status-badge i.notification-pulse{animation:pulse 2s infinite}:host-context(.has-notification) .status-badge i{animation:pulse 2s infinite}.service-card-header{display:none}@media (min-width: 768px){.service-card-header{display:block}}.service-card-header.force-show{display:block}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
92
92
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CardLayoutComponent, decorators: [{
93
93
  type: Component,
94
94
  args: [{ selector: 'lib-card-layout', template: "<div\n class=\"service-card rounded-xl shadow-md overflow-hidden bg-white hover:shadow-lg transition-all duration-300 relative mb-5\"\n>\n <div\n [class.force-show]=\"!hideHeader\"\n class=\"service-card-header flex items-center justify-between p-3 border-b border-gray-200\"\n >\n <div class=\"flex items-center gap-3 w-full min-w-0\">\n <div class=\"icon-style flex-shrink-0\">\n <ng-content select=\"[service-icon]\"></ng-content>\n </div>\n\n <div class=\"flex flex-col flex-1 min-w-0\">\n <div class=\"flex items-center gap-3 w-full min-w-0\">\n <div class=\"service-title truncate flex-1 min-w-0\">\n <ng-content select=\"[service-title]\"></ng-content>\n </div>\n\n <div class=\"flex-shrink-0\">\n <ng-content select=\"[details-btn]\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"truncate w-full\"\n style=\"\n font-size: 12px;\n color: var(--tab-link);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n \"\n >\n <ng-content select=\"[service-address]\"></ng-content>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"service-card-body p-4 space-y-3\">\n <div>\n <div\n class=\"flex flex-col items-start gap-3 border-b border-gray-100 pb-3 mb-3\"\n *ngIf=\"cardTemplateIndicator === 1\"\n >\n <div class=\"flex justify-between w-full pb-2\">\n <div class=\"status-badge\" [ngStyle]=\"badgeStyles\">\n <ng-content select=\"[status-badge]\"></ng-content>\n </div>\n\n <div\n class=\"text-xs text-gray-50 font-semibold\"\n style=\"\n background-color: #d3d3d32c;\n color: grey;\n border-radius: 25px;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 4px 10px;\n \"\n >\n <ng-content select=\"[order-number]\"></ng-content>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2 items-center\">\n <ng-content select=\"[filter-tag]\"></ng-content>\n </div>\n </div>\n\n <div class=\"fw-semibold\" *ngIf=\"statusPedido === 'finalizado'\">\n <ng-content select=\"[conclusion-date]\"></ng-content>\n </div>\n </div>\n <ng-content select=\"[info-row]\"></ng-content>\n\n <ng-content select=\"[description]\"></ng-content>\n </div>\n\n <div\n class=\"service-card-footer flex justify-center items-center p-3 border-t border-gray-100 bg-gray-50 gap-1\"\n >\n <div class=\"col-6\">\n <ng-content select=\"[main-btn]\"></ng-content>\n </div>\n <div\n class=\"fw-semibold col-6\"\n style=\"display: flex; justify-content: flex-end\"\n >\n <ng-content select=\"[price]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".service-card{background:var(--light, #fff);border-radius:1rem;transition:all .3s ease;.service-card-header i {color: var(--primary); font-size: 20px;} .order-badge {background-color: #d3d3d32c; color: grey; border-radius: 25px; padding: 5px;} .template-2-order {margin-top: -6em;} &[data-template=\"1\"] {} &[data-template=\"2\"] {} .status-badge {display: inline-flex; align-items: center; gap: 4px; font-weight: 600; font-size: 12px; padding: 4px 10px; border-radius: 25px; text-transform: capitalize; transition: all .3s ease; i {color: inherit !important;}} .filter-tag {background: var(--tag-bg, #f9fafb); border: 1px solid var(--primary); border-radius: 9999px; padding: .25rem .75rem; color: var(--primary); font-size: 12px;} .details-btn {cursor: pointer;} .price {font-weight: 600; font-size: 1rem; color: var(--primary);} .service-address {font-size: 13px; color: rgb(212,212,212) !important;} .icon-style {display: flex; justify-content: center; align-items: center; background-color: var(--primary) !important; width: 40px; height: 40px; font-size: 12px; font-size: 20px; border-radius: 10px;} .price {font-weight: 600; color: var(--background-color);} .service-title {flex: 1; min-width: 0; display: block; font-weight: 600; font-size: 1.1rem; ::ng-deep > * {display: block !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; width: 100%;}} .badge-finalizado {background-color: #e0f7fa; color: #00796b;} .badge-concluido {background-color: #e8f5e9; color: #2e7d32;} .badge-cancelado {background-color: #ffebee; color: #c62828;} .badge-publicado {background-color: #fff3e0; color: #25a5ff;} .badge-default {background-color: #eeeeee; color: #757575;}}.prestador-photo{width:100%;height:100%;object-fit:cover;border-radius:50%}.budget-card-footer button{width:100%;border-radius:8px;font-weight:600;transition:.2s}.status-badge i.notification-pulse{animation:pulse 2s infinite}:host-context(.has-notification) .status-badge i{animation:pulse 2s infinite}.service-card-header{display:none}@media (min-width: 768px){.service-card-header{display:block}}.service-card-header.force-show{display:block}\n"] }]
@@ -100,100 +100,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
100
100
  type: Input
101
101
  }] } });
102
102
 
103
- class NavComponent {
104
- constructor(router, activatedRoute, el) {
105
- this.router = router;
106
- this.activatedRoute = activatedRoute;
107
- this.el = el;
108
- this.changeNavColor = false;
109
- this.openClose = false;
103
+ class CustomModalComponent {
104
+ constructor(location) {
105
+ this.location = location;
106
+ this.modalId = 'customModal';
107
+ this.title = 'Aviso';
110
108
  this.message = '';
111
- this.lastScrollPosition = 0;
112
- this.isHeaderVisible = true;
113
- this.headerHeight = 0;
114
- this.isMobile = false;
115
- this.hasOffer = false;
116
- this.allowTransparency = false;
117
- this.router.events
118
- .pipe(filter((event) => event instanceof NavigationEnd), map(() => this.activatedRoute), map((route) => {
119
- while (route.firstChild)
120
- route = route.firstChild;
121
- return route;
122
- }), mergeMap((route) => route.data))
123
- .subscribe((data) => {
124
- this.allowTransparency = !!data['transparentNav'];
125
- this.lastScrollPosition = 0;
126
- this.isHeaderVisible = true; // força aparecer no load
127
- this.changeNavColor = !this.allowTransparency;
128
- });
129
- }
130
- ngAfterViewInit() {
131
- this.checkMobile();
132
- // Obtém a altura do header-menu após a view ser inicializada
133
- const headerMenu = this.el.nativeElement.querySelector('[header-menu]');
134
- if (headerMenu) {
135
- this.headerHeight = headerMenu.offsetHeight;
136
- }
109
+ this.closeButtonText = 'Fechar';
110
+ this.actionButtonText = '';
111
+ this.paymentMethod = null;
112
+ this.errorDetails = null;
113
+ this.modalClosed = new EventEmitter();
114
+ this.modalAction = new EventEmitter();
115
+ this.showModal = false;
116
+ this.messageTitle = 'Pagamento Aprovado!';
117
+ this.showBtn = true;
118
+ this.priceNegotiated = 0;
119
+ this.messageBody = 'Seu pagamento foi processado com sucesso.';
120
+ // Configuração dinâmica
121
+ this.modalIcon = 'fa-check';
122
+ this.modalIconColor = 'text-green-600';
123
+ this.modalBgColor = 'bg-green-100';
124
+ this.isClosing = false;
137
125
  }
138
- ngOnInit() {
139
- this.hasOffer = this.router.url.includes('offer');
126
+ ngOnInit() { }
127
+ // Centraliza a abertura do modal com suporte ao botão voltar
128
+ openModal() {
129
+ this.showModal = true;
130
+ // Adiciona um estado no histórico para o botão voltar funcionar
131
+ this.location.go(this.location.path() + '#modalOpen');
140
132
  }
141
- onResize() {
142
- this.checkMobile();
133
+ // Atalho para abrir com tipos específicos
134
+ open(type, message = '', paymentMethod) {
135
+ this.configureModal(type, message);
136
+ if (paymentMethod) {
137
+ this.paymentMethod = paymentMethod;
138
+ }
139
+ this.openModal();
143
140
  }
144
- checkMobile() {
145
- this.isMobile = window.innerWidth < 768; // 768px é o breakpoint padrão do Tailwind para md
146
- if (!this.isMobile) {
147
- this.isHeaderVisible = true; // Garante que fique visível em desktop
141
+ configureModal(type, message = '') {
142
+ switch (type) {
143
+ case 'success':
144
+ this.setSuccessStyles(message);
145
+ break;
146
+ case 'error':
147
+ this.setErrorStyles(message);
148
+ break;
149
+ case 'warning':
150
+ this.setWarningStyles(message);
151
+ break;
148
152
  }
149
153
  }
150
- menu() {
151
- this.openClose = !this.openClose;
154
+ setSuccessStyles(message) {
155
+ this.modalIcon = 'fa-check-circle';
156
+ this.modalIconColor = 'modal-icon-success';
157
+ this.modalBgColor = 'modal-bg-success';
158
+ this.messageTitle = 'Sucesso!';
159
+ this.messageBody = message || 'Operação realizada com sucesso.';
152
160
  }
153
- receiveMessage(event) {
154
- this.message = event;
161
+ setErrorStyles(message) {
162
+ this.modalIcon = 'fa-times-circle';
163
+ this.modalIconColor = 'modal-icon-error';
164
+ this.modalBgColor = 'modal-bg-error';
165
+ this.messageTitle = 'Ops! Algo deu errado';
166
+ this.messageBody = message || 'Não conseguimos processar sua solicitação.';
155
167
  }
156
- onWindowScroll() {
157
- const scroll = window.pageYOffset || document.documentElement.scrollTop;
158
- const isScrollingDown = scroll > this.lastScrollPosition;
159
- /* =========================
160
- * VISIBILIDADE
161
- * ========================= */
162
- if (scroll <= 10) {
163
- // TOPO
164
- this.isHeaderVisible = !isScrollingDown;
165
- }
166
- else if (isScrollingDown && scroll > 50) {
167
- // SCROLL DOWN
168
- this.isHeaderVisible = false;
168
+ setWarningStyles(message) {
169
+ this.modalIcon = 'fa-exclamation-circle';
170
+ this.modalIconColor = 'modal-icon-warning';
171
+ this.modalBgColor = 'modal-bg-warning';
172
+ this.messageTitle = 'Atenção';
173
+ this.messageBody = message || 'Verifique os dados antes de continuar.';
174
+ }
175
+ actionModal() {
176
+ if (this.isLoadingBtn !== undefined) {
177
+ this.isLoadingBtn = true;
178
+ this.modalAction.emit();
169
179
  }
170
180
  else {
171
- // SCROLL UP
172
- this.isHeaderVisible = true;
173
- }
174
- /* =========================
175
- * COR
176
- * ========================= */
177
- if (!this.allowTransparency) {
178
- this.changeNavColor = true;
181
+ this.modalAction.emit();
182
+ this.isLoadingBtn = false;
183
+ this.closeModal(); // Usa o método de fechar para limpar o histórico
179
184
  }
180
- else {
181
- this.changeNavColor = scroll > 20;
185
+ }
186
+ closeModal() {
187
+ this.isClosing = true; // Ativa a animação de descida
188
+ // Aguarda o tempo da animação (300ms) antes de remover do DOM
189
+ setTimeout(() => {
190
+ this.showModal = false;
191
+ this.isClosing = false; // Reseta para a próxima abertura
192
+ this.modalClosed.emit();
193
+ // Lógica do histórico que já fizemos
194
+ if (window.location.hash === '#modalOpen') {
195
+ const currentPath = this.location.path().split('#')[0];
196
+ this.location.replaceState(currentPath);
197
+ }
198
+ }, 300);
199
+ }
200
+ // Escuta o botão voltar do navegador ou celular
201
+ onPopState() {
202
+ if (this.showModal) {
203
+ this.showModal = false;
204
+ this.modalClosed.emit();
182
205
  }
183
- this.lastScrollPosition = scroll;
184
206
  }
185
207
  }
186
- NavComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
187
- NavComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NavComponent, selector: "lib-nav", host: { listeners: { "window:resize": "onResize()", "window:scroll": "onWindowScroll()" } }, ngImport: i0, template: "<!-- Overlay -->\n<div\n *ngIf=\"openClose\"\n (click)=\"openClose = false\"\n class=\"fixed inset-0 bg-black bg-opacity-40 z-40 md:hidden\"\n></div>\n\n<div\n class=\"fixed top-0 left-0 right-0 z-50 shadow-none transition-all duration-500 w-full\"\n [class.-translate-y-full]=\"!isHeaderVisible\"\n [style.background-color]=\"changeNavColor ? 'var(--primary)' : 'transparent'\"\n>\n <div class=\"w-full\">\n <div class=\"mx-auto px-2 h-16 flex items-center justify-between\">\n <!-- Left Content -->\n <div class=\"flex-1 flex justify-start\">\n <ng-content select=\"[left-content]\"></ng-content>\n </div>\n\n <!-- Center Content -->\n <div class=\"flex-1 flex justify-center\">\n <ng-content select=\"[central-content]\"></ng-content>\n </div>\n\n <!-- Right Content -->\n <div class=\"flex-1\" style=\"display: flex; justify-content: flex-end\">\n <ng-content select=\"[right-content]\"></ng-content>\n </div>\n </div>\n </div>\n\n <!-- Header Menu (Submenu) -->\n <div header-menu class=\"w-full\">\n <ng-content select=\"[header-menu]\"></ng-content>\n </div>\n</div>\n", styles: [".navbar-ajust{background-color:var(--medium);padding:1em}.container-fluid{display:flex;justify-content:space-between;align-items:center}.navbar-left,.navbar-right{flex:1;display:flex;justify-content:flex-start}.navbar-right{justify-content:flex-end}.navbar-center{flex:2;display:flex;justify-content:center}:host{display:block}.-translate-y-full{transform:translateY(calc(-100% - 1px))}.nav-transparent{background-color:var(--premium)!important}.nav-scrolled{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}@media (max-width: 767px){.-translate-y-full{transform:translateY(calc(-100% - 1px))}}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
188
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavComponent, decorators: [{
208
+ CustomModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomModalComponent, deps: [{ token: i1$1.Location }], target: i0.ɵɵFactoryTarget.Component });
209
+ CustomModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CustomModalComponent, selector: "lib-custom-modal", inputs: { modalId: "modalId", title: "title", message: "message", closeButtonText: "closeButtonText", actionButtonText: "actionButtonText", paymentMethod: "paymentMethod", errorDetails: "errorDetails", showModal: "showModal", messageTitle: "messageTitle", showBtn: "showBtn", priceNegotiated: "priceNegotiated", messageBody: "messageBody", isLoadingBtn: "isLoadingBtn" }, outputs: { modalClosed: "modalClosed", modalAction: "modalAction" }, host: { listeners: { "window:popstate": "onPopState()" } }, ngImport: i0, template: "<div\n *ngIf=\"showModal\"\n class=\"modal-overlay-fixed\"\n [ngClass]=\"{ 'overlay-hide': isClosing }\"\n (click)=\"closeModal()\"\n>\n <div\n class=\"bg-white w-full max-w-2xl rounded-t-[2.5rem] p-6 shadow-2xl border-t border-gray-100 flex flex-col\"\n [ngClass]=\"isClosing ? 'animate-slide-down' : 'animate-slide-up'\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"w-full py-4 -mt-2 cursor-pointer flex justify-center\"\n (click)=\"closeModal()\"\n >\n <div class=\"w-12 h-1.5 bg-gray-200 rounded-full\"></div>\n </div>\n\n <div class=\"flex flex-col items-center text-center\">\n <div class=\"relative mb-4\">\n <div\n [class]=\"modalBgColor\"\n class=\"w-20 h-20 rounded-full opacity-40\"\n ></div>\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <i\n [class]=\"modalIcon + ' ' + modalIconColor\"\n class=\"fas text-3xl\"\n ></i>\n </div>\n </div>\n\n <h2 class=\"text-2xl font-bold text-gray-900 mb-2\">{{ messageTitle }}</h2>\n\n <div class=\"w-full modal-scroll-area px-2 custom-scrollbar\">\n <p *ngIf=\"messageBody\" class=\"text-gray-600 mb-4\">{{ messageBody }}</p>\n\n <div class=\"modal-dynamic-content text-left\">\n <ng-content select=\"[optional-content]\"></ng-content>\n </div>\n\n <div\n *ngIf=\"errorDetails\"\n class=\"mt-4 p-4 bg-red-50 rounded-2xl text-left border border-red-100\"\n >\n <p class=\"text-[10px] font-bold text-red-700 uppercase mb-1\">\n Log do sistema:\n </p>\n <pre class=\"text-[11px] text-red-600 font-mono whitespace-pre-wrap\">{{\n errorDetails | json\n }}</pre>\n </div>\n </div>\n\n <div class=\"mt-6 flex flex-col w-full gap-3 pb-4\">\n <button\n [disabled]=\"priceNegotiated <= 0 && actionButtonText === 'Negociar'\"\n *ngIf=\"actionButtonText\"\n (click)=\"actionModal()\"\n class=\"w-full py-4 text-white rounded-2xl font-bold active:scale-[0.98] transition-all flex items-center justify-center gap-3 shadow-lg btn-primary-custom\"\n [style.background-color]=\"'var(--primary)'\"\n >\n <span *ngIf=\"!isLoadingBtn\">{{ actionButtonText }}</span>\n <ng-container *ngIf=\"isLoadingBtn\">\n <span>Processando</span>\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n </ng-container>\n </button>\n\n <button\n *ngIf=\"showBtn\"\n (click)=\"closeModal()\"\n class=\"w-full py-2 text-gray-500 font-semibold hover:text-gray-800 transition-colors\"\n >\n {{ closeButtonText }}\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes slideDown{0%{transform:translateY(0)}to{transform:translateY(100%)}}.animate-slide-up{animation:slideUp .4s cubic-bezier(.25,1,.5,1) forwards}.animate-slide-down{animation:slideDown .4s cubic-bezier(.25,1,.5,1) forwards}.modal-overlay-fixed{position:fixed;inset:0;background-color:#0009!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;display:flex;align-items:flex-end;justify-content:center;z-index:9999;transition:opacity .3s ease;opacity:1}.overlay-hide{opacity:0;pointer-events:none}.modal-scroll-area{max-height:60vh;overflow-y:auto;overflow-x:hidden;transition:max-height .4s cubic-bezier(.25,1,.5,1)}.modal-scroll-area:has(.animate-fade-in),.modal-scroll-area:focus-within{max-height:85vh}.modal-dynamic-content{height:auto;overflow:visible!important;display:block}.custom-scrollbar::-webkit-scrollbar{width:4px}.custom-scrollbar::-webkit-scrollbar-thumb{background:#f1f1f1;border-radius:10px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.btn-primary-custom:hover:not(:disabled){filter:brightness(.9);transition:filter .2s ease}.btn-primary-custom:disabled{opacity:.6;cursor:not-allowed}.modal-bg-success{background-color:#d1fae5!important}.modal-icon-success{color:#10b981!important}.modal-bg-error{background-color:#fee2e2!important}.modal-icon-error{color:#ef4444!important}.modal-bg-warning{background-color:#fef3c7!important}.modal-icon-warning{color:#f59e0b!important}@media (min-width: 768px){.modal-overlay-fixed{align-items:center}.animate-slide-up,.animate-slide-down{border-radius:2.5rem;width:90%;margin-bottom:0}@keyframes slideUp{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}@keyframes slideDown{0%{transform:scale(1);opacity:1}to{transform:scale(.9);opacity:0}}}:host-context(body:has(.modal-overlay-fixed)){overflow:hidden}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomModalComponent, decorators: [{
189
211
  type: Component,
190
- args: [{ selector: 'lib-nav', template: "<!-- Overlay -->\n<div\n *ngIf=\"openClose\"\n (click)=\"openClose = false\"\n class=\"fixed inset-0 bg-black bg-opacity-40 z-40 md:hidden\"\n></div>\n\n<div\n class=\"fixed top-0 left-0 right-0 z-50 shadow-none transition-all duration-500 w-full\"\n [class.-translate-y-full]=\"!isHeaderVisible\"\n [style.background-color]=\"changeNavColor ? 'var(--primary)' : 'transparent'\"\n>\n <div class=\"w-full\">\n <div class=\"mx-auto px-2 h-16 flex items-center justify-between\">\n <!-- Left Content -->\n <div class=\"flex-1 flex justify-start\">\n <ng-content select=\"[left-content]\"></ng-content>\n </div>\n\n <!-- Center Content -->\n <div class=\"flex-1 flex justify-center\">\n <ng-content select=\"[central-content]\"></ng-content>\n </div>\n\n <!-- Right Content -->\n <div class=\"flex-1\" style=\"display: flex; justify-content: flex-end\">\n <ng-content select=\"[right-content]\"></ng-content>\n </div>\n </div>\n </div>\n\n <!-- Header Menu (Submenu) -->\n <div header-menu class=\"w-full\">\n <ng-content select=\"[header-menu]\"></ng-content>\n </div>\n</div>\n", styles: [".navbar-ajust{background-color:var(--medium);padding:1em}.container-fluid{display:flex;justify-content:space-between;align-items:center}.navbar-left,.navbar-right{flex:1;display:flex;justify-content:flex-start}.navbar-right{justify-content:flex-end}.navbar-center{flex:2;display:flex;justify-content:center}:host{display:block}.-translate-y-full{transform:translateY(calc(-100% - 1px))}.nav-transparent{background-color:var(--premium)!important}.nav-scrolled{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}@media (max-width: 767px){.-translate-y-full{transform:translateY(calc(-100% - 1px))}}\n"] }]
191
- }], ctorParameters: function () { return [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i0.ElementRef }]; }, propDecorators: { onResize: [{
192
- type: HostListener,
193
- args: ['window:resize']
194
- }], onWindowScroll: [{
212
+ args: [{ selector: 'lib-custom-modal', standalone: false, template: "<div\n *ngIf=\"showModal\"\n class=\"modal-overlay-fixed\"\n [ngClass]=\"{ 'overlay-hide': isClosing }\"\n (click)=\"closeModal()\"\n>\n <div\n class=\"bg-white w-full max-w-2xl rounded-t-[2.5rem] p-6 shadow-2xl border-t border-gray-100 flex flex-col\"\n [ngClass]=\"isClosing ? 'animate-slide-down' : 'animate-slide-up'\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"w-full py-4 -mt-2 cursor-pointer flex justify-center\"\n (click)=\"closeModal()\"\n >\n <div class=\"w-12 h-1.5 bg-gray-200 rounded-full\"></div>\n </div>\n\n <div class=\"flex flex-col items-center text-center\">\n <div class=\"relative mb-4\">\n <div\n [class]=\"modalBgColor\"\n class=\"w-20 h-20 rounded-full opacity-40\"\n ></div>\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <i\n [class]=\"modalIcon + ' ' + modalIconColor\"\n class=\"fas text-3xl\"\n ></i>\n </div>\n </div>\n\n <h2 class=\"text-2xl font-bold text-gray-900 mb-2\">{{ messageTitle }}</h2>\n\n <div class=\"w-full modal-scroll-area px-2 custom-scrollbar\">\n <p *ngIf=\"messageBody\" class=\"text-gray-600 mb-4\">{{ messageBody }}</p>\n\n <div class=\"modal-dynamic-content text-left\">\n <ng-content select=\"[optional-content]\"></ng-content>\n </div>\n\n <div\n *ngIf=\"errorDetails\"\n class=\"mt-4 p-4 bg-red-50 rounded-2xl text-left border border-red-100\"\n >\n <p class=\"text-[10px] font-bold text-red-700 uppercase mb-1\">\n Log do sistema:\n </p>\n <pre class=\"text-[11px] text-red-600 font-mono whitespace-pre-wrap\">{{\n errorDetails | json\n }}</pre>\n </div>\n </div>\n\n <div class=\"mt-6 flex flex-col w-full gap-3 pb-4\">\n <button\n [disabled]=\"priceNegotiated <= 0 && actionButtonText === 'Negociar'\"\n *ngIf=\"actionButtonText\"\n (click)=\"actionModal()\"\n class=\"w-full py-4 text-white rounded-2xl font-bold active:scale-[0.98] transition-all flex items-center justify-center gap-3 shadow-lg btn-primary-custom\"\n [style.background-color]=\"'var(--primary)'\"\n >\n <span *ngIf=\"!isLoadingBtn\">{{ actionButtonText }}</span>\n <ng-container *ngIf=\"isLoadingBtn\">\n <span>Processando</span>\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n </ng-container>\n </button>\n\n <button\n *ngIf=\"showBtn\"\n (click)=\"closeModal()\"\n class=\"w-full py-2 text-gray-500 font-semibold hover:text-gray-800 transition-colors\"\n >\n {{ closeButtonText }}\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes slideDown{0%{transform:translateY(0)}to{transform:translateY(100%)}}.animate-slide-up{animation:slideUp .4s cubic-bezier(.25,1,.5,1) forwards}.animate-slide-down{animation:slideDown .4s cubic-bezier(.25,1,.5,1) forwards}.modal-overlay-fixed{position:fixed;inset:0;background-color:#0009!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;display:flex;align-items:flex-end;justify-content:center;z-index:9999;transition:opacity .3s ease;opacity:1}.overlay-hide{opacity:0;pointer-events:none}.modal-scroll-area{max-height:60vh;overflow-y:auto;overflow-x:hidden;transition:max-height .4s cubic-bezier(.25,1,.5,1)}.modal-scroll-area:has(.animate-fade-in),.modal-scroll-area:focus-within{max-height:85vh}.modal-dynamic-content{height:auto;overflow:visible!important;display:block}.custom-scrollbar::-webkit-scrollbar{width:4px}.custom-scrollbar::-webkit-scrollbar-thumb{background:#f1f1f1;border-radius:10px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.btn-primary-custom:hover:not(:disabled){filter:brightness(.9);transition:filter .2s ease}.btn-primary-custom:disabled{opacity:.6;cursor:not-allowed}.modal-bg-success{background-color:#d1fae5!important}.modal-icon-success{color:#10b981!important}.modal-bg-error{background-color:#fee2e2!important}.modal-icon-error{color:#ef4444!important}.modal-bg-warning{background-color:#fef3c7!important}.modal-icon-warning{color:#f59e0b!important}@media (min-width: 768px){.modal-overlay-fixed{align-items:center}.animate-slide-up,.animate-slide-down{border-radius:2.5rem;width:90%;margin-bottom:0}@keyframes slideUp{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}@keyframes slideDown{0%{transform:scale(1);opacity:1}to{transform:scale(.9);opacity:0}}}:host-context(body:has(.modal-overlay-fixed)){overflow:hidden}\n"] }]
213
+ }], ctorParameters: function () { return [{ type: i1$1.Location }]; }, propDecorators: { modalId: [{
214
+ type: Input
215
+ }], title: [{
216
+ type: Input
217
+ }], message: [{
218
+ type: Input
219
+ }], closeButtonText: [{
220
+ type: Input
221
+ }], actionButtonText: [{
222
+ type: Input
223
+ }], paymentMethod: [{
224
+ type: Input
225
+ }], errorDetails: [{
226
+ type: Input
227
+ }], modalClosed: [{
228
+ type: Output
229
+ }], modalAction: [{
230
+ type: Output
231
+ }], showModal: [{
232
+ type: Input
233
+ }], messageTitle: [{
234
+ type: Input
235
+ }], showBtn: [{
236
+ type: Input
237
+ }], priceNegotiated: [{
238
+ type: Input
239
+ }], messageBody: [{
240
+ type: Input
241
+ }], isLoadingBtn: [{
242
+ type: Input
243
+ }], onPopState: [{
195
244
  type: HostListener,
196
- args: ['window:scroll', []]
245
+ args: ['window:popstate']
197
246
  }] } });
198
247
 
199
248
  class FallbackMessageComponent {
@@ -300,7 +349,7 @@ class FallbackMessageComponent {
300
349
  }
301
350
  }
302
351
  FallbackMessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FallbackMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
303
- FallbackMessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: FallbackMessageComponent, selector: "lib-fallback-message", inputs: { card: "card", statusPedido: "statusPedido", customTitle: "customTitle", customDescription: "customDescription", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", hideBtn: "hideBtn" }, outputs: { primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, ngImport: i0, template: "<div *ngIf=\"shouldShowEmptyState()\" class=\"empty-state-container\">\n <div\n class=\"empty-state-card max-w-md mx-auto bg-white shadow-xl rounded-3xl p-8 border border-gray-100\"\n >\n <!-- \u00CDcone din\u00E2mico -->\n <div class=\"empty-state-icon mb-6 flex justify-center\">\n <div class=\"relative w-32 h-32 flex items-center justify-center\">\n <div [class]=\"emptyStateConfig.iconColor\" class=\"z-10\">\n <div class=\"text-xl leading-none\" style=\"font-size: 4rem\">\n {{ emptyStateConfig.icon }}\n </div>\n </div>\n\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <div\n [class]=\"emptyStateConfig.bgColor\"\n class=\"w-full h-full rounded-full opacity-50 flex-shrink-0\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Conte\u00FAdo da mensagem -->\n <div class=\"empty-state-content text-center space-y-4\">\n <!-- T\u00EDtulo -->\n <h3 class=\"text-2xl font-bold text-gray-900 mb-2\">\n {{ emptyStateConfig.title }}\n </h3>\n\n <!-- Descri\u00E7\u00E3o -->\n <p class=\"text-gray-600 text-lg leading-relaxed px-4\">\n {{ emptyStateConfig.description }}\n </p>\n\n <!-- Informa\u00E7\u00F5es adicionais baseadas no status -->\n <div *ngIf=\"statusPedido === 'finalizado'\" class=\"mt-4\">\n <div\n class=\"inline-flex items-center gap-2 bg-green-50 text-green-700 px-4 py-2 rounded-full\"\n >\n <i class=\"fas fa-check-circle\"></i>\n <span class=\"font-medium\">Servi\u00E7o avaliado e finalizado</span>\n </div>\n </div>\n\n <div *ngIf=\"statusPedido === 'cancelado'\" class=\"mt-4\">\n <div\n class=\"inline-flex items-center gap-2 bg-red-50 text-red-700 px-4 py-2 rounded-full\"\n >\n <i class=\"fas fa-exclamation-circle\"></i>\n <span class=\"font-medium\">Cancelado pelo prestador do servi\u00E7o</span>\n </div>\n </div>\n </div>\n\n <!-- A\u00E7\u00F5es -->\n <div class=\"mt-8 flex flex-col sm:flex-row gap-4 justify-center\">\n <!-- A\u00E7\u00E3o Prim\u00E1ria -->\n <button\n *ngIf=\"hideBtn\"\n (click)=\"onPrimaryAction()\"\n [ngClass]=\"{\n 'bg-green-600 hover:bg-green-700': statusPedido === 'finalizado',\n 'bg-red-600 hover:bg-red-700': statusPedido === 'cancelado',\n 'bg-blue-600 ':\n statusPedido === 'indispon\u00EDvel' || statusPedido === 'indisponivel',\n 'bg-primary-600 hover:bg-primary-700': card.length === 0\n }\"\n class=\"col-12 btn btn-primary\"\n >\n {{ emptyStateConfig.primaryActionText }}\n </button>\n\n <!-- A\u00E7\u00E3o Secund\u00E1ria -->\n <button\n *ngIf=\"emptyStateConfig.secondaryActionText\"\n (click)=\"onSecondaryAction()\"\n class=\"col-12 btn btn-outline-primary\"\n >\n {{ emptyStateConfig.secondaryActionText }}\n </button>\n </div>\n\n <!-- Link de ajuda (opcional) -->\n <div *ngIf=\"statusPedido === 'cancelado'\" class=\"mt-6 text-center\">\n <a\n href=\"#\"\n class=\"text-sm text-blue-600 hover:text-blue-800 hover:underline\"\n >\n <i class=\"fas fa-question-circle mr-2\"></i>\n Precisa de ajuda? Entre em contato com o suporte\n </a>\n </div>\n </div>\n</div>\n", styles: [".empty-state-card{animation:fadeInUp .5s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.empty-state-icon{animation:bounceIn .6s ease-out}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
352
+ FallbackMessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: FallbackMessageComponent, selector: "lib-fallback-message", inputs: { card: "card", statusPedido: "statusPedido", customTitle: "customTitle", customDescription: "customDescription", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", hideBtn: "hideBtn" }, outputs: { primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, ngImport: i0, template: "<div *ngIf=\"shouldShowEmptyState()\" class=\"empty-state-container\">\n <div\n class=\"empty-state-card max-w-md mx-auto bg-white shadow-xl rounded-3xl p-8 border border-gray-100\"\n >\n <!-- \u00CDcone din\u00E2mico -->\n <div class=\"empty-state-icon mb-6 flex justify-center\">\n <div class=\"relative w-32 h-32 flex items-center justify-center\">\n <div [class]=\"emptyStateConfig.iconColor\" class=\"z-10\">\n <div class=\"text-xl leading-none\" style=\"font-size: 4rem\">\n {{ emptyStateConfig.icon }}\n </div>\n </div>\n\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <div\n [class]=\"emptyStateConfig.bgColor\"\n class=\"w-full h-full rounded-full opacity-50 flex-shrink-0\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Conte\u00FAdo da mensagem -->\n <div class=\"empty-state-content text-center space-y-4\">\n <!-- T\u00EDtulo -->\n <h3 class=\"text-2xl font-bold text-gray-900 mb-2\">\n {{ emptyStateConfig.title }}\n </h3>\n\n <!-- Descri\u00E7\u00E3o -->\n <p class=\"text-gray-600 text-lg leading-relaxed px-4\">\n {{ emptyStateConfig.description }}\n </p>\n\n <!-- Informa\u00E7\u00F5es adicionais baseadas no status -->\n <div *ngIf=\"statusPedido === 'finalizado'\" class=\"mt-4\">\n <div\n class=\"inline-flex items-center gap-2 bg-green-50 text-green-700 px-4 py-2 rounded-full\"\n >\n <i class=\"fas fa-check-circle\"></i>\n <span class=\"font-medium\">Servi\u00E7o avaliado e finalizado</span>\n </div>\n </div>\n\n <div *ngIf=\"statusPedido === 'cancelado'\" class=\"mt-4\">\n <div\n class=\"inline-flex items-center gap-2 bg-red-50 text-red-700 px-4 py-2 rounded-full\"\n >\n <i class=\"fas fa-exclamation-circle\"></i>\n <span class=\"font-medium\">Cancelado pelo prestador do servi\u00E7o</span>\n </div>\n </div>\n </div>\n\n <!-- A\u00E7\u00F5es -->\n <div class=\"mt-8 flex flex-col sm:flex-row gap-4 justify-center\">\n <!-- A\u00E7\u00E3o Prim\u00E1ria -->\n <button\n *ngIf=\"hideBtn\"\n (click)=\"onPrimaryAction()\"\n [ngClass]=\"{\n 'bg-green-600 hover:bg-green-700': statusPedido === 'finalizado',\n 'bg-red-600 hover:bg-red-700': statusPedido === 'cancelado',\n 'bg-blue-600 ':\n statusPedido === 'indispon\u00EDvel' || statusPedido === 'indisponivel',\n 'bg-primary-600 hover:bg-primary-700': card.length === 0\n }\"\n class=\"col-12 btn btn-primary\"\n >\n {{ emptyStateConfig.primaryActionText }}\n </button>\n\n <!-- A\u00E7\u00E3o Secund\u00E1ria -->\n <button\n *ngIf=\"emptyStateConfig.secondaryActionText\"\n (click)=\"onSecondaryAction()\"\n class=\"col-12 btn btn-outline-primary\"\n >\n {{ emptyStateConfig.secondaryActionText }}\n </button>\n </div>\n\n <!-- Link de ajuda (opcional) -->\n <div *ngIf=\"statusPedido === 'cancelado'\" class=\"mt-6 text-center\">\n <a\n href=\"#\"\n class=\"text-sm text-blue-600 hover:text-blue-800 hover:underline\"\n >\n <i class=\"fas fa-question-circle mr-2\"></i>\n Precisa de ajuda? Entre em contato com o suporte\n </a>\n </div>\n </div>\n</div>\n", styles: [".empty-state-card{animation:fadeInUp .5s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.empty-state-icon{animation:bounceIn .6s ease-out}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}to{transform:scale(1)}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
304
353
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FallbackMessageComponent, decorators: [{
305
354
  type: Component,
306
355
  args: [{ selector: 'lib-fallback-message', template: "<div *ngIf=\"shouldShowEmptyState()\" class=\"empty-state-container\">\n <div\n class=\"empty-state-card max-w-md mx-auto bg-white shadow-xl rounded-3xl p-8 border border-gray-100\"\n >\n <!-- \u00CDcone din\u00E2mico -->\n <div class=\"empty-state-icon mb-6 flex justify-center\">\n <div class=\"relative w-32 h-32 flex items-center justify-center\">\n <div [class]=\"emptyStateConfig.iconColor\" class=\"z-10\">\n <div class=\"text-xl leading-none\" style=\"font-size: 4rem\">\n {{ emptyStateConfig.icon }}\n </div>\n </div>\n\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <div\n [class]=\"emptyStateConfig.bgColor\"\n class=\"w-full h-full rounded-full opacity-50 flex-shrink-0\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Conte\u00FAdo da mensagem -->\n <div class=\"empty-state-content text-center space-y-4\">\n <!-- T\u00EDtulo -->\n <h3 class=\"text-2xl font-bold text-gray-900 mb-2\">\n {{ emptyStateConfig.title }}\n </h3>\n\n <!-- Descri\u00E7\u00E3o -->\n <p class=\"text-gray-600 text-lg leading-relaxed px-4\">\n {{ emptyStateConfig.description }}\n </p>\n\n <!-- Informa\u00E7\u00F5es adicionais baseadas no status -->\n <div *ngIf=\"statusPedido === 'finalizado'\" class=\"mt-4\">\n <div\n class=\"inline-flex items-center gap-2 bg-green-50 text-green-700 px-4 py-2 rounded-full\"\n >\n <i class=\"fas fa-check-circle\"></i>\n <span class=\"font-medium\">Servi\u00E7o avaliado e finalizado</span>\n </div>\n </div>\n\n <div *ngIf=\"statusPedido === 'cancelado'\" class=\"mt-4\">\n <div\n class=\"inline-flex items-center gap-2 bg-red-50 text-red-700 px-4 py-2 rounded-full\"\n >\n <i class=\"fas fa-exclamation-circle\"></i>\n <span class=\"font-medium\">Cancelado pelo prestador do servi\u00E7o</span>\n </div>\n </div>\n </div>\n\n <!-- A\u00E7\u00F5es -->\n <div class=\"mt-8 flex flex-col sm:flex-row gap-4 justify-center\">\n <!-- A\u00E7\u00E3o Prim\u00E1ria -->\n <button\n *ngIf=\"hideBtn\"\n (click)=\"onPrimaryAction()\"\n [ngClass]=\"{\n 'bg-green-600 hover:bg-green-700': statusPedido === 'finalizado',\n 'bg-red-600 hover:bg-red-700': statusPedido === 'cancelado',\n 'bg-blue-600 ':\n statusPedido === 'indispon\u00EDvel' || statusPedido === 'indisponivel',\n 'bg-primary-600 hover:bg-primary-700': card.length === 0\n }\"\n class=\"col-12 btn btn-primary\"\n >\n {{ emptyStateConfig.primaryActionText }}\n </button>\n\n <!-- A\u00E7\u00E3o Secund\u00E1ria -->\n <button\n *ngIf=\"emptyStateConfig.secondaryActionText\"\n (click)=\"onSecondaryAction()\"\n class=\"col-12 btn btn-outline-primary\"\n >\n {{ emptyStateConfig.secondaryActionText }}\n </button>\n </div>\n\n <!-- Link de ajuda (opcional) -->\n <div *ngIf=\"statusPedido === 'cancelado'\" class=\"mt-6 text-center\">\n <a\n href=\"#\"\n class=\"text-sm text-blue-600 hover:text-blue-800 hover:underline\"\n >\n <i class=\"fas fa-question-circle mr-2\"></i>\n Precisa de ajuda? Entre em contato com o suporte\n </a>\n </div>\n </div>\n</div>\n", styles: [".empty-state-card{animation:fadeInUp .5s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.empty-state-icon{animation:bounceIn .6s ease-out}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}to{transform:scale(1)}}\n"] }]
@@ -324,17 +373,133 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
324
373
  type: Output
325
374
  }] } });
326
375
 
376
+ class NavComponent {
377
+ constructor(router, activatedRoute, el) {
378
+ this.router = router;
379
+ this.activatedRoute = activatedRoute;
380
+ this.el = el;
381
+ this.changeNavColor = false;
382
+ this.openClose = false;
383
+ this.message = '';
384
+ this.lastScrollPosition = 0;
385
+ this.isHeaderVisible = true;
386
+ this.headerHeight = 0;
387
+ this.isMobile = false;
388
+ this.hasOffer = false;
389
+ this.allowTransparency = false;
390
+ this.router.events
391
+ .pipe(filter((event) => event instanceof NavigationEnd), map(() => this.activatedRoute), map((route) => {
392
+ while (route.firstChild)
393
+ route = route.firstChild;
394
+ return route;
395
+ }), mergeMap((route) => route.data))
396
+ .subscribe((data) => {
397
+ this.allowTransparency = !!data['transparentNav'];
398
+ this.lastScrollPosition = 0;
399
+ this.isHeaderVisible = true; // força aparecer no load
400
+ this.changeNavColor = !this.allowTransparency;
401
+ });
402
+ }
403
+ ngAfterViewInit() {
404
+ this.checkMobile();
405
+ // Obtém a altura do header-menu após a view ser inicializada
406
+ const headerMenu = this.el.nativeElement.querySelector('[header-menu]');
407
+ if (headerMenu) {
408
+ this.headerHeight = headerMenu.offsetHeight;
409
+ }
410
+ }
411
+ ngOnInit() {
412
+ this.hasOffer = this.router.url.includes('offer');
413
+ }
414
+ onResize() {
415
+ this.checkMobile();
416
+ }
417
+ checkMobile() {
418
+ this.isMobile = window.innerWidth < 768; // 768px é o breakpoint padrão do Tailwind para md
419
+ if (!this.isMobile) {
420
+ this.isHeaderVisible = true; // Garante que fique visível em desktop
421
+ }
422
+ }
423
+ menu() {
424
+ this.openClose = !this.openClose;
425
+ }
426
+ receiveMessage(event) {
427
+ this.message = event;
428
+ }
429
+ onWindowScroll() {
430
+ const scroll = window.pageYOffset || document.documentElement.scrollTop;
431
+ const isScrollingDown = scroll > this.lastScrollPosition;
432
+ /* =========================
433
+ * VISIBILIDADE
434
+ * ========================= */
435
+ if (scroll <= 10) {
436
+ // TOPO
437
+ this.isHeaderVisible = !isScrollingDown;
438
+ }
439
+ else if (isScrollingDown && scroll > 50) {
440
+ // SCROLL DOWN
441
+ this.isHeaderVisible = false;
442
+ }
443
+ else {
444
+ // SCROLL UP
445
+ this.isHeaderVisible = true;
446
+ }
447
+ /* =========================
448
+ * COR
449
+ * ========================= */
450
+ if (!this.allowTransparency) {
451
+ this.changeNavColor = true;
452
+ }
453
+ else {
454
+ this.changeNavColor = scroll > 20;
455
+ }
456
+ this.lastScrollPosition = scroll;
457
+ }
458
+ }
459
+ NavComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
460
+ NavComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NavComponent, selector: "lib-nav", host: { listeners: { "window:resize": "onResize()", "window:scroll": "onWindowScroll()" } }, ngImport: i0, template: "<!-- Overlay -->\n<div\n *ngIf=\"openClose\"\n (click)=\"openClose = false\"\n class=\"fixed inset-0 bg-black bg-opacity-40 z-40 md:hidden\"\n></div>\n\n<div\n class=\"fixed top-0 left-0 right-0 z-50 shadow-none transition-all duration-500 w-full\"\n [class.-translate-y-full]=\"!isHeaderVisible\"\n [style.background-color]=\"changeNavColor ? 'var(--primary)' : 'transparent'\"\n>\n <div class=\"w-full\">\n <div class=\"mx-auto px-2 h-16 flex items-center justify-between\">\n <!-- Left Content -->\n <div class=\"flex-1 flex justify-start\">\n <ng-content select=\"[left-content]\"></ng-content>\n </div>\n\n <!-- Center Content -->\n <div class=\"flex-1 flex justify-center\">\n <ng-content select=\"[central-content]\"></ng-content>\n </div>\n\n <!-- Right Content -->\n <div class=\"flex-1\" style=\"display: flex; justify-content: flex-end\">\n <ng-content select=\"[right-content]\"></ng-content>\n </div>\n </div>\n </div>\n\n <!-- Header Menu (Submenu) -->\n <div header-menu class=\"w-full\">\n <ng-content select=\"[header-menu]\"></ng-content>\n </div>\n</div>\n", styles: [".navbar-ajust{background-color:var(--medium);padding:1em}.container-fluid{display:flex;justify-content:space-between;align-items:center}.navbar-left,.navbar-right{flex:1;display:flex;justify-content:flex-start}.navbar-right{justify-content:flex-end}.navbar-center{flex:2;display:flex;justify-content:center}:host{display:block}.-translate-y-full{transform:translateY(calc(-100% - 1px))}.nav-transparent{background-color:var(--premium)!important}.nav-scrolled{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}@media (max-width: 767px){.-translate-y-full{transform:translateY(calc(-100% - 1px))}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
461
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavComponent, decorators: [{
462
+ type: Component,
463
+ args: [{ selector: 'lib-nav', template: "<!-- Overlay -->\n<div\n *ngIf=\"openClose\"\n (click)=\"openClose = false\"\n class=\"fixed inset-0 bg-black bg-opacity-40 z-40 md:hidden\"\n></div>\n\n<div\n class=\"fixed top-0 left-0 right-0 z-50 shadow-none transition-all duration-500 w-full\"\n [class.-translate-y-full]=\"!isHeaderVisible\"\n [style.background-color]=\"changeNavColor ? 'var(--primary)' : 'transparent'\"\n>\n <div class=\"w-full\">\n <div class=\"mx-auto px-2 h-16 flex items-center justify-between\">\n <!-- Left Content -->\n <div class=\"flex-1 flex justify-start\">\n <ng-content select=\"[left-content]\"></ng-content>\n </div>\n\n <!-- Center Content -->\n <div class=\"flex-1 flex justify-center\">\n <ng-content select=\"[central-content]\"></ng-content>\n </div>\n\n <!-- Right Content -->\n <div class=\"flex-1\" style=\"display: flex; justify-content: flex-end\">\n <ng-content select=\"[right-content]\"></ng-content>\n </div>\n </div>\n </div>\n\n <!-- Header Menu (Submenu) -->\n <div header-menu class=\"w-full\">\n <ng-content select=\"[header-menu]\"></ng-content>\n </div>\n</div>\n", styles: [".navbar-ajust{background-color:var(--medium);padding:1em}.container-fluid{display:flex;justify-content:space-between;align-items:center}.navbar-left,.navbar-right{flex:1;display:flex;justify-content:flex-start}.navbar-right{justify-content:flex-end}.navbar-center{flex:2;display:flex;justify-content:center}:host{display:block}.-translate-y-full{transform:translateY(calc(-100% - 1px))}.nav-transparent{background-color:var(--premium)!important}.nav-scrolled{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}@media (max-width: 767px){.-translate-y-full{transform:translateY(calc(-100% - 1px))}}\n"] }]
464
+ }], ctorParameters: function () { return [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i0.ElementRef }]; }, propDecorators: { onResize: [{
465
+ type: HostListener,
466
+ args: ['window:resize']
467
+ }], onWindowScroll: [{
468
+ type: HostListener,
469
+ args: ['window:scroll', []]
470
+ }] } });
471
+
327
472
  class TuduComponentsModule {
328
473
  }
329
474
  TuduComponentsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
330
- TuduComponentsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, declarations: [TuduComponentsComponent, CardLayoutComponent, NavComponent, FallbackMessageComponent], imports: [CommonModule], exports: [TuduComponentsComponent, CardLayoutComponent, NavComponent, FallbackMessageComponent] });
475
+ TuduComponentsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, declarations: [TuduComponentsComponent,
476
+ CardLayoutComponent,
477
+ NavComponent,
478
+ FallbackMessageComponent,
479
+ CustomModalComponent], imports: [CommonModule], exports: [TuduComponentsComponent,
480
+ CardLayoutComponent,
481
+ NavComponent,
482
+ FallbackMessageComponent,
483
+ CustomModalComponent] });
331
484
  TuduComponentsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, imports: [CommonModule] });
332
485
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, decorators: [{
333
486
  type: NgModule,
334
487
  args: [{
335
- declarations: [TuduComponentsComponent, CardLayoutComponent, NavComponent, FallbackMessageComponent],
488
+ declarations: [
489
+ TuduComponentsComponent,
490
+ CardLayoutComponent,
491
+ NavComponent,
492
+ FallbackMessageComponent,
493
+ CustomModalComponent,
494
+ ],
336
495
  imports: [CommonModule],
337
- exports: [TuduComponentsComponent, CardLayoutComponent, NavComponent, FallbackMessageComponent],
496
+ exports: [
497
+ TuduComponentsComponent,
498
+ CardLayoutComponent,
499
+ NavComponent,
500
+ FallbackMessageComponent,
501
+ CustomModalComponent,
502
+ ],
338
503
  }]
339
504
  }] });
340
505
 
@@ -359,5 +524,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
359
524
  * Generated bundle index. Do not edit.
360
525
  */
361
526
 
362
- export { CardLayoutComponent, FallbackMessageComponent, NavComponent, TuduComponentsComponent, TuduComponentsModule, TuduComponentsService };
527
+ export { CardLayoutComponent, CustomModalComponent, FallbackMessageComponent, NavComponent, TuduComponentsComponent, TuduComponentsModule, TuduComponentsService };
363
528
  //# sourceMappingURL=tudu-components.mjs.map