feat(qr-modal): implement QR modal component and integrate with tickets page

This commit is contained in:
2026-07-21 14:55:46 -03:00
parent 472dead0ff
commit 3cefaf85d9
10 changed files with 274 additions and 110 deletions

View File

@@ -37,6 +37,7 @@
[date]="formatDate(ticket)"
[selected]="isSelected(ticket.id)"
(selectedChange)="toggleTicket(ticket.id, $event)"
(viewQr)="viewQr(ticket)"
/>
}

View File

@@ -3,6 +3,7 @@ import { TestBed } from '@angular/core/testing';
import { describe, expect, it, vi } from 'vitest';
import { ToastService } from '../../../../../../core/services/toast.service';
import { ModalService } from '../../../../../../core/services/modal.service';
import { TicketComponent } from './components/ticket/ticket.component';
import { TicketResponse, TicketService } from './ticket.service';
import { TicketsPage } from './tickets-page';
@@ -76,4 +77,42 @@ describe('TicketsPage', () => {
expect(element.querySelector('[aria-label="Compartir ticket"]')).toBeNull();
});
});
it('opens the QR modal with the selected ticket data', async () => {
const modalService = { openQr: vi.fn() };
await TestBed.configureTestingModule({
imports: [TicketsPage],
providers: [
{ provide: ToastService, useValue: { danger: vi.fn() } },
{ provide: ModalService, useValue: modalService },
],
})
.overrideComponent(TicketsPage, {
set: {
providers: [
{
provide: TicketService,
useValue: { getTickets: () => Promise.resolve([ticket({})]) },
},
],
},
})
.compileComponents();
const fixture = TestBed.createComponent(TicketsPage);
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();
const page = fixture.nativeElement as HTMLElement;
page.querySelector<HTMLButtonElement>('app-ticket app-button button')?.click();
expect(modalService.openQr).toHaveBeenCalledWith({
title: 'Entrada general',
id: 1,
date: '09-octubre',
ticket: 'ticket-1',
});
});
});

View File

@@ -1,5 +1,6 @@
import { Component, computed, inject, OnInit, signal } from '@angular/core';
import { ModalService } from '../../../../../../core/services/modal.service';
import { ToastService } from '../../../../../../core/services/toast.service';
import { IconButtonComponent } from '../../../../../../shared/components/icon-button/icon-button.component';
import { TicketComponent } from './components/ticket/ticket.component';
@@ -15,6 +16,7 @@ import { TicketResponse, TicketService } from './ticket.service';
export class TicketsPage implements OnInit {
private readonly ticketService = inject(TicketService);
private readonly toastService = inject(ToastService);
private readonly modalService = inject(ModalService);
protected readonly tickets = signal<TicketResponse[]>([]);
protected readonly activeTickets = computed(() =>
@@ -75,4 +77,13 @@ export class TicketsPage implements OnInit {
timeZone: 'UTC',
}).format(date);
}
protected viewQr(ticket: TicketResponse): void {
this.modalService.openQr({
title: ticket.name,
id: ticket.id,
date: this.formatDate(ticket) ?? '',
ticket: ticket.ticket,
});
}
}