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';
@@ -87,7 +87,7 @@ class CardLayoutComponent {
87
87
  }
88
88
  }
89
89
  CardLayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CardLayoutComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
90
- 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"] }] });
90
+ 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"] }] });
91
91
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CardLayoutComponent, decorators: [{
92
92
  type: Component,
93
93
  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"] }]
@@ -99,100 +99,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
99
99
  type: Input
100
100
  }] } });
101
101
 
102
- class NavComponent {
103
- constructor(router, activatedRoute, el) {
104
- this.router = router;
105
- this.activatedRoute = activatedRoute;
106
- this.el = el;
107
- this.changeNavColor = false;
108
- this.openClose = false;
102
+ class CustomModalComponent {
103
+ constructor(location) {
104
+ this.location = location;
105
+ this.modalId = 'customModal';
106
+ this.title = 'Aviso';
109
107
  this.message = '';
110
- this.lastScrollPosition = 0;
111
- this.isHeaderVisible = true;
112
- this.headerHeight = 0;
113
- this.isMobile = false;
114
- this.hasOffer = false;
115
- this.allowTransparency = false;
116
- this.router.events
117
- .pipe(filter((event) => event instanceof NavigationEnd), map(() => this.activatedRoute), map((route) => {
118
- while (route.firstChild)
119
- route = route.firstChild;
120
- return route;
121
- }), mergeMap((route) => route.data))
122
- .subscribe((data) => {
123
- this.allowTransparency = !!data['transparentNav'];
124
- this.lastScrollPosition = 0;
125
- this.isHeaderVisible = true; // força aparecer no load
126
- this.changeNavColor = !this.allowTransparency;
127
- });
128
- }
129
- ngAfterViewInit() {
130
- this.checkMobile();
131
- // Obtém a altura do header-menu após a view ser inicializada
132
- const headerMenu = this.el.nativeElement.querySelector('[header-menu]');
133
- if (headerMenu) {
134
- this.headerHeight = headerMenu.offsetHeight;
135
- }
108
+ this.closeButtonText = 'Fechar';
109
+ this.actionButtonText = '';
110
+ this.paymentMethod = null;
111
+ this.errorDetails = null;
112
+ this.modalClosed = new EventEmitter();
113
+ this.modalAction = new EventEmitter();
114
+ this.showModal = false;
115
+ this.messageTitle = 'Pagamento Aprovado!';
116
+ this.showBtn = true;
117
+ this.priceNegotiated = 0;
118
+ this.messageBody = 'Seu pagamento foi processado com sucesso.';
119
+ // Configuração dinâmica
120
+ this.modalIcon = 'fa-check';
121
+ this.modalIconColor = 'text-green-600';
122
+ this.modalBgColor = 'bg-green-100';
123
+ this.isClosing = false;
136
124
  }
137
- ngOnInit() {
138
- this.hasOffer = this.router.url.includes('offer');
125
+ ngOnInit() { }
126
+ // Centraliza a abertura do modal com suporte ao botão voltar
127
+ openModal() {
128
+ this.showModal = true;
129
+ // Adiciona um estado no histórico para o botão voltar funcionar
130
+ this.location.go(this.location.path() + '#modalOpen');
139
131
  }
140
- onResize() {
141
- this.checkMobile();
132
+ // Atalho para abrir com tipos específicos
133
+ open(type, message = '', paymentMethod) {
134
+ this.configureModal(type, message);
135
+ if (paymentMethod) {
136
+ this.paymentMethod = paymentMethod;
137
+ }
138
+ this.openModal();
142
139
  }
143
- checkMobile() {
144
- this.isMobile = window.innerWidth < 768; // 768px é o breakpoint padrão do Tailwind para md
145
- if (!this.isMobile) {
146
- this.isHeaderVisible = true; // Garante que fique visível em desktop
140
+ configureModal(type, message = '') {
141
+ switch (type) {
142
+ case 'success':
143
+ this.setSuccessStyles(message);
144
+ break;
145
+ case 'error':
146
+ this.setErrorStyles(message);
147
+ break;
148
+ case 'warning':
149
+ this.setWarningStyles(message);
150
+ break;
147
151
  }
148
152
  }
149
- menu() {
150
- this.openClose = !this.openClose;
153
+ setSuccessStyles(message) {
154
+ this.modalIcon = 'fa-check-circle';
155
+ this.modalIconColor = 'modal-icon-success';
156
+ this.modalBgColor = 'modal-bg-success';
157
+ this.messageTitle = 'Sucesso!';
158
+ this.messageBody = message || 'Operação realizada com sucesso.';
151
159
  }
152
- receiveMessage(event) {
153
- this.message = event;
160
+ setErrorStyles(message) {
161
+ this.modalIcon = 'fa-times-circle';
162
+ this.modalIconColor = 'modal-icon-error';
163
+ this.modalBgColor = 'modal-bg-error';
164
+ this.messageTitle = 'Ops! Algo deu errado';
165
+ this.messageBody = message || 'Não conseguimos processar sua solicitação.';
154
166
  }
155
- onWindowScroll() {
156
- const scroll = window.pageYOffset || document.documentElement.scrollTop;
157
- const isScrollingDown = scroll > this.lastScrollPosition;
158
- /* =========================
159
- * VISIBILIDADE
160
- * ========================= */
161
- if (scroll <= 10) {
162
- // TOPO
163
- this.isHeaderVisible = !isScrollingDown;
164
- }
165
- else if (isScrollingDown && scroll > 50) {
166
- // SCROLL DOWN
167
- this.isHeaderVisible = false;
167
+ setWarningStyles(message) {
168
+ this.modalIcon = 'fa-exclamation-circle';
169
+ this.modalIconColor = 'modal-icon-warning';
170
+ this.modalBgColor = 'modal-bg-warning';
171
+ this.messageTitle = 'Atenção';
172
+ this.messageBody = message || 'Verifique os dados antes de continuar.';
173
+ }
174
+ actionModal() {
175
+ if (this.isLoadingBtn !== undefined) {
176
+ this.isLoadingBtn = true;
177
+ this.modalAction.emit();
168
178
  }
169
179
  else {
170
- // SCROLL UP
171
- this.isHeaderVisible = true;
172
- }
173
- /* =========================
174
- * COR
175
- * ========================= */
176
- if (!this.allowTransparency) {
177
- this.changeNavColor = true;
180
+ this.modalAction.emit();
181
+ this.isLoadingBtn = false;
182
+ this.closeModal(); // Usa o método de fechar para limpar o histórico
178
183
  }
179
- else {
180
- this.changeNavColor = scroll > 20;
184
+ }
185
+ closeModal() {
186
+ this.isClosing = true; // Ativa a animação de descida
187
+ // Aguarda o tempo da animação (300ms) antes de remover do DOM
188
+ setTimeout(() => {
189
+ this.showModal = false;
190
+ this.isClosing = false; // Reseta para a próxima abertura
191
+ this.modalClosed.emit();
192
+ // Lógica do histórico que já fizemos
193
+ if (window.location.hash === '#modalOpen') {
194
+ const currentPath = this.location.path().split('#')[0];
195
+ this.location.replaceState(currentPath);
196
+ }
197
+ }, 300);
198
+ }
199
+ // Escuta o botão voltar do navegador ou celular
200
+ onPopState() {
201
+ if (this.showModal) {
202
+ this.showModal = false;
203
+ this.modalClosed.emit();
181
204
  }
182
- this.lastScrollPosition = scroll;
183
205
  }
184
206
  }
185
- 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 });
186
- 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"] }] });
187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavComponent, decorators: [{
207
+ 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 });
208
+ 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" }] });
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomModalComponent, decorators: [{
188
210
  type: Component,
189
- 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"] }]
190
- }], ctorParameters: function () { return [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i0.ElementRef }]; }, propDecorators: { onResize: [{
191
- type: HostListener,
192
- args: ['window:resize']
193
- }], onWindowScroll: [{
211
+ 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"] }]
212
+ }], ctorParameters: function () { return [{ type: i1$1.Location }]; }, propDecorators: { modalId: [{
213
+ type: Input
214
+ }], title: [{
215
+ type: Input
216
+ }], message: [{
217
+ type: Input
218
+ }], closeButtonText: [{
219
+ type: Input
220
+ }], actionButtonText: [{
221
+ type: Input
222
+ }], paymentMethod: [{
223
+ type: Input
224
+ }], errorDetails: [{
225
+ type: Input
226
+ }], modalClosed: [{
227
+ type: Output
228
+ }], modalAction: [{
229
+ type: Output
230
+ }], showModal: [{
231
+ type: Input
232
+ }], messageTitle: [{
233
+ type: Input
234
+ }], showBtn: [{
235
+ type: Input
236
+ }], priceNegotiated: [{
237
+ type: Input
238
+ }], messageBody: [{
239
+ type: Input
240
+ }], isLoadingBtn: [{
241
+ type: Input
242
+ }], onPopState: [{
194
243
  type: HostListener,
195
- args: ['window:scroll', []]
244
+ args: ['window:popstate']
196
245
  }] } });
197
246
 
198
247
  class FallbackMessageComponent {
@@ -298,7 +347,7 @@ class FallbackMessageComponent {
298
347
  }
299
348
  }
300
349
  FallbackMessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FallbackMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
301
- 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"] }] });
350
+ 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"] }] });
302
351
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FallbackMessageComponent, decorators: [{
303
352
  type: Component,
304
353
  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"] }]
@@ -322,17 +371,133 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
322
371
  type: Output
323
372
  }] } });
324
373
 
374
+ class NavComponent {
375
+ constructor(router, activatedRoute, el) {
376
+ this.router = router;
377
+ this.activatedRoute = activatedRoute;
378
+ this.el = el;
379
+ this.changeNavColor = false;
380
+ this.openClose = false;
381
+ this.message = '';
382
+ this.lastScrollPosition = 0;
383
+ this.isHeaderVisible = true;
384
+ this.headerHeight = 0;
385
+ this.isMobile = false;
386
+ this.hasOffer = false;
387
+ this.allowTransparency = false;
388
+ this.router.events
389
+ .pipe(filter((event) => event instanceof NavigationEnd), map(() => this.activatedRoute), map((route) => {
390
+ while (route.firstChild)
391
+ route = route.firstChild;
392
+ return route;
393
+ }), mergeMap((route) => route.data))
394
+ .subscribe((data) => {
395
+ this.allowTransparency = !!data['transparentNav'];
396
+ this.lastScrollPosition = 0;
397
+ this.isHeaderVisible = true; // força aparecer no load
398
+ this.changeNavColor = !this.allowTransparency;
399
+ });
400
+ }
401
+ ngAfterViewInit() {
402
+ this.checkMobile();
403
+ // Obtém a altura do header-menu após a view ser inicializada
404
+ const headerMenu = this.el.nativeElement.querySelector('[header-menu]');
405
+ if (headerMenu) {
406
+ this.headerHeight = headerMenu.offsetHeight;
407
+ }
408
+ }
409
+ ngOnInit() {
410
+ this.hasOffer = this.router.url.includes('offer');
411
+ }
412
+ onResize() {
413
+ this.checkMobile();
414
+ }
415
+ checkMobile() {
416
+ this.isMobile = window.innerWidth < 768; // 768px é o breakpoint padrão do Tailwind para md
417
+ if (!this.isMobile) {
418
+ this.isHeaderVisible = true; // Garante que fique visível em desktop
419
+ }
420
+ }
421
+ menu() {
422
+ this.openClose = !this.openClose;
423
+ }
424
+ receiveMessage(event) {
425
+ this.message = event;
426
+ }
427
+ onWindowScroll() {
428
+ const scroll = window.pageYOffset || document.documentElement.scrollTop;
429
+ const isScrollingDown = scroll > this.lastScrollPosition;
430
+ /* =========================
431
+ * VISIBILIDADE
432
+ * ========================= */
433
+ if (scroll <= 10) {
434
+ // TOPO
435
+ this.isHeaderVisible = !isScrollingDown;
436
+ }
437
+ else if (isScrollingDown && scroll > 50) {
438
+ // SCROLL DOWN
439
+ this.isHeaderVisible = false;
440
+ }
441
+ else {
442
+ // SCROLL UP
443
+ this.isHeaderVisible = true;
444
+ }
445
+ /* =========================
446
+ * COR
447
+ * ========================= */
448
+ if (!this.allowTransparency) {
449
+ this.changeNavColor = true;
450
+ }
451
+ else {
452
+ this.changeNavColor = scroll > 20;
453
+ }
454
+ this.lastScrollPosition = scroll;
455
+ }
456
+ }
457
+ 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 });
458
+ 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"] }] });
459
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavComponent, decorators: [{
460
+ type: Component,
461
+ 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"] }]
462
+ }], ctorParameters: function () { return [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i0.ElementRef }]; }, propDecorators: { onResize: [{
463
+ type: HostListener,
464
+ args: ['window:resize']
465
+ }], onWindowScroll: [{
466
+ type: HostListener,
467
+ args: ['window:scroll', []]
468
+ }] } });
469
+
325
470
  class TuduComponentsModule {
326
471
  }
