feat(categories): separate event and product navigation
This commit is contained in:
@@ -12,8 +12,8 @@
|
|||||||
[isAuthenticated]="isAuthenticated()"
|
[isAuthenticated]="isAuthenticated()"
|
||||||
[accountNavigationMenus]="accountNavigationMenus()"
|
[accountNavigationMenus]="accountNavigationMenus()"
|
||||||
[ticketsMenu]="ticketsMenu() ?? null"
|
[ticketsMenu]="ticketsMenu() ?? null"
|
||||||
[categories]="tenant()?.categories ?? []"
|
[categories]="navigationCategories()"
|
||||||
[displayCategories]="tenant()?.display_categories ?? true"
|
[displayCategories]="displayCategories()"
|
||||||
[displaySeachBar]="tenant()?.display_seach_bar ?? true"
|
[displaySeachBar]="tenant()?.display_seach_bar ?? true"
|
||||||
[displayCart]="displayCart()"
|
[displayCart]="displayCart()"
|
||||||
[cartDisabled]="isCheckoutRoute()"
|
[cartDisabled]="isCheckoutRoute()"
|
||||||
|
|||||||
@@ -294,6 +294,18 @@ describe('StoreLayoutComponent', () => {
|
|||||||
header_type: 'immersive',
|
header_type: 'immersive',
|
||||||
display_categories: true,
|
display_categories: true,
|
||||||
categories: [{ id: 11, nombre: 'Música', subcategories: [] }],
|
categories: [{ id: 11, nombre: 'Música', subcategories: [] }],
|
||||||
|
menues: [
|
||||||
|
...(tenant.menues ?? []),
|
||||||
|
{
|
||||||
|
id: 20,
|
||||||
|
code: 'product.category',
|
||||||
|
label: 'Categoría de productos',
|
||||||
|
parent_menu_code: null,
|
||||||
|
content_type: 'dynamic',
|
||||||
|
route: '/categoria/:id',
|
||||||
|
submenues: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const fixture = TestBed.createComponent(StoreLayoutComponent);
|
const fixture = TestBed.createComponent(StoreLayoutComponent);
|
||||||
@@ -323,6 +335,43 @@ describe('StoreLayoutComponent', () => {
|
|||||||
expect(element.querySelector('.immersive-categories')).toBeNull();
|
expect(element.querySelector('.immersive-categories')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses event categories and their dedicated route for multi-event storefronts', () => {
|
||||||
|
tenantState.set({
|
||||||
|
...tenant,
|
||||||
|
storefront_website_type_code: 'onticket_multi_event',
|
||||||
|
header_type: 'immersive',
|
||||||
|
display_categories: true,
|
||||||
|
categories: [],
|
||||||
|
event_categories: [{ id: 12, nombre: 'Teatro', subcategories: [] }],
|
||||||
|
menues: [
|
||||||
|
...(tenant.menues ?? []),
|
||||||
|
{
|
||||||
|
id: 21,
|
||||||
|
code: 'event.category',
|
||||||
|
label: 'Categoría de eventos',
|
||||||
|
parent_menu_code: null,
|
||||||
|
content_type: 'dynamic',
|
||||||
|
route: '/eventos/categoria/:id',
|
||||||
|
submenues: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const fixture = TestBed.createComponent(StoreLayoutComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const categoryButton = (fixture.nativeElement as HTMLElement).querySelector<HTMLButtonElement>(
|
||||||
|
'.immersive-categories button',
|
||||||
|
);
|
||||||
|
const navigate = vi.spyOn(TestBed.inject(Router), 'navigate');
|
||||||
|
|
||||||
|
expect(categoryButton?.textContent?.trim()).toBe('TEATRO');
|
||||||
|
categoryButton?.click();
|
||||||
|
expect(navigate).toHaveBeenCalledWith(['/eventos/categoria', 12], {
|
||||||
|
queryParams: { page: 1 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('opens the cart when requested through the openCart query parameter', () => {
|
it('opens the cart when requested through the openCart query parameter', () => {
|
||||||
const fixture = TestBed.createComponent(StoreLayoutComponent);
|
const fixture = TestBed.createComponent(StoreLayoutComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|||||||
@@ -71,6 +71,23 @@ export class StoreLayoutComponent implements OnInit {
|
|||||||
protected readonly isHomeRoute = signal(this.isHomeUrl(this.router.url));
|
protected readonly isHomeRoute = signal(this.isHomeUrl(this.router.url));
|
||||||
protected readonly checkoutRemainingSeconds = this.checkoutCountdownService.remainingSeconds;
|
protected readonly checkoutRemainingSeconds = this.checkoutCountdownService.remainingSeconds;
|
||||||
protected readonly isCreatingPurchase = signal(false);
|
protected readonly isCreatingPurchase = signal(false);
|
||||||
|
private readonly isMultiEventStorefront = computed(
|
||||||
|
() => this.tenant()?.storefront_website_type_code === 'onticket_multi_event',
|
||||||
|
);
|
||||||
|
protected readonly navigationCategories = computed(() =>
|
||||||
|
this.isMultiEventStorefront()
|
||||||
|
? (this.tenant()?.event_categories ?? [])
|
||||||
|
: (this.tenant()?.categories ?? []),
|
||||||
|
);
|
||||||
|
private readonly categoryMenu = computed(() =>
|
||||||
|
findMenu(
|
||||||
|
this.tenant()?.menues ?? [],
|
||||||
|
this.isMultiEventStorefront() ? 'event.category' : 'product.category',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
protected readonly displayCategories = computed(
|
||||||
|
() => (this.tenant()?.display_categories ?? true) && this.categoryMenu() !== undefined,
|
||||||
|
);
|
||||||
protected readonly displayCart = computed(() => this.tenant()?.display_cart ?? true);
|
protected readonly displayCart = computed(() => this.tenant()?.display_cart ?? true);
|
||||||
protected readonly cartEditingPolicy = computed(() => this.tenant()?.cart_editing_policy ?? null);
|
protected readonly cartEditingPolicy = computed(() => this.tenant()?.cart_editing_policy ?? null);
|
||||||
protected readonly canModifyCart = computed(
|
protected readonly canModifyCart = computed(
|
||||||
@@ -281,7 +298,9 @@ export class StoreLayoutComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected onCategorySelect(category: Category): void {
|
protected onCategorySelect(category: Category): void {
|
||||||
void this.router.navigate(['/categoria', category.id], {
|
const route = this.isMultiEventStorefront() ? '/eventos/categoria' : '/categoria';
|
||||||
|
|
||||||
|
void this.router.navigate([route, category.id], {
|
||||||
queryParams: { page: 1 },
|
queryParams: { page: 1 },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ export interface Tenant {
|
|||||||
ticket_partial_refund_percentage?: string;
|
ticket_partial_refund_percentage?: string;
|
||||||
social_media?: SocialMedia[];
|
social_media?: SocialMedia[];
|
||||||
menues?: Menu[];
|
menues?: Menu[];
|
||||||
categories: Category[];
|
categories?: Category[];
|
||||||
|
event_categories?: Category[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TenantBootstrapResponse = ApiResponse<Tenant>;
|
export type TenantBootstrapResponse = ApiResponse<Tenant>;
|
||||||
|
|||||||
@@ -22,10 +22,12 @@ import { EventListComponent } from '../../components/event-list/event-list.compo
|
|||||||
export class EventCategoryPageComponent {
|
export class EventCategoryPageComponent {
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
private readonly tenant = inject(TenantService).tenant;
|
private readonly tenant = inject(TenantService).tenant;
|
||||||
private readonly params = toSignal(this.route.paramMap, { initialValue: this.route.snapshot.paramMap });
|
private readonly params = toSignal(this.route.paramMap, {
|
||||||
|
initialValue: this.route.snapshot.paramMap,
|
||||||
|
});
|
||||||
|
|
||||||
protected readonly category = computed(() => {
|
protected readonly category = computed(() => {
|
||||||
const id = Number(this.params().get('id'));
|
const id = Number(this.params().get('id'));
|
||||||
return this.tenant()?.categories.find((category) => category.id === id) ?? null;
|
return this.tenant()?.event_categories?.find((category) => category.id === id) ?? null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ export const routes: Routes = [
|
|||||||
canMatch: [isMultiEventStorefront],
|
canMatch: [isMultiEventStorefront],
|
||||||
canActivate: [hasMenuGuard('event.index')],
|
canActivate: [hasMenuGuard('event.index')],
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('./pages/event-home-page/event-home-page.component').then((m) => m.EventHomePageComponent),
|
import('./pages/event-home-page/event-home-page.component').then(
|
||||||
|
(m) => m.EventHomePageComponent,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
@@ -86,7 +88,9 @@ export const routes: Routes = [
|
|||||||
path: 'buscar',
|
path: 'buscar',
|
||||||
canMatch: [isMultiEventStorefront],
|
canMatch: [isMultiEventStorefront],
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('./pages/event-search-page/event-search-page.component').then((m) => m.EventSearchPageComponent),
|
import('./pages/event-search-page/event-search-page.component').then(
|
||||||
|
(m) => m.EventSearchPageComponent,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'buscar',
|
path: 'buscar',
|
||||||
@@ -98,11 +102,14 @@ export const routes: Routes = [
|
|||||||
canMatch: [isMultiEventStorefront],
|
canMatch: [isMultiEventStorefront],
|
||||||
canActivate: [hasMenuGuard('event.detail')],
|
canActivate: [hasMenuGuard('event.detail')],
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('./pages/event-detail-page/event-detail-page.component').then((m) => m.EventDetailPageComponent),
|
import('./pages/event-detail-page/event-detail-page.component').then(
|
||||||
|
(m) => m.EventDetailPageComponent,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'categoria/:id',
|
path: 'eventos/categoria/:id',
|
||||||
canMatch: [isMultiEventStorefront],
|
canMatch: [isMultiEventStorefront],
|
||||||
|
canActivate: [hasMenuGuard('event.category')],
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('./pages/event-category-page/event-category-page.component').then(
|
import('./pages/event-category-page/event-category-page.component').then(
|
||||||
(m) => m.EventCategoryPageComponent,
|
(m) => m.EventCategoryPageComponent,
|
||||||
@@ -110,6 +117,7 @@ export const routes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'categoria/:id',
|
path: 'categoria/:id',
|
||||||
|
canActivate: [hasMenuGuard('product.category')],
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('./pages/category-items-page/category-items-page.component').then(
|
import('./pages/category-items-page/category-items-page.component').then(
|
||||||
(m) => m.CategoryItemsPageComponent,
|
(m) => m.CategoryItemsPageComponent,
|
||||||
|
|||||||
Reference in New Issue
Block a user