valtech-components 2.0.1024 → 2.0.1025
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/molecules/ticket-card/ticket-card.component.mjs +183 -0
- package/esm2022/lib/components/molecules/ticket-card/ticket-card.i18n.mjs +23 -0
- package/esm2022/lib/components/molecules/ticket-card/types.mjs +2 -0
- package/esm2022/lib/components/organisms/qr-scanner/qr-scanner.component.mjs +310 -0
- package/esm2022/lib/components/organisms/qr-scanner/qr-scanner.i18n.mjs +28 -0
- package/esm2022/lib/components/organisms/qr-scanner/types.mjs +2 -0
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +6 -1
- package/fesm2022/valtech-components.mjs +531 -3
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/molecules/ticket-card/ticket-card.component.d.ts +42 -0
- package/lib/components/molecules/ticket-card/ticket-card.i18n.d.ts +22 -0
- package/lib/components/molecules/ticket-card/types.d.ts +45 -0
- package/lib/components/organisms/qr-scanner/qr-scanner.component.d.ts +51 -0
- package/lib/components/organisms/qr-scanner/qr-scanner.i18n.d.ts +27 -0
- package/lib/components/organisms/qr-scanner/types.d.ts +31 -0
- package/lib/version.d.ts +1 -1
- package/package.json +3 -1
- package/public-api.d.ts +4 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { QrCodeMetadata } from '../../atoms/qr-code/types';
|
|
2
|
+
import { QrResult } from '../../../services/qr-generator/types';
|
|
3
|
+
import { TicketCardMetadata, TicketCardStatus } from './types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* val-ticket-card
|
|
7
|
+
*
|
|
8
|
+
* Tarjeta presentacional de una entrada de bingo: muestra el QR escaneable
|
|
9
|
+
* (generado del `qrToken` opaco firmado vía `QrGeneratorService`), el folio, el
|
|
10
|
+
* nombre del comprador (si hay) y un badge de estado (vendida / canjeada).
|
|
11
|
+
*
|
|
12
|
+
* Es la pieza que el vendedor le entrega al comprador tras la venta y que la
|
|
13
|
+
* taquilla escanea para canjear. Object-first (`input()` signal), i18n
|
|
14
|
+
* auto-registrado (namespace `TicketCard`). Estados negativos/neutros en gris
|
|
15
|
+
* muted (convención del factory — sin rojo de alarma).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```html
|
|
19
|
+
* <val-ticket-card [props]="{ qrToken: ticket.qrToken, folio: ticket.folio,
|
|
20
|
+
* buyerName: ticket.compradorNombre, status: 'sold', showShare: true }" />
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class TicketCardComponent {
|
|
24
|
+
/** Props object-first del componente. */
|
|
25
|
+
readonly props: import("@angular/core").InputSignal<TicketCardMetadata>;
|
|
26
|
+
private qrService;
|
|
27
|
+
private i18n;
|
|
28
|
+
/** QR generado (null mientras carga o si falló). */
|
|
29
|
+
readonly qr: import("@angular/core").WritableSignal<QrResult>;
|
|
30
|
+
/** Falló la generación del QR → fallback al token corto. */
|
|
31
|
+
readonly failed: import("@angular/core").WritableSignal<boolean>;
|
|
32
|
+
constructor();
|
|
33
|
+
private generate;
|
|
34
|
+
t(key: string): string;
|
|
35
|
+
readonly status: import("@angular/core").Signal<TicketCardStatus>;
|
|
36
|
+
readonly tokenShort: import("@angular/core").Signal<string>;
|
|
37
|
+
readonly folioText: import("@angular/core").Signal<string>;
|
|
38
|
+
readonly statusLabel: import("@angular/core").Signal<string>;
|
|
39
|
+
qrProps(q: QrResult): QrCodeMetadata;
|
|
40
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TicketCardComponent, never>;
|
|
41
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TicketCardComponent, "val-ticket-card", never, { "props": { "alias": "props"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defaults i18n (es/en) del `val-ticket-card`. Auto-registrados en el
|
|
3
|
+
* constructor del componente (namespace `TicketCard`) — el consumer NUNCA tiene
|
|
4
|
+
* que registrarlos. Override pasando los labels por props o registrando el
|
|
5
|
+
* namespace antes de montar el componente.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TICKET_CARD_I18N: {
|
|
8
|
+
readonly es: {
|
|
9
|
+
readonly folio: "Folio";
|
|
10
|
+
readonly statusSold: "Vendida";
|
|
11
|
+
readonly statusCheckedIn: "Canjeada";
|
|
12
|
+
readonly download: "Descargar";
|
|
13
|
+
readonly share: "Compartir";
|
|
14
|
+
};
|
|
15
|
+
readonly en: {
|
|
16
|
+
readonly folio: "Folio";
|
|
17
|
+
readonly statusSold: "Sold";
|
|
18
|
+
readonly statusCheckedIn: "Checked in";
|
|
19
|
+
readonly download: "Download";
|
|
20
|
+
readonly share: "Share";
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estado de canje/venta que el ticket-card refleja en su badge.
|
|
3
|
+
*
|
|
4
|
+
* - `sold` — entrada vendida, todavía no canjeada (QR válido para canjear).
|
|
5
|
+
* - `checkedIn` — entrada ya canjeada (QR ya usado en puerta).
|
|
6
|
+
* - `neutral` — sin estado destacado (p.ej. solo se muestra el QR).
|
|
7
|
+
*/
|
|
8
|
+
export type TicketCardStatus = 'sold' | 'checkedIn' | 'neutral';
|
|
9
|
+
/**
|
|
10
|
+
* Metadata (object-first) del componente `val-ticket-card`.
|
|
11
|
+
*
|
|
12
|
+
* Tarjeta presentacional de una entrada: muestra el QR (generado a partir del
|
|
13
|
+
* `qrToken` opaco firmado), el folio, el nombre del comprador (si hay) y un
|
|
14
|
+
* badge de estado. NO trae texto propio fijo — el consumer pasa los labels ya
|
|
15
|
+
* resueltos (`statusSoldLabel` / `statusCheckedInLabel` / `folioLabel`). El
|
|
16
|
+
* único texto auto-i18n son los defaults de esos labels (namespace `TicketCard`).
|
|
17
|
+
*/
|
|
18
|
+
export interface TicketCardMetadata {
|
|
19
|
+
/**
|
|
20
|
+
* Token opaco firmado que va DENTRO del QR escaneable (formato
|
|
21
|
+
* `base64url.base64url`). Es exactamente el dato que la taquilla manda al
|
|
22
|
+
* endpoint de canje. El componente lo codifica en el QR tal cual.
|
|
23
|
+
*/
|
|
24
|
+
qrToken: string;
|
|
25
|
+
/** Folio de la entrada (número visible junto al QR). */
|
|
26
|
+
folio?: number | string;
|
|
27
|
+
/** Nombre del comprador, si se capturó en la venta. */
|
|
28
|
+
buyerName?: string;
|
|
29
|
+
/** Estado de la entrada (controla el color/label del badge). */
|
|
30
|
+
status?: TicketCardStatus;
|
|
31
|
+
/** Título de la tarjeta (ej. nombre del evento). Opcional. */
|
|
32
|
+
title?: string;
|
|
33
|
+
/** Tamaño del QR en px (default 200). */
|
|
34
|
+
qrSize?: number;
|
|
35
|
+
/** Mostrar botón de descarga del QR. */
|
|
36
|
+
showDownload?: boolean;
|
|
37
|
+
/** Mostrar botón de compartir el QR. */
|
|
38
|
+
showShare?: boolean;
|
|
39
|
+
/** Label del prefijo de folio (default i18n: "Folio"). */
|
|
40
|
+
folioLabel?: string;
|
|
41
|
+
/** Label del badge cuando `status === 'sold'` (default: "Vendida"). */
|
|
42
|
+
statusSoldLabel?: string;
|
|
43
|
+
/** Label del badge cuando `status === 'checkedIn'` (default: "Canjeada"). */
|
|
44
|
+
statusCheckedInLabel?: string;
|
|
45
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { AfterViewInit, ElementRef, EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { QrScannerMetadata, QrScannerState } from './types';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* val-qr-scanner
|
|
6
|
+
*
|
|
7
|
+
* Organism: scanner de códigos QR por cámara (`@zxing/browser` +
|
|
8
|
+
* `@zxing/library`). Emite el texto decodificado por `(scanned)`.
|
|
9
|
+
*
|
|
10
|
+
* Maneja: permiso de cámara denegado (`denied`), ausencia de cámara
|
|
11
|
+
* (`no-camera`), selector cuando hay varias cámaras, y botón start/stop. Hace
|
|
12
|
+
* cleanup del stream en `ngOnDestroy`. i18n auto-registrado (namespace
|
|
13
|
+
* `QrScanner`).
|
|
14
|
+
*
|
|
15
|
+
* Object-first (`@Input() props`) + un único `@Output() scanned`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```html
|
|
19
|
+
* <val-qr-scanner [props]="{ continuous: true }" (scanned)="onScan($event)" />
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class QrScannerComponent implements AfterViewInit, OnDestroy {
|
|
23
|
+
props: QrScannerMetadata;
|
|
24
|
+
/** Emite el texto decodificado del QR. */
|
|
25
|
+
scanned: EventEmitter<string>;
|
|
26
|
+
videoRef: ElementRef<HTMLVideoElement>;
|
|
27
|
+
private i18n;
|
|
28
|
+
readonly state: import("@angular/core").WritableSignal<QrScannerState>;
|
|
29
|
+
readonly devices: import("@angular/core").WritableSignal<MediaDeviceInfo[]>;
|
|
30
|
+
readonly activeDeviceId: import("@angular/core").WritableSignal<string>;
|
|
31
|
+
private reader;
|
|
32
|
+
private controls;
|
|
33
|
+
private lastValue;
|
|
34
|
+
private lastAt;
|
|
35
|
+
private viewReady;
|
|
36
|
+
constructor();
|
|
37
|
+
ngAfterViewInit(): void;
|
|
38
|
+
ngOnDestroy(): void;
|
|
39
|
+
t(key: string): string;
|
|
40
|
+
stateMessage(): string;
|
|
41
|
+
deviceLabel(d: MediaDeviceInfo): string;
|
|
42
|
+
start(deviceId?: string): Promise<void>;
|
|
43
|
+
stop(): void;
|
|
44
|
+
onSelectDevice(deviceId: string): Promise<void>;
|
|
45
|
+
private handleResult;
|
|
46
|
+
private handleStartError;
|
|
47
|
+
/** Detiene el decode + libera el stream de la cámara. */
|
|
48
|
+
private teardown;
|
|
49
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<QrScannerComponent, never>;
|
|
50
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<QrScannerComponent, "val-qr-scanner", never, { "props": { "alias": "props"; "required": false; }; }, { "scanned": "scanned"; }, never, never, true, never>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defaults i18n (es/en) del `val-qr-scanner`. Auto-registrados en el
|
|
3
|
+
* constructor (namespace `QrScanner`) — el consumer NUNCA tiene que
|
|
4
|
+
* registrarlos. Override por props (start/stop) o registrando el namespace.
|
|
5
|
+
*/
|
|
6
|
+
export declare const QR_SCANNER_I18N: {
|
|
7
|
+
readonly es: {
|
|
8
|
+
readonly start: "Iniciar cámara";
|
|
9
|
+
readonly stop: "Detener";
|
|
10
|
+
readonly starting: "Iniciando cámara…";
|
|
11
|
+
readonly hint: "Apunta la cámara al código QR de la entrada.";
|
|
12
|
+
readonly cameraLabel: "Cámara";
|
|
13
|
+
readonly denied: "No se pudo acceder a la cámara. Revisa los permisos del navegador e inténtalo de nuevo.";
|
|
14
|
+
readonly noCamera: "No se encontró ninguna cámara en este dispositivo.";
|
|
15
|
+
readonly error: "Ocurrió un problema con la cámara. Inténtalo de nuevo.";
|
|
16
|
+
};
|
|
17
|
+
readonly en: {
|
|
18
|
+
readonly start: "Start camera";
|
|
19
|
+
readonly stop: "Stop";
|
|
20
|
+
readonly starting: "Starting camera…";
|
|
21
|
+
readonly hint: "Point the camera at the ticket QR code.";
|
|
22
|
+
readonly cameraLabel: "Camera";
|
|
23
|
+
readonly denied: "Could not access the camera. Check your browser permissions and try again.";
|
|
24
|
+
readonly noCamera: "No camera was found on this device.";
|
|
25
|
+
readonly error: "Something went wrong with the camera. Please try again.";
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata (object-first) del organism `val-qr-scanner`.
|
|
3
|
+
*
|
|
4
|
+
* Scanner de QR por cámara. Todos los campos son opcionales (la cámara
|
|
5
|
+
* funciona con defaults). El consumer pasa los labels ya resueltos por i18n;
|
|
6
|
+
* si no, el componente cae a sus defaults auto-registrados (namespace
|
|
7
|
+
* `QrScanner`).
|
|
8
|
+
*/
|
|
9
|
+
export interface QrScannerMetadata {
|
|
10
|
+
/** Arrancar la cámara automáticamente al montar (default false). */
|
|
11
|
+
autoStart?: boolean;
|
|
12
|
+
/** Label del botón de iniciar (override del auto-i18n). */
|
|
13
|
+
startLabel?: string;
|
|
14
|
+
/** Label del botón de detener (override del auto-i18n). */
|
|
15
|
+
stopLabel?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Mantener la cámara encendida tras un escaneo exitoso (default true). Si es
|
|
18
|
+
* `false`, el scanner se detiene solo al primer match — útil para flujos de
|
|
19
|
+
* un solo canje. Si es `true`, sigue escaneando (la página decide cuándo
|
|
20
|
+
* parar / reanudar).
|
|
21
|
+
*/
|
|
22
|
+
continuous?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Anti-rebote entre lecturas del MISMO valor, en ms (default 1500). Evita
|
|
25
|
+
* que el mismo QR dispare `scanned` muchas veces por segundo mientras está
|
|
26
|
+
* frente a la cámara.
|
|
27
|
+
*/
|
|
28
|
+
dedupeMs?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Estado interno del scanner (expuesto para feedback de UI). */
|
|
31
|
+
export type QrScannerState = 'idle' | 'starting' | 'scanning' | 'denied' | 'no-camera' | 'error';
|
package/lib/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valtech-components",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1025",
|
|
4
4
|
"private": false,
|
|
5
5
|
"bin": {
|
|
6
6
|
"valtech-firebase-config": "./src/lib/services/firebase/scripts/generate-sw-config.js"
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@capacitor/browser": "^6.0.3",
|
|
39
|
+
"@zxing/browser": "^0.2.0",
|
|
40
|
+
"@zxing/library": "^0.22.0",
|
|
39
41
|
"compressorjs": "^1.3.0",
|
|
40
42
|
"ng-otp-input": "^1.9.3",
|
|
41
43
|
"ngx-image-cropper": "^9.0.0",
|
package/public-api.d.ts
CHANGED
|
@@ -433,3 +433,7 @@ export * from './lib/components/molecules/content-card/content-card.component';
|
|
|
433
433
|
export * from './lib/components/molecules/content-card/types';
|
|
434
434
|
export * from './lib/components/organisms/auth-cta/auth-cta.component';
|
|
435
435
|
export * from './lib/components/organisms/auth-cta/types';
|
|
436
|
+
export * from './lib/components/molecules/ticket-card/ticket-card.component';
|
|
437
|
+
export * from './lib/components/molecules/ticket-card/types';
|
|
438
|
+
export * from './lib/components/organisms/qr-scanner/qr-scanner.component';
|
|
439
|
+
export * from './lib/components/organisms/qr-scanner/types';
|