feat: update social media handling across components to prioritize tenant-specific links and add banner support in category items
This commit is contained in:
@@ -69,7 +69,7 @@
|
||||
<app-store-footer
|
||||
[currentYear]="currentYear"
|
||||
[footerSections]="footerSections()"
|
||||
[socialMedia]="tenant()?.social_media ?? []"
|
||||
[socialMedia]="tenant()?.tenant_social_media ?? tenant()?.social_media ?? []"
|
||||
[logoUrl]="tenant()?.footer_logo ?? null"
|
||||
[backgroundImageUrl]="tenant()?.footer_bg_image ?? null"
|
||||
[storeName]="tenant()?.nombre ?? null"
|
||||
|
||||
@@ -580,6 +580,20 @@ describe('StoreLayoutComponent', () => {
|
||||
expect(footer.textContent).not.toContain(tenant.address);
|
||||
});
|
||||
|
||||
it('uses commerce social networks in the footer and respects an empty collection', () => {
|
||||
tenantState.set({ ...tenant, tenant_social_media: [
|
||||
{ ...tenant.social_media![0], url: 'https://instagram.com/commerce-contact' },
|
||||
] });
|
||||
const fixture = TestBed.createComponent(StoreLayoutComponent);
|
||||
fixture.detectChanges();
|
||||
const footer = fixture.nativeElement.querySelector('app-store-footer') as HTMLElement;
|
||||
expect(footer.querySelector('a[href="https://instagram.com/commerce-contact"]')).not.toBeNull();
|
||||
tenantState.set({ ...tenant, tenant_social_media: [] });
|
||||
fixture.detectChanges();
|
||||
expect(footer.querySelector('a[href="https://instagram.com/commerce-contact"]')).toBeNull();
|
||||
expect(footer.querySelector('a[href="' + tenant.social_media![0].url + '"]')).toBeNull();
|
||||
});
|
||||
|
||||
it('uses only the main phone number in the footer', () => {
|
||||
tenantState.set({ ...tenant, main_phone_number: {
|
||||
id: 10, label: 'Principal', number: '3411234567', tel_url: 'tel:3411234567',
|
||||
|
||||
@@ -170,6 +170,7 @@ export interface CatalogCategory {
|
||||
id: number;
|
||||
nombre: string;
|
||||
categoria_id: number | null;
|
||||
banner_url?: string | null;
|
||||
}
|
||||
|
||||
export interface CategoryItemsResponse extends ApiPaginatedResponse<CatalogFeaturedItem[]> {
|
||||
|
||||
@@ -161,6 +161,7 @@ export interface Tenant {
|
||||
allow_ticket_partial_refund?: boolean;
|
||||
ticket_partial_refund_percentage?: string;
|
||||
social_media?: SocialMedia[];
|
||||
tenant_social_media?: SocialMedia[];
|
||||
menues?: Menu[];
|
||||
categories?: Category[];
|
||||
event_categories?: Category[];
|
||||
|
||||
@@ -2,7 +2,14 @@
|
||||
@if (error()) {
|
||||
<p class="alert text-center mb-0 category-items__alert-error">{{ error() }}</p>
|
||||
} @else if (results(); as categoryResults) {
|
||||
<header class="category-items__header mb-5">
|
||||
@if (categoryResults.category.banner_url; as bannerUrl) {
|
||||
<img
|
||||
class="category-items__banner"
|
||||
[src]="bannerUrl"
|
||||
[alt]="'Banner de ' + categoryResults.category.nombre"
|
||||
/>
|
||||
}
|
||||
<header class="category-items__header">
|
||||
<h1 id="category-items-title" class="category-items__title mb-0">
|
||||
{{ categoryResults.category.nombre }}
|
||||
</h1>
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
.category-items__banner {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 170px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.category-items__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16px 28px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.category-items__title {
|
||||
font-size: 24px;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
color:var(--bs-primary)
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.category-items__alert-error {
|
||||
|
||||
@@ -106,6 +106,30 @@ describe('CategoryItemsPageComponent', () => {
|
||||
expect(productList.layout()).toBe('row');
|
||||
expect(productList.groupLayout()).toBe('paginated');
|
||||
expect(Array.isArray(productList.items())).toBe(false);
|
||||
expect(fixture.nativeElement.querySelector('.category-items__banner')).toBeNull();
|
||||
});
|
||||
|
||||
it('renders the category banner above the title when the API returns its URL', () => {
|
||||
getCategoryItems.mockReturnValue(
|
||||
of({
|
||||
category: {
|
||||
id: 7,
|
||||
nombre: 'Remeras',
|
||||
categoria_id: null,
|
||||
banner_url: 'https://example.com/banner.jpg',
|
||||
},
|
||||
data: [],
|
||||
}),
|
||||
);
|
||||
|
||||
const fixture = TestBed.createComponent(CategoryItemsPageComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const element = fixture.nativeElement as HTMLElement;
|
||||
const banner = element.querySelector<HTMLImageElement>('.category-items__banner');
|
||||
expect(banner?.getAttribute('src')).toBe('https://example.com/banner.jpg');
|
||||
expect(banner?.alt).toBe('Banner de Remeras');
|
||||
expect(banner?.nextElementSibling?.querySelector('h1')?.textContent).toContain('Remeras');
|
||||
});
|
||||
|
||||
it('reloads the current category page when catalog availability changes', () => {
|
||||
|
||||
@@ -138,6 +138,24 @@ describe('ContactPage', () => {
|
||||
expect(element.textContent).toContain('San Martín 2450');
|
||||
});
|
||||
|
||||
it('uses commerce networks even when the active event has different networks', () => {
|
||||
tenantState.set({
|
||||
...tenant,
|
||||
tenant_social_media: [{ ...tenant.social_media![0], url: 'https://wa.me/commerce' }],
|
||||
social_media: [{ ...tenant.social_media![0], url: 'https://wa.me/event' }],
|
||||
});
|
||||
fixture.detectChanges();
|
||||
const element = fixture.nativeElement as HTMLElement;
|
||||
expect(element.querySelector('a[href="https://wa.me/commerce"]')).not.toBeNull();
|
||||
expect(element.querySelector('a[href="https://wa.me/event"]')).toBeNull();
|
||||
});
|
||||
|
||||
it('does not restore event networks after all commerce networks are removed', () => {
|
||||
tenantState.set({ ...tenant, tenant_social_media: [] });
|
||||
fixture.detectChanges();
|
||||
expect((fixture.nativeElement as HTMLElement).querySelector('a[href="https://wa.me/543412602222"]')).toBeNull();
|
||||
});
|
||||
|
||||
it('passes the tenant map coordinates to the reusable map component', () => {
|
||||
const element = fixture.nativeElement as HTMLElement;
|
||||
const map = element.querySelector('app-location-map');
|
||||
|
||||
@@ -47,7 +47,7 @@ export class ContactPage {
|
||||
|
||||
private buildContactContent(): ContactContent {
|
||||
const tenant = this.tenantService.tenant();
|
||||
const socialMedia = (tenant?.social_media ?? []).filter((social) => social.url.trim());
|
||||
const socialMedia = (tenant?.tenant_social_media ?? tenant?.social_media ?? []).filter((social) => social.url.trim());
|
||||
const addresses = [...(tenant?.addresses ?? [])].sort(
|
||||
(a, b) => Number(b.is_main) - Number(a.is_main),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user