327
472
  TuduComponentsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
328
- 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] });
473
+ TuduComponentsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, declarations: [TuduComponentsComponent,
474
+ CardLayoutComponent,
475
+ NavComponent,
476
+ FallbackMessageComponent,
477
+ CustomModalComponent], imports: [CommonModule], exports: [TuduComponentsComponent,
478
+ CardLayoutComponent,
479
+ NavComponent,
480
+ FallbackMessageComponent,
481
+ CustomModalComponent] });
329
482
  TuduComponentsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, imports: [CommonModule] });
330
483
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TuduComponentsModule, decorators: [{
331
484
  type: NgModule,
332
485
  args: [{
333
- declarations: [TuduComponentsComponent, CardLayoutComponent, NavComponent, FallbackMessageComponent],
486
+ declarations: [
487
+ TuduComponentsComponent,
488
+ CardLayoutComponent,
489
+ NavComponent,
490
+ FallbackMessageComponent,
491
+ CustomModalComponent,
492
+ ],
334
493
  imports: [CommonModule],
335
- exports: [TuduComponentsComponent, CardLayoutComponent, NavComponent, FallbackMessageComponent],
494
+ exports: [
495
+ TuduComponentsComponent,
496
+ CardLayoutComponent,
497
+ NavComponent,
498
+ FallbackMessageComponent,
499
+ CustomModalComponent,
500
+ ],
336
501
  }]
337
502
  }] });
338
503
 
@@ -357,5 +522,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
357
522
  * Generated bundle index. Do not edit.
358
523
  */
359
524
 
360
- export { CardLayoutComponent, FallbackMessageComponent, NavComponent, TuduComponentsComponent, TuduComponentsModule, TuduComponentsService };
525
+ export { CardLayoutComponent, CustomModalComponent, FallbackMessageComponent, NavComponent, TuduComponentsComponent, TuduComponentsModule, TuduComponentsService };
361
526
  //# sourceMappingURL=tudu-components.mjs.map