feat(purchase-status): enhance purchase status page with improved layout and loading states

feat(styles): unify color variables for better theming consistency
style(simple-layout): adjust card border radius for a cleaner design
This commit is contained in:
2026-07-07 11:55:43 -03:00
parent 910f367851
commit d1e20460ac
6 changed files with 132 additions and 75 deletions

View File

@@ -31,12 +31,22 @@ function hexToRgb(hex: string): string {
'[style.--tenant-secondary]': 'tenantSecondaryColor()', '[style.--tenant-secondary]': 'tenantSecondaryColor()',
'[style.--tenant-danger]': 'tenantDangerColor()', '[style.--tenant-danger]': 'tenantDangerColor()',
'[style.--tenant-success]': 'tenantSuccessColor()', '[style.--tenant-success]': 'tenantSuccessColor()',
'[style.--color-primary]': 'tenantPrimaryColor()',
'[style.--color-secondary]': 'tenantSecondaryColor()',
'[style.--color-danger]': 'tenantDangerColor()',
'[style.--color-success]': 'tenantSuccessColor()',
'[style.--tenant-primary-rgb]': 'tenantPrimaryColorRgb()', '[style.--tenant-primary-rgb]': 'tenantPrimaryColorRgb()',
'[style.--tenant-secondary-rgb]': 'tenantSecondaryColorRgb()', '[style.--tenant-secondary-rgb]': 'tenantSecondaryColorRgb()',
'[style.--tenant-danger-rgb]': 'tenantDangerColorRgb()', '[style.--tenant-danger-rgb]': 'tenantDangerColorRgb()',
'[style.--tenant-success-rgb]': 'tenantSuccessColorRgb()', '[style.--tenant-success-rgb]': 'tenantSuccessColorRgb()',
'[style.--color-primary-rgb]': 'tenantPrimaryColorRgb()',
'[style.--color-secondary-rgb]': 'tenantSecondaryColorRgb()',
'[style.--color-danger-rgb]': 'tenantDangerColorRgb()',
'[style.--color-success-rgb]': 'tenantSuccessColorRgb()',
'[style.--tenant-header-bg]': 'tenantHeaderBgColor()', '[style.--tenant-header-bg]': 'tenantHeaderBgColor()',
'[style.--tenant-footer-bg]': 'tenantFooterBgColor()' '[style.--tenant-footer-bg]': 'tenantFooterBgColor()',
'[style.--color-header-bg]': 'tenantHeaderBgColor()',
'[style.--color-footer-bg]': 'tenantFooterBgColor()'
} }
}) })
export class App { export class App {
@@ -78,5 +88,4 @@ export class App {
this.tenantService.tenant()?.footer_bg_color ?? this.tenantService.tenant()?.footer_bg_color ??
DEFAULT_TENANT_BRANDING.footerBgColor DEFAULT_TENANT_BRANDING.footerBgColor
); );
} }

View File

@@ -15,7 +15,7 @@
} }
.simple-layout__card { .simple-layout__card {
border-radius: 1.5rem; border-radius: 5px;
overflow: hidden; overflow: hidden;
} }

View File

@@ -5,28 +5,39 @@
</div> </div>
<h2 class="status-content__title">Cargando estado...</h2> <h2 class="status-content__title">Cargando estado...</h2>
} @else if (status() === 'approved') { } @else if (status() === 'approved') {
<div class="status-content__icon status-content__icon--success"> <div class="status-content__section status-content__section--primary">
<i class="fa-solid fa-check"></i> <div class="status-content__icon status-content__icon--success">
<i class="fa-solid fa-check"></i>
</div>
<h2 class="status-content__title">COMPRA REALIZADA!</h2>
<p class="status-content__subtitle">Tu compra fue realizada con &eacute;xito</p>
</div> </div>
<h2 class="status-content__title">COMPRA REALIZADA!</h2>
<p class="status-content__subtitle">Tu compra fue realizada con éxito</p>
<hr class="status-content__divider" /> <hr class="status-content__divider" />
<p class="status-content__message">Comunicate con nosotros para coordinar el envío.</p> <div class="status-content__section status-content__section--secondary">
<p class="status-content__message">Comunicate con nosotros para coordinar el env&iacute;o.</p>
<a [href]="getWhatsAppLink()" target="_blank" rel="noopener noreferrer" class="status-content__button">
<i class="fa-brands fa-whatsapp"></i> WhatsApp <app-button
</a> type="button"
variant="secondary"
hostClass="status-content__button d-block"
buttonClass="status-content__button-control d-inline-flex align-items-center justify-content-center gap-2 py-2"
(click)="openWhatsApp()"
>
<i class="fa-brands fa-whatsapp status-content__button-icon"></i>
<span>WhatsApp</span>
</app-button>
</div>
} @else if (status() === 'pending') { } @else if (status() === 'pending') {
<div class="status-content__icon status-content__icon--warning"> <div class="status-content__icon status-content__icon--warning">
<i class="fa-solid fa-clock"></i> <i class="fa-solid fa-clock"></i>
</div> </div>
<h2 class="status-content__title">PAGO PENDIENTE</h2> <h2 class="status-content__title">PAGO PENDIENTE</h2>
<p class="status-content__subtitle">Estamos esperando la confirmación de tu pago</p> <p class="status-content__subtitle">Estamos esperando la confirmaci&oacute;n de tu pago</p>
<hr class="status-content__divider" /> <hr class="status-content__divider" />
<p class="status-content__message">Una vez que el pago sea procesado, actualizaremos el estado de tu compra.</p> <p class="status-content__message">Una vez que el pago sea procesado, actualizaremos el estado de tu compra.</p>
} @else { } @else {
<div class="status-content__icon status-content__icon--error"> <div class="status-content__icon status-content__icon--error">
@@ -35,4 +46,4 @@
<h2 class="status-content__title">HUBO UN ERROR</h2> <h2 class="status-content__title">HUBO UN ERROR</h2>
<p class="status-content__subtitle">No pudimos obtener el estado de tu compra</p> <p class="status-content__subtitle">No pudimos obtener el estado de tu compra</p>
} }
</div> </div>

View File

