feat: add additionalInfoConfig to tenant interface and implement rendering in store home page

This commit is contained in:
2026-08-03 15:08:33 -03:00
parent cc884e3cc0
commit 2487546a75
5 changed files with 95 additions and 0 deletions

View File

@@ -27,6 +27,10 @@ export interface HeroConfig {
button_href?: string | null;
}
export interface AdditionalInfoConfig {
description?: string | null;
}
export interface EventDate {
id?: number;
date: string;
@@ -60,6 +64,7 @@ export interface ActiveEvent {
export interface WebsiteExtras {
carousel?: string[];
heroConfig?: HeroConfig | null;
additionalInfoConfig?: AdditionalInfoConfig | null;
[extraName: string]: unknown;
}

View File

@@ -37,3 +37,9 @@
</app-store-section>
}
}
@if (additionalInfo(); as content) {
<app-store-section class="store-home__additional-info" title="Información adicional">
<div class="store-home__additional-info-content" [innerHTML]="content"></div>
</app-store-section>
}

View File

@@ -11,6 +11,25 @@ app-store-section + app-store-section {
margin-top: clamp(3rem, 6vw, 5rem);
}
:host > .store-home__additional-info:not(:first-child) {
margin-top: clamp(3rem, 6vw, 5rem);
}
.store-home__additional-info-content {
width: 100%;
text-align: center;
}
::ng-deep .store-home__additional-info-content img {
display: block;
margin-right: auto;
margin-left: auto;
}
::ng-deep .store-home__additional-info-content > :last-child {
margin-bottom: 0;
}
.store-home__alert-error {
margin: 0;
border-color: rgba(var(--tenant-danger-rgb, 220, 53, 69), 0.18);

View File

@@ -267,6 +267,68 @@ describe('StoreHomePageComponent', () => {
expect(heroComponent.eventConfig?.contact).toEqual(tenant.social_media);
});
it('renders additional information as an HTML section', async () => {
const description =
'<p>Consultá los <strong>términos del evento</strong>.</p><ul><li>Ingreso con DNI</li></ul>';
await TestBed.configureTestingModule({
imports: [StoreHomePageComponent],
providers: [
provideActivatedRoute({ response: createCatalog(), error: null }),
{
provide: CatalogService,
useValue: { getCatalog: vi.fn(), getFeaturedGroupItems: vi.fn() },
},
{
provide: TenantService,
useValue: createTenantServiceStub(
createTenant({ additionalInfoConfig: { description } }),
),
},
],
}).compileComponents();
const fixture = TestBed.createComponent(StoreHomePageComponent);
fixture.detectChanges();
const element = fixture.nativeElement as HTMLElement;
const section = element.querySelector('.store-home__additional-info');
const sections = element.querySelectorAll(':scope > app-store-section');
expect(sections[sections.length - 1]).toBe(section);
expect(section?.querySelector('.store-section__title')?.textContent?.trim()).toBe(
'Información adicional',
);
expect(section?.querySelector('strong')?.textContent).toBe('términos del evento');
expect(section?.querySelector('li')?.textContent).toBe('Ingreso con DNI');
});
it('does not render the additional information section without content', async () => {
await TestBed.configureTestingModule({
imports: [StoreHomePageComponent],
providers: [
provideActivatedRoute({ response: createCatalog(), error: null }),
{
provide: CatalogService,
useValue: { getCatalog: vi.fn(), getFeaturedGroupItems: vi.fn() },
},
{
provide: TenantService,
useValue: createTenantServiceStub(
createTenant({ additionalInfoConfig: { description: ' ' } }),
),
},
],
}).compileComponents();
const fixture = TestBed.createComponent(StoreHomePageComponent);
fixture.detectChanges();
expect(
(fixture.nativeElement as HTMLElement).querySelector('.store-home__additional-info'),
).toBeNull();
});
it('renders only the active event data when the tenant does not have the hero extra', async () => {
const tenant = createTenant();
tenant.active_event_id = 12;

View File

@@ -62,6 +62,9 @@ export class StoreHomePageComponent implements OnInit, OnDestroy {
protected readonly creatingDirectPurchase = signal(false);
protected readonly mainCarouselImages = computed(() => this.tenant()?.extras?.carousel ?? []);
protected readonly heroConfig = computed(() => this.tenant()?.extras?.heroConfig ?? null);
protected readonly additionalInfo = computed(
() => this.tenant()?.extras?.additionalInfoConfig?.description?.trim() || null,
);
protected readonly eventConfig = computed(() => {
const tenant = this.tenant();
const contact = tenant?.social_media ?? [];