diff --git a/src/app/core/layout/store-layout/store-footer/store-footer.component.html b/src/app/core/layout/store-layout/store-footer/store-footer.component.html
index 642eb62..ef60575 100644
--- a/src/app/core/layout/store-layout/store-footer/store-footer.component.html
+++ b/src/app/core/layout/store-layout/store-footer/store-footer.component.html
@@ -5,12 +5,19 @@
diff --git a/src/app/core/layout/store-layout/store-footer/store-footer.component.scss b/src/app/core/layout/store-layout/store-footer/store-footer.component.scss
index 9dbd2c8..6eea43d 100644
--- a/src/app/core/layout/store-layout/store-footer/store-footer.component.scss
+++ b/src/app/core/layout/store-layout/store-footer/store-footer.component.scss
@@ -6,6 +6,42 @@
min-width: 10rem;
}
+.store-layout__brand-logo-shell {
+ position: relative;
+ width: min(100%, 12rem);
+ height: 2.75rem;
+}
+
+.store-layout__brand-logo {
+ display: block;
+ width: 100%;
+ height: 100%;
+ max-height: 2.75rem;
+ object-fit: contain;
+}
+
+.store-layout__brand-logo--preload {
+ opacity: 0;
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+}
+
+.store-layout__brand-logo-skeleton {
+ display: block;
+ width: 100%;
+ height: 100%;
+ border-radius: 0.75rem;
+ background: linear-gradient(
+ 90deg,
+ rgba(255, 255, 255, 0.12) 0%,
+ rgba(255, 255, 255, 0.24) 50%,
+ rgba(255, 255, 255, 0.12) 100%
+ );
+ background-size: 200% 100%;
+ animation: store-footer-logo-skeleton 1.2s ease-in-out infinite;
+}
+
.store-layout__brand-mark {
display: grid;
place-items: center;
@@ -33,6 +69,16 @@
color: #f8f8f8;
}
+@keyframes store-footer-logo-skeleton {
+ from {
+ background-position: 200% 0;
+ }
+
+ to {
+ background-position: -200% 0;
+ }
+}
+
@media (max-width: 767.98px) {
.store-layout__brand-slot {
min-width: 0;
diff --git a/src/app/core/layout/store-layout/store-footer/store-footer.component.ts b/src/app/core/layout/store-layout/store-footer/store-footer.component.ts
index 6856258..4de54a7 100644
--- a/src/app/core/layout/store-layout/store-footer/store-footer.component.ts
+++ b/src/app/core/layout/store-layout/store-footer/store-footer.component.ts
@@ -17,7 +17,25 @@ export type StoreSocialLink = {
styleUrl: './store-footer.component.scss'
})
export class StoreFooterComponent {
+ private logoUrlValue: string | null = null;
+
@Input({ required: true }) currentYear = new Date().getFullYear();
@Input({ required: true }) footerSections: StoreFooterSection[] = [];
@Input({ required: true }) socialLinks: StoreSocialLink[] = [];
+
+ @Input()
+ set logoUrl(value: string | null) {
+ this.logoUrlValue = value;
+ this.logoLoaded = false;
+ }
+
+ get logoUrl(): string | null {
+ return this.logoUrlValue;
+ }
+
+ protected logoLoaded = false;
+
+ protected onLogoLoad(): void {
+ this.logoLoaded = true;
+ }
}
diff --git a/src/app/core/layout/store-layout/store-header/store-header.component.html b/src/app/core/layout/store-layout/store-header/store-header.component.html
index d317329..86abb35 100644
--- a/src/app/core/layout/store-layout/store-header/store-header.component.html
+++ b/src/app/core/layout/store-layout/store-header/store-header.component.html
@@ -4,10 +4,19 @@
-
S
-
SONDER
+ @if (logoUrl && logoLoaded) {
+
![Logo del comercio]()
+ } @else {
+
+
+
+ @if (logoUrl && !logoLoaded) {
+
![]()
+ }
+
+ }
diff --git a/src/app/core/layout/store-layout/store-header/store-header.component.scss b/src/app/core/layout/store-layout/store-header/store-header.component.scss
index a44ea69..f36a635 100644
--- a/src/app/core/layout/store-layout/store-header/store-header.component.scss
+++ b/src/app/core/layout/store-layout/store-header/store-header.component.scss
@@ -2,23 +2,34 @@
min-width: 10rem;
}
-.store-layout__brand-mark {
- display: grid;
- place-items: center;
- width: 2.75rem;
+.store-layout__brand-logo-shell {
+ position: relative;
+ width: min(100%, 12rem);
height: 2.75rem;
- border: 1px dashed #bbbbbb;
- border-radius: 999px;
- font-size: 1.05rem;
- font-weight: 700;
- letter-spacing: 0.04em;
- color: #373737;
}
-.store-layout__brand-text {
- font-size: 1.8rem;
- font-weight: 700;
- letter-spacing: -0.08em;
+.store-layout__brand-logo {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.store-layout__brand-logo--preload {
+ opacity: 0;
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+}
+
+.store-layout__brand-logo-skeleton {
+ display: block;
+ width: 100%;
+ height: 100%;
+ border-radius: 0.75rem;
+ background: linear-gradient(90deg, rgba(0, 0, 0, 0.08) 0%, rgba(0, 0, 0, 0.14) 50%, rgba(0, 0, 0, 0.08) 100%);
+ background-size: 200% 100%;
+ animation: store-header-logo-skeleton 1.2s ease-in-out infinite;
}
.store-layout__search {
@@ -31,15 +42,21 @@
letter-spacing: 0.02em;
}
+@keyframes store-header-logo-skeleton {
+ from {
+ background-position: 200% 0;
+ }
+
+ to {
+ background-position: -200% 0;
+ }
+}
+
@media (max-width: 767.98px) {
.store-layout__brand-slot {
min-width: 0;
}
- .store-layout__brand-text {
- font-size: 1.45rem;
- }
-
.store-layout__search {
min-width: 0;
}
diff --git a/src/app/core/layout/store-layout/store-header/store-header.component.ts b/src/app/core/layout/store-layout/store-header/store-header.component.ts
index 44e18a1..0157ac1 100644
--- a/src/app/core/layout/store-layout/store-header/store-header.component.ts
+++ b/src/app/core/layout/store-layout/store-header/store-header.component.ts
@@ -12,5 +12,23 @@ export type StoreHeaderAction = {
styleUrl: './store-header.component.scss'
})
export class StoreHeaderComponent {
+ private logoUrlValue: string | null = null;
+
@Input({ required: true }) headerActions: StoreHeaderAction[] = [];
+
+ @Input()
+ set logoUrl(value: string | null) {
+ this.logoUrlValue = value;
+ this.logoLoaded = false;
+ }
+
+ get logoUrl(): string | null {
+ return this.logoUrlValue;
+ }
+
+ protected logoLoaded = false;
+
+ protected onLogoLoad(): void {
+ this.logoLoaded = true;
+ }
}
diff --git a/src/app/core/layout/store-layout/store-layout.component.html b/src/app/core/layout/store-layout/store-layout.component.html
index f7e1639..79b0636 100644
--- a/src/app/core/layout/store-layout/store-layout.component.html
+++ b/src/app/core/layout/store-layout/store-layout.component.html
@@ -1,5 +1,5 @@
-
+
@@ -9,5 +9,6 @@
[currentYear]="currentYear"
[footerSections]="footerSections"
[socialLinks]="socialLinks"
+ [logoUrl]="tenant()?.footer_logo ?? null"
/>
diff --git a/src/app/core/layout/store-layout/store-layout.component.ts b/src/app/core/layout/store-layout/store-layout.component.ts
index 764d17f..932864a 100644
--- a/src/app/core/layout/store-layout/store-layout.component.ts
+++ b/src/app/core/layout/store-layout/store-layout.component.ts
@@ -1,5 +1,6 @@
-import { Component } from '@angular/core';
+import { Component, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
+import { TenantService } from '../../services/tenant.service';
import { StoreFooterComponent, StoreFooterSection, StoreSocialLink } from './store-footer/store-footer.component';
import { StoreHeaderComponent, StoreHeaderAction } from './store-header/store-header.component';
@@ -10,7 +11,10 @@ import { StoreHeaderComponent, StoreHeaderAction } from './store-header/store-he
styleUrl: './store-layout.component.scss'
})
export class StoreLayoutComponent {
+ private readonly tenantService = inject(TenantService);
+
protected readonly currentYear = new Date().getFullYear();
+ protected readonly tenant = this.tenantService.tenant;
protected readonly headerActions: StoreHeaderAction[] = [
{
diff --git a/src/app/core/services/tenant.service.spec.ts b/src/app/core/services/tenant.service.spec.ts
index 5585a09..2a61dc2 100644
--- a/src/app/core/services/tenant.service.spec.ts
+++ b/src/app/core/services/tenant.service.spec.ts
@@ -44,6 +44,7 @@ describe('TenantService', () => {
await expect(bootstrapPromise).resolves.toEqual(response.data);
expect(service.tenant()).toEqual(response.data);
+ expect(service.getTenant()).toEqual(response.data);
httpController.verify();
});
@@ -81,6 +82,7 @@ describe('TenantService', () => {
await expect(service.bootstrap()).resolves.toBeNull();
expect(service.tenant()).toBeNull();
+ expect(service.getTenant()).toBeNull();
httpController.expectNone(() => true);
httpController.verify();
diff --git a/src/app/core/services/tenant.service.ts b/src/app/core/services/tenant.service.ts
index 018b3b6..565a2e2 100644
--- a/src/app/core/services/tenant.service.ts
+++ b/src/app/core/services/tenant.service.ts
@@ -16,6 +16,10 @@ export class TenantService {
readonly tenant = this.tenantState.asReadonly();
+ getTenant(): Tenant | null {
+ return this.tenantState();
+ }
+
async bootstrap(): Promise
{
if (!isPlatformBrowser(this.platformId)) {
return null;