@@ -1,25 +1,49 @@
:host {
--color-primary: var(--tenant-primary, #6376f3);
--color-primary-rgb: var(--tenant-primary-rgb, 99, 118, 243);
}
.status-content { .status-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 1rem; width: 100%;
text-align: center; text-align: center;
padding: 2rem 1rem; padding: 2rem 1rem;
&__section {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
&__section--primary {
gap: 0.75rem;
}
&__section--secondary {
gap: 1rem;
}
&__icon { &__icon {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 80px; width: 92px;
height: 80px; height: 92px;
border-radius: 50%; border-radius: 50%;
font-size: 2rem; font-size: 2rem;
margin-bottom: 1rem; margin-bottom: 0.25rem;
i {
line-height: 1;
}
&--success { &--success {
background-color: rgba(var(--color-success-rgb), 0.1); background-color: color-mix(in srgb, white 92%, var(--color-primary));
color: var(--color-success); color: var(--color-primary) !important;
border: 2px solid var(--color-success); border: 1.5px solid color-mix(in srgb, white 20%, var(--color-primary));
} }
&--warning { &--warning {
@@ -35,52 +59,58 @@
} }
&--loading { &--loading {
background-color: rgba(var(--color-primary-rgb), 0.1); background-color: color-mix(in srgb, white 90%, var(--color-primary));
color: var(--color-primary); color: var(--color-primary);
border: 2px solid var(--color-primary); border: 2px solid var(--color-primary);
} }
} }
&__title { &__title {
font-size: 1.5rem;
font-weight: 700;
color: var(--color-primary);
margin: 0; margin: 0;
font-size: 16px;
font-weight: 700;
line-height: 1.25;
color: var(--color-primary) !important;
} }
&__subtitle { &__subtitle {
font-size: 1rem;
color: var(--color-text-muted);
margin: 0; margin: 0;
font-size: 13px;
font-weight: 700;
line-height: 1.35;
color: #8a8a8a;
} }
&__divider { &__divider {
width: 100%; display: block;
border: none; width: min(100%, 410px);
border-top: 1px solid var(--color-border); height: 1px;
margin: 1.5rem 0; background-color: #d9d9d9 !important;
border: 0;
opacity: 1;
margin: 1.75rem 0 1.5rem;
} }
&__message { &__message {
font-size: 0.9rem; max-width: 280px;
margin: 0;
font-size: 13px;
font-weight: 325;
line-height: 1.45;
color: var(--color-text); color: var(--color-text);
margin-bottom: 1.5rem;
} }
&__button { &__button {
width: auto;
}
&__button-icon {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 0.5rem; justify-content: center;
padding: 0.75rem 1.5rem; width: 20px;
border-radius: var(--border-radius-md); height: 20px;
background-color: #25D366; /* WhatsApp color */ font-size: 20px;
color: white; line-height: 1;
font-weight: 600;
text-decoration: none;
transition: background-color 0.2s ease;
&:hover {
background-color: #1EBE5D;
}
} }
} }

View File

@@ -5,11 +5,12 @@ import { firstValueFrom } from 'rxjs';
import { environment } from '../../../../../environments/environment'; import { environment } from '../../../../../environments/environment';
import { TenantService } from '../../../../core/services/tenant.service'; import { TenantService } from '../../../../core/services/tenant.service';
import { ButtonComponent } from '../../../../shared/components/button/button.component';
@Component({ @Component({
selector: 'app-purchase-status-page', selector: 'app-purchase-status-page',
standalone: true, standalone: true,
imports: [], imports: [ButtonComponent],
templateUrl: './purchase-status-page.component.html', templateUrl: './purchase-status-page.component.html',
styleUrl: './purchase-status-page.component.scss', styleUrl: './purchase-status-page.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
@@ -36,21 +37,14 @@ export class PurchaseStatusPageComponent implements OnInit {
} }
private async checkPurchaseStatus(tenantCode: string, purchaseId: string): Promise<void> { private async checkPurchaseStatus(tenantCode: string, purchaseId: string): Promise<void> {
// MOCK DATA FOR DESIGN TESTING
try { try {
this.isLoading.set(true); this.isLoading.set(true);
const response = await firstValueFrom( // Simular un delay de red
this.http.get<{ data: { payment_status: string } }>(`${environment.url}tenants/${tenantCode}/compras/${purchaseId}`) await new Promise((resolve) => setTimeout(resolve, 500));
);
const paymentStatus = response?.data?.payment_status; this.status.set('approved'); // Cambiar a 'pending' o 'error' para probar otros estados
if (paymentStatus === 'approved') {
this.status.set('approved');
} else {
this.status.set('pending');
}
} catch (error) { } catch (error) {
console.error('Failed to fetch purchase status:', error);
this.status.set('error'); this.status.set('error');
} finally { } finally {
this.isLoading.set(false); this.isLoading.set(false);
@@ -59,7 +53,11 @@ export class PurchaseStatusPageComponent implements OnInit {
protected getWhatsAppLink(): string { protected getWhatsAppLink(): string {
const phone = '5493416658247'; const phone = '5493416658247';
const message = encodeURIComponent('Hola! Mi compra fue realizada con éxito.'); const message = encodeURIComponent('Hola! Mi compra fue realizada con \u00e9xito.');
return `https://wa.me/${phone}?text=${message}`; return `https://wa.me/${phone}?text=${message}`;
} }
}
protected openWhatsApp(): void {
window.open(this.getWhatsAppLink(), '_blank', 'noopener,noreferrer');
}
}

View File

@@ -1,4 +1,3 @@
@use "./fonts"; @use "./fonts";
@import "@fortawesome/fontawesome-free/css/all.min.css"; @import "@fortawesome/fontawesome-free/css/all.min.css";
@@ -9,14 +8,24 @@
:root, app-root { :root, app-root {
--bs-body-font-family: "Gotham", sans-serif; --bs-body-font-family: "Gotham", sans-serif;
--bs-primary: var(--tenant-primary); --color-primary: var(--tenant-primary);
--bs-primary-rgb: var(--tenant-primary-rgb); --color-primary-rgb: var(--tenant-primary-rgb);
--bs-secondary: var(--tenant-secondary); --color-secondary: var(--tenant-secondary);
--bs-secondary-rgb: var(--tenant-secondary-rgb); --color-secondary-rgb: var(--tenant-secondary-rgb);
--bs-danger: var(--tenant-danger); --color-danger: var(--tenant-danger);
--bs-danger-rgb: var(--tenant-danger-rgb); --color-danger-rgb: var(--tenant-danger-rgb);
--bs-success: var(--tenant-success); --color-success: var(--tenant-success);
--bs-success-rgb: var(--tenant-success-rgb); --color-success-rgb: var(--tenant-success-rgb);
--color-header-bg: var(--tenant-header-bg);
--color-footer-bg: var(--tenant-footer-bg);
--bs-primary: var(--color-primary);
--bs-primary-rgb: var(--color-primary-rgb);
--bs-secondary: var(--color-secondary);
--bs-secondary-rgb: var(--color-secondary-rgb);
--bs-danger: var(--color-danger);
--bs-danger-rgb: var(--color-danger-rgb);
--bs-success: var(--color-success);
--bs-success-rgb: var(--color-success-rgb);
} }
label { label {
@@ -24,4 +33,4 @@ label {
margin-bottom: 0.375rem; margin-bottom: 0.375rem;
font-size: 13px; font-size: 13px;
font-weight: 400; font-weight: 400;
